[
  {
    "path": ".github/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 responsible for enforcement at\nconduct@v2fly.org.\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": ".github/ISSUE_TEMPLATE/bug_cn.md",
    "content": "---\nname: V2Ray 程序问题\nabout: \"提交一个 V2Ray 的程序问题报告。\"\n---\n\n<!--\n除非特殊情况，请完整填写所有问题。不按模板发的 issue 将直接被关闭。\n如果你遇到的问题不是 V2Ray 的 bug，比如你不清楚如何配置，请在 https://github.com/v2fly/v2ray-core/discussions 进行讨论。\n-->\n\n## 你正在使用哪个版本的 V2Ray？\n\n<!-- 如果服务端和客户端使用了不同版本，请注明 -->\n\n\n## 你的使用场景是什么？\n\n<!-- 比如使用 Chrome 通过 Socks/VMess 代理观看 YouTube 视频 -->\n\n\n## 你看到的异常现象是什么？\n\n<!-- 请描述具体现象，比如访问超时、TLS 证书错误等 -->\n\n\n## 你期待看到的正常表现是怎样的？\n\n\n\n## 请附上你的配置\n\n<!-- 提交 issue 前，请隐去服务器域名或 IP 地址 -->\n\n**服务端配置：**\n\n```javascript\n// 在这里附上服务器端配置文件\n\n```\n\n**客户端配置：**\n\n```javascript\n// 在这里附上客户端配置\n\n```\n\n## 请附上出错时软件输出的错误日志\n\n<!-- 在 Linux 中，日志通常在 `/var/log/v2ray/error.log` 文件中 -->\n\n**服务器端错误日志：**\n\n```javascript\n// 在这里附上服务器端日志\n\n```\n\n**客户端错误日志：**\n\n```javascript\n// 在这里附上客户端日志\n\n```\n\n## 请附上访问日志\n\n<!-- 在 Linux 中，访问日志通常在 `/var/log/v2ray/access.log` 文件中 -->\n\n```javascript\n// 在这里附上服务器端日志\n\n```\n\n## 其它相关的配置文件（如 Nginx）和相关日志\n\n\n\n## 如果 V2Ray 无法启动，请附上 `--test` 命令的输出\n\n\n\n## 如果 V2Ray 服务运行异常，请附上 journal 日志\n\n<!-- 通常的命令为 `journalctl -u v2ray` -->\n\n<!-- 请预览一下你填写的内容并整理好格式后，再提交 -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_en.md",
    "content": "---\nname: Bug report\nabout: \"Create a bug report to help us improve\"\n---\n\n<!--\nPlease answer all the questions with enough information. All issues not following this template will be closed immediately.\nIf you are not sure if your question is truely a bug of V2Ray, please discuss it at https://github.com/v2fly/v2ray-core/discussions first.\n-->\n\n## What version of V2Ray are you using?\n\n<!-- If you deploy different versions of V2Ray on server and client, please explicitly point out -->\n\n\n## What's your scenario of using V2Ray?\n\n<!-- E.g., watching YouTube videos in browsers via Socks/VMess proxy -->\n\n\n## What problems have you encountered?\n\n<!-- Please describe in detail, such as timeout, fake TLS certificate, etc -->\n\n\n## What's your expectation?\n\n\n\n## Please attach your configuration here\n\n<!-- Remember to mask your IP address or hostname -->\n\n**Server configuration:**\n\n```javascript\n// Please attach your server configuration here.\n\n```\n\n**Client configuration:**\n\n```javascript\n// Please attach your client configuration here.\n\n```\n\n## Please attach error logs here\n\n<!--\nonly trailing lines if the log file is large in size.\nError log file is usually at `/var/log/v2ray/error.log` on Linux.\n-->\n\n**Server error log:**\n\n```javascript\n// Please attach your server error log here.\n\n```\n\n**Client error log:**\n\n```javascript\n// Please attach your client error log here.\n\n```\n\n## Please attach access log here\n\n<!-- Access log is usually at '/var/log/v2ray/access.log' on Linux. -->\n\n```javascript\n// Please attach your server access log here.\n\n```\n\n## Other configurations (such as Nginx) and logs here\n\n\n\n## If V2Ray cannot start up, please attach output from `--test` command\n\n\n\n## If V2Ray service is abnormal, please attach journal log here\n\n<!-- Usual command is `journalctl -u v2ray` -->\n\n<!-- Please review your issue and check the format before submitting. -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/other_en.md",
    "content": "---\nname: Other\nabout: \"其它问题请使用 https://github.com/v2fly/v2ray-core/discussions 进行讨论 / Please discuss other issues at https://github.com/v2fly/v2ray-core/discussions\"\n---\n\n如果你遇到的问题不是 V2Ray 的 bug，比如你不清楚要如何配置，请使用[Discussion](https://github.com/v2fly/v2ray-core/discussions)进行讨论。\n\n此 Issue 会被立即关闭。\n\nIf you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/v2ray-core/discussions) first.\n\nThis issue will be closed immediately.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "如果你遇到的问题不是 V2Ray 的 bug，比如你不清楚要如何配置，请使用[Discussion](https://github.com/v2fly/discussion/issues)进行讨论。\n\n此 Issue 会被立即关闭。\n\nIf you are not sure if your question is truely a bug in V2Ray, please discuss it [here](https://github.com/v2fly/discussion/issues) first.\n\nThis issue will be closed immediately.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n    open-pull-requests-limit: 10\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "name: CodeQL\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    branches: [master]\n    types: [opened, synchronize, reopened]\n    paths-ignore:\n      - \"**/*.md\"\n      - \"**/*.txt\"\n\njobs:\n  analyze:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [\"go\"]\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v4\n        with:\n          languages: ${{ matrix.language }}\n          build-mode: autobuild\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v4\n"
  },
  {
    "path": ".github/workflows/linter.yml",
    "content": "name: Linter\n\non:\n  push:\n    branches:\n      - master\n      - v*\n    paths:\n      - \"**/*.go\"\n      - \".github/workflows/linter.yml\"\n  pull_request:\n    types: [opened, synchronize, reopened]\n    paths:\n      - \"**/*.go\"\n      - \".github/workflows/linter.yml\"\n\njobs:\n  lint:\n    if: github.repository == 'v2fly/v2ray-core'\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout codebase\n        uses: actions/checkout@v6\n\n      - name: Set up Go\n        uses: actions/setup-go@v6\n        with:\n          go-version-file: ./go.mod\n          cache-dependency-path: ./go.sum\n\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@v9\n        with:\n          args: --config=.github/linters/.golangci.yml\n          only-new-issues: true\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  release:\n    types:\n      - prereleased\n      - released\n  push:\n    branches:\n      - master\n      - v*\n      - dev*\n    paths:\n      - \"**/*.go\"\n      - \"go.mod\"\n      - \"go.sum\"\n      - \".github/workflows/release.yml\"\n  pull_request:\n    types: [opened, synchronize, reopened]\n    paths:\n      - \"**/*.go\"\n      - \"go.mod\"\n      - \"go.sum\"\n      - \".github/workflows/release.yml\"\n\njobs:\n  build:\n    strategy:\n      matrix:\n        # Include amd64 on all platforms.\n        goos: [windows, freebsd, openbsd, linux, dragonfly, darwin]\n        goarch: [amd64, 386]\n        exclude:\n          # Exclude i386 on darwin and dragonfly.\n          - goarch: 386\n            goos: dragonfly\n          - goarch: 386\n            goos: darwin\n          - goarch: amd64\n            goos: linux\n        include:\n          # BEGIN Linux ARM 5 6 7\n          - goos: linux\n            goarch: arm\n            goarm: 7\n          - goos: linux\n            goarch: arm\n            goarm: 6\n          - goos: linux\n            goarch: arm\n            goarm: 5\n          # END Linux ARM 5 6 7\n          # BEGIN Windows ARM 7\n#          - goos: windows\n#            goarch: arm\n#            goarm: 7\n          # END Windows ARM 7\n          # BEGIN FreeBSD ARM 6 7\n          - goos: freebsd\n            goarch: arm\n            goarm: 6\n          - goos: freebsd\n            goarch: arm\n            goarm: 7\n          # END FreeBSD ARM 6 7\n          # BEGIN OpenBSD ARM 6 7\n          - goos: openbsd\n            goarch: arm\n            goarm: 6\n          - goos: openbsd\n            goarch: arm\n            goarm: 7\n          # END OpenBSD ARM 6 7\n          # BEGIN Other architectures\n          - goos: darwin\n            goarch: arm64\n          - goos: linux\n            goarch: arm64\n          - goos: linux\n            goarch: riscv64\n          - goos: linux\n            goarch: loong64\n          - goos: windows\n            goarch: arm64\n          - goos: android\n            goarch: arm64\n          - goos: freebsd\n            goarch: arm64\n          - goos: openbsd\n            goarch: arm64\n          # BEGIN MIPS\n          - goos: linux\n            goarch: mips64\n          - goos: linux\n            goarch: mips64le\n          - goos: linux\n            goarch: mipsle\n          - goos: linux\n            goarch: mips\n          - goos: linux\n            goarch: arm64\n            pie: pie\n          - goos: linux\n            goarch: amd64\n            pie: pie\n          - goos: linux\n            goarch: amd64\n            pie:\n          # END MIPS\n          # END Other architectures\n      fail-fast: false\n\n    runs-on: ubuntu-latest\n    env:\n      GOOS: ${{ matrix.goos }}\n      GOARCH: ${{ matrix.goarch }}\n      GOARM: ${{ matrix.goarm }}\n      PIE_ENABLED: ${{ matrix.pie }}\n      CGO_ENABLED: 0\n      IS_PRERELEASE: ${{ github.event.release.prerelease }}\n\n    steps:\n      - name: Checkout codebase\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Show workflow information\n        id: get_filename\n        run: |\n          export _NAME=$(jq \".[\\\"$GOOS-$GOARCH$GOARM$PIE_ENABLED\\\"].friendlyName\" -r < release/friendly-filenames.json)\n\n          if [ \"$GOARCH\" = \"arm64\" ] && [ \"$PIE_ENABLED\" = \"pie\" ] && [ \"$IS_PRERELEASE\" = \"true\" ]; then\n            export _NAME=\"${_NAME}-prerelease\"\n          fi\n\n          echo \"GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, RELEASE_NAME: $_NAME\"\n          echo \"ASSET_NAME=$_NAME\" >> $GITHUB_OUTPUT\n          echo \"ASSET_NAME=$_NAME\" >> $GITHUB_ENV\n\n      - name: Set up Go\n        uses: actions/setup-go@v6\n        with:\n          go-version-file: ./go.mod\n          cache-dependency-path: ./go.sum\n\n      - name: Get project dependencies\n        run: go mod download\n\n      - name: Build V2Ray\n        run: |\n          mkdir -p build_assets\n          EXTRA_ARG=\"\"\n          case \"$GOOS-$GOARCH\" in\n            \"linux-amd64\")\n              ;&\n            \"linux-arm64\")\n            if [ ! -z $PIE_ENABLED ]\n            then\n              EXTRA_ARG=$EXTRA_ARG\" -buildmode=pie\"\n            fi\n              ;;\n          esac\n          go build $EXTRA_ARG -v -o build_assets/v2ray -trimpath -ldflags \"-s -w -buildid=\" ./main\n\n      - name: Rename Windows V2Ray\n        if: matrix.goos == 'windows'\n        run: |\n          cd ./build_assets || exit 1\n          mv v2ray v2ray.exe\n\n      - name: Download geo files\n        run: |\n          wget -O release/config/geoip.dat \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat\"\n          wget -O release/config/geoip-only-cn-private.dat \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip-only-cn-private.dat\"\n          wget -O release/config/geosite.dat \"https://raw.githubusercontent.com/v2fly/domain-list-community/release/dlc.dat\"\n\n      - name: Prepare package\n        run: cp -v ./release/config/*.* ./build_assets\n\n      - name: Prepare package for Linux\n        if: matrix.goos == 'linux'\n        run: cp -rv ./release/config/systemd ./build_assets/\n\n      - name: Create ZIP archive\n        run: |\n          pushd build_assets || exit 1\n          zip -9vr ../v2ray-$ASSET_NAME.zip .\n          popd || exit 1\n          FILE=./v2ray-$ASSET_NAME.zip\n          DGST=$FILE.dgst\n          openssl dgst -md5    $FILE | sed 's/([^)]*)//g' >>$DGST\n          openssl dgst -sha1   $FILE | sed 's/([^)]*)//g' >>$DGST\n          openssl dgst -sha256 $FILE | sed 's/([^)]*)//g' >>$DGST\n          openssl dgst -sha512 $FILE | sed 's/([^)]*)//g' >>$DGST\n\n      - name: Upload ZIP file to Artifacts\n        uses: actions/upload-artifact@v7\n        with:\n          name: v2ray-${{ steps.get_filename.outputs.ASSET_NAME }}.zip\n          path: v2ray-${{ steps.get_filename.outputs.ASSET_NAME }}.zip\n\n      - name: Upload files to GitHub release\n        uses: svenstaro/upload-release-action@v2\n        if: github.event_name == 'release'\n        with:\n          repo_token: ${{ secrets.GITHUB_TOKEN }}\n          file_glob: true\n          file: ./v2ray-${{ steps.get_filename.outputs.ASSET_NAME }}.zip*\n          tag: ${{ github.ref }}\n          overwrite: true\n\n  signature:\n    runs-on: ubuntu-latest\n    needs: build\n    steps:\n      - name: Checkout codebase\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Set up Go\n        uses: actions/setup-go@v6\n        with:\n          go-version-file: ./go.mod\n          cache-dependency-path: ./go.sum\n\n      - uses: actions/download-artifact@v8\n        with:\n          path: build_artifacts\n\n      - name: Create extra package\n        run: |\n          pushd ./release/extra/\n          zip -9vr ../../build_artifacts/v2ray-extra.zip .\n          popd\n\n      - name: Generate shasum\n        run: |\n          go get -v github.com/v2fly/V2BuildAssist/v2buildutil\n          cd build_artifacts || exit 1\n          mkdir .temp\n          mv ./*/*.zip ./.temp\n          rmdir ./*/\n          mv ./.temp/* .\n          ls -lah --recursive\n          {\n            go run github.com/v2fly/V2BuildAssist/v2buildutil gen version $(git describe --tags $(git rev-list --tags --max-count=1))\n            go run github.com/v2fly/V2BuildAssist/v2buildutil gen project \"v2fly\"\n            for zip in $(ls *.zip); do\n              go run github.com/v2fly/V2BuildAssist/v2buildutil gen file ${zip}\n            done\n          } >Release.unsigned.unsorted\n          go run github.com/v2fly/V2BuildAssist/v2buildutil gen sort < Release.unsigned.unsorted > Release.unsigned\n          rm -f Release.unsigned.unsorted\n          FILE=./Release.unsigned\n          DGST=$FILE.dgst\n          openssl dgst -md5    $FILE | sed 's/([^)]*)//g' >>$DGST\n          openssl dgst -sha1   $FILE | sed 's/([^)]*)//g' >>$DGST\n          openssl dgst -sha256 $FILE | sed 's/([^)]*)//g' >>$DGST\n          openssl dgst -sha512 $FILE | sed 's/([^)]*)//g' >>$DGST\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: Release.unsigned\n          path: build_artifacts/Release.unsigned\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: Release.unsigned.dgst\n          path: build_artifacts/Release.unsigned.dgst\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: v2ray-extra.zip\n          path: build_artifacts/v2ray-extra.zip\n\n      - name: Upload Release.unsigned related files\n        uses: svenstaro/upload-release-action@v2\n        if: github.event_name == 'release'\n        with:\n          repo_token: ${{ secrets.GITHUB_TOKEN }}\n          file_glob: true\n          file: build_artifacts/Release.unsigned*\n          tag: ${{ github.ref }}\n          overwrite: true\n\n      - name: Upload extra package\n        uses: svenstaro/upload-release-action@v2\n        if: github.event_name == 'release'\n        with:\n          repo_token: ${{ secrets.GITHUB_TOKEN }}\n          file_glob: true\n          file: build_artifacts/v2ray-extra.zip\n          tag: ${{ github.ref }}\n          overwrite: true\n\n  buildContainer:\n    if: github.event_name == 'release'\n    needs: signature\n    name: Build And Push image\n    runs-on: ubuntu-latest\n    env:\n      REGISTRY_USER: ${{ github.actor }}\n      REGISTRY_PASSWORD: ${{ github.token }}\n      IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }}\n      RELEASE_REPO: ${{ github.repository }}\n      VERSION: ${{ github.event.release.tag_name }}\n      TIMESTAMP: ${{ github.event.release.created_at }}\n      PRERELEASE: ${{ github.event.release.prerelease }}\n      VARIANTS: | # <v2ray variant>:<image tag suffix>\n        std:\n        extra:-extra\n      ARCHS: | # <v2ray arch name>:<container arch name>\n        32:386\n        64:amd64\n        arm32-v6:arm/v6\n        arm32-v7a:arm/v7\n        arm64-v8a:arm64\n        arm64-v8a:arm64/v8\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Log in to ghcr.io\n        uses: redhat-actions/podman-login@v1\n        with:\n          username: ${{ env.REGISTRY_USER }}\n          password: ${{ env.REGISTRY_PASSWORD }}\n          registry: ${{ env.IMAGE_REGISTRY }}\n\n      - name: Build Images\n        id: build-image\n        run: |\n          image=v2ray\n          tags=\n\n          timestamp=$(date -d $TIMESTAMP +%s)\n          versions=\"$VERSION\" # full version (v1.2.3)\n          versions=\"$versions $(echo $VERSION | cut -d. -f1,2)\" # minor version (v1.2)\n          if [ $PRERELEASE = false ]; then\n            versions=\"$versions $(echo $VERSION | cut -d. -f1)\" # major version (v1)\n            versions=\"$versions latest\"\n          fi\n\n          formatEach() {\n            format=$1\n            shift 1\n            echo \"$@\" | xargs -n1 | xargs -i echo \"$format\" | xargs\n          }\n\n          for variant in $VARIANTS; do\n            v2Variant=$(echo $variant | cut -d: -f1)\n            containerVariant=$(echo $variant | cut -d: -f2)\n            variantTags=$(formatEach \"{}$containerVariant\" $versions)\n            tags=\"$tags $variantTags\"\n            for arch in $ARCHS; do\n              v2Arch=$(echo $arch | cut -d: -f1)\n              containerArch=$(echo $arch | cut -d: -f2)\n              bash ./release/container/downloadAssets.sh $VERSION $v2Arch $containerArch $v2Variant\n              for tag in $variantTags; do\n                buildah bud \\\n                  --manifest $image:$tag \\\n                  --file ./release/container/Containerfile \\\n                  --platform linux/$containerArch \\\n                  --timestamp $timestamp \\\n                  --squash \\\n                  ./context/linux/$containerArch/$v2Variant\n              done\n            done\n          done\n\n          echo image=$image >> $GITHUB_OUTPUT\n          echo tags=$tags >> $GITHUB_OUTPUT\n\n      - name: Push To ghcr.io\n        uses: redhat-actions/push-to-registry@v2\n        with:\n          image: ${{ steps.build-image.outputs.image }}\n          tags: ${{ steps.build-image.outputs.tags }}\n          registry: ${{ env.IMAGE_REGISTRY }}\n"
  },
  {
    "path": ".github/workflows/sign.yml",
    "content": "name: Sign\n\non:\n  release:\n    types: [released]\n\njobs:\n  sign:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout default branch\n        uses: actions/checkout@v6\n\n      - name: Grant it execution permission\n        run: |\n          chmod +x $GITHUB_WORKSPACE/release/requestsign.sh\n\n      - name: Invoke release signing\n        env:\n          SIGN_SERVICE_PASSWORD: ${{ secrets.SIGN_SERVICE_PASSWORD }}\n          SIGN_SERIVCE_URL: ${{ secrets.SIGN_SERIVCE_URL_V5 }}\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          export SIGN_VERSION=$(cat $GITHUB_EVENT_PATH| jq -r \".release.tag_name\")\n          echo $SIGN_VERSION\n          $GITHUB_WORKSPACE/release/requestsign.sh\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: Mark stale issues and pull requests\n\non:\n  schedule:\n    - cron: \"30 1 * * *\"\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@v10\n        with:\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n          stale-issue-message: \"This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days\"\n          stale-pr-message: \"It has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days\"\n          days-before-stale: 120\n          days-before-close: 5\n          exempt-pr-labels: \"planned\"\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\non:\n  push:\n    branches:\n      - master\n      - v*\n      - dev*\n    paths:\n      - \"**/*.go\"\n      - \"go.mod\"\n      - \"go.sum\"\n      - \".github/workflows/test.yml\"\n  pull_request:\n    types: [opened, synchronize, reopened]\n    paths:\n      - \"**/*.go\"\n      - \"go.mod\"\n      - \"go.sum\"\n      - \".github/workflows/test.yml\"\n\njobs:\n  test:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [windows-latest, ubuntu-latest, macos-latest]\n    steps:\n      - name: Checkout codebase\n        uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n\n      - name: Set up Go\n        uses: actions/setup-go@v6\n        with:\n          go-version-file: ./go.mod\n          cache-dependency-path: ./go.sum\n\n      - name: Check Go modules\n        run: |\n          go mod tidy\n          git diff --exit-code go.mod go.sum\n          go mod verify\n\n      - name: Run tests with coverage report\n        run: |\n          go test ./... -v -timeout=1h -coverprofile=coverage.out -covermode=atomic\n\n      - name: Upload coverage to Codecov\n        uses: codecov/codecov-action@v5\n        if: runner.os == 'Linux'\n        env:\n          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n        with:\n          slug: ${{ github.repository }}\n          verbose: true\n          fail_ci_if_error: true\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\n# vendor/\n\n*.DS_Store\n.idea\n*.zip\n*.tar.gz\nv2ray\nv2ctl\nmockgen\nvprotogen\n!infra/vprotogen/\nerrorgen\n!common/errors/errorgen/\n*.dat\n*~\n[._]*.un~\n\n.golangci.yml"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-2025 V2Fly Community\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": "README.md",
    "content": "<div>\n  <img width=\"190\" height=\"210\" align=\"left\" src=\"https://raw.githubusercontent.com/v2fly/v2fly-github-io/master/docs/.vuepress/public/readme-logo.png\" alt=\"V2Ray\"/>\n  <br>\n  <h1>Project V</h1>\n  <p>Project V is a set of network tools that helps you to build your own computer network. It secures your network connections and thus protects your privacy.</p>\n</div>\n\n[![GitHub Test Badge](https://github.com/v2fly/v2ray-core/actions/workflows/test.yml/badge.svg)](https://github.com/v2fly/v2ray-core/actions/workflows/test.yml)\n[![codecov.io](https://codecov.io/gh/v2fly/v2ray-core/branch/master/graph/badge.svg?branch=master)](https://codecov.io/gh/v2fly/v2ray-core?branch=master)\n[![goreportcard](https://goreportcard.com/badge/github.com/v2fly/v2ray-core/v5)](https://goreportcard.com/report/github.com/v2fly/v2ray-core/v5)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/e150b7ede2114388921943bf23d95161)](https://app.codacy.com/gh/v2fly/v2ray-core/dashboard)\n[![Downloads](https://img.shields.io/github/downloads/v2fly/v2ray-core/total.svg)](https://github.com/v2fly/v2ray-core/releases/latest)\n\n## Related Links\n\n- [Documentation](https://www.v2fly.org) and [Newcomer's Instructions](https://www.v2fly.org/guide/start.html)\n- Welcome to translate V2Ray documents via [Transifex](https://www.transifex.com/v2fly/public/)\n\n## Packaging Status\n\n> If you are willing to package V2Ray for other distros/platforms, please let us know or seek for help via [GitHub issues](https://github.com/v2fly/v2ray-core/issues).\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/v2ray.svg)](https://repology.org/project/v2ray/versions)\n\n## License\n\n[The MIT License (MIT)](https://raw.githubusercontent.com/v2fly/v2ray-core/master/LICENSE)\n\n## Credits\n\nThis repo relies on the following third-party projects:\n\n- In production:\n  - [gorilla/websocket](https://github.com/gorilla/websocket)\n  - [quic-go/quic-go](https://github.com/quic-go/quic-go)\n  - [pires/go-proxyproto](https://github.com/pires/go-proxyproto)\n  - [seiflotfy/cuckoofilter](https://github.com/seiflotfy/cuckoofilter)\n  - [google/starlark-go](https://github.com/google/starlark-go)\n  - [jhump/protoreflect](https://github.com/jhump/protoreflect)\n  - [inetaf/netaddr](https://github.com/inetaf/netaddr)\n\n- For testing only:\n  - [miekg/dns](https://github.com/miekg/dns)\n  - [h12w/socks](https://github.com/h12w/socks)\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# 安全策略 Security Policy\n\n## 受支持的版本 Supported Versions\n\n目前 v2ray-core 项目由 [V2Fly 社区](https://github.com/v2fly) 继续提供代码维护，由于精力有限且项目复杂度较高，只维护主线代码的功能和安全性完整。原则上主页的兼容性保证继续遵循，\n如有例外另行说明。\n\nCurrently v2ray-core project is maintained by [V2Fly community](https://github.com/v2fly). Feature and security guarantee may only be limited to the\nmaster branch, though we would still try our best to follow the compatibility claims listed on the official website.\n\n\n## 汇报安全风险 Reporting a Vulnerability\n\n使用邮箱: security |at| v2fly.org。\n\nReport to email: security |at| v2fly.org.\n\nGPG public key:\n\n```\npub   rsa4096 2020-06-02 [SC] [有效至：2022-01-02]\n      E2E35E27914FB007C0D4B6DDB117BA3BE8B494A7\nuid           [ 绝对 ] V2Fly Developers <dev@v2fly.org>\nsub   rsa4096 2020-06-02 [E] [有效至：2022-01-02]\nsub   rsa4096 2020-11-08 [S] [有效至：2022-01-02] // 用于 Debian / Ubuntu 签名\n\n\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBF7V7pQBEACozcw4/BlPgFWaz4AdN8HKSrCDLlN+/g7m4AKZIo13fAnDh+sJ\n2H4NrWNr0xxgovbco5Xw4OSSwY1BuUhnb4AmIyxbwqUQD2UADe5xD6gMBwNiJTP4\n02VCHhh7DnWTeLbAsUgRotxUCxsWVvd2F08SYGfJggOVftOnG+VNnwzTOvHWFVEw\n1Pv1DaY7bKSA0voACerRbAPCYqhmElAGJHYNjBMaxqCaWFJWpAFfBxkvS1FDVyZk\nBsABhn6sOcGJn8EYSHUIXhWwqtkQCjBB4OOik+Jn+S2DFGyk5l1NrGRQtX8C0BYn\nnc7VaxtFOp5fnJ4y0GNd4AM9KO0/Ojosi6b64l407Fj9i9OXznmZUACQw2u+VcL3\nqNy768hsTmka3pXzpRHZwYcOLOEr3jGHmLOtXgQ656OjF8Xd9DJ4cB42X8iBeqTp\niQchHIdBpnu27ZbBFy09OMak+STB5zA0JmxDaC8b48mVkc0BMRXdYl7wWXJsEJf1\nroAOr3RCBKiE840w0PLOTnUljfqazPYTwzs91oP+SeZjBmGOpaAh7bh5BVOpzPSE\nbdA61/n01GEb5bpOKpaTi9GviF3RCbfFnLKJnBq0vHvW9BqKTVFRPAKkBGuOPBdy\n8MBNY+VY/2aP3ukZUoYe8Ypl9Q7dVPRjnoWaH0sEMzftoh+3s7GSSgAylQARAQAB\ntCBWMkZseSBEZXZlbG9wZXJzIDxkZXZAdjJmbHkub3JnPokCVAQTAQgAPgIbAwUL\nCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBOLjXieRT7AHwNS23bEXujvotJSnBQJf\np4leBQkC+1DKAAoJELEXujvotJSn124P/0swu9POvEQtxVlRzNh2VjAGHZ5NEDnl\npMrhfC5ryCYtlVS/kc2WwRhIRHKzr9nbamgSxUCiyLagfnIjhIvAohun49grYNzG\nMZWRURiuFrCnYbD7juJTvfbzZCzJk7LPsdnqHWr8fYcOZMTOZVzQiQB2jUx2KeRm\nyV8aV21Z8gMLqSGjs06a0UaRbKB0FSysTURm91/jFmiH43aG1s/LcB9/lKf5HpNl\n9or6LrEOrokAwtkMSBYTqm7Dp1j+cK0iOMw2CmMqmQZkV+i6msYrQRiX/X6YufiM\nwfMMSdOZOz9KG+k+C6N1swSbGeDMrJfnDUDbvrAXKhDjNgY7UBwbk69Abd7Y9aQz\n/jVmrFEWt4lisBxglBot60CRUTM2boK/uQS5zBCJhemeg14F9Q/FRiUTlS8jQoeK\nPWeK2lagYJS8lpJZLXkqe4xSpjCgoT0Z+lYSfTjx+T0AFF+xz5E243Lb5kDxwnR9\nY5CZt3vV6GWBYOt9MEL3pk7AnYyNT1y1KIiMyONh/Z1koUdHr4J9exllnsmAJQUa\nW/j0UtVsLsvUjFv9RTr9w5p/U0J0VLIN0YOpx4wYaBEwFIa8lsL+Ey1Vphkvvjfz\nuMRAHe4v+axWb1f1hVCBjtyCVyvzf+i9RTAYsBJ3MJ0C8cvvrm10N9B7MHh0JZA5\nPcJSilailp1TuQINBF7V7pQBEADkQdO75smeKnmPt0/aNNlb7JDOSWW5VY0kYgx3\n6Toh139JstIQ2xz0CLSGReizUFB6eR3DXmezLrmhkgN2Aq5A+hCtFAJwWKuKr1HS\nusvJ1el9h0oh7IO+tF8E/gNYwWfabjPX27FGVCHR1qG7ffN51Bghrnwi1T4YC98E\nR9EGU6N0Xs9DeIJL9WQPH/DF22251i/OAXkqKVGn3PNe2cBsp0yKxr9mlSyzjrha\nKXokPiPcvNqlnkiDCgfiRj7c2C2Lyl9PoEiGpsNZaCZYkMPgjM0xiLenQddwRyOU\nz2cLG3d8WdCTRyHSZd/YQtSi5R6AnkJEsVtUiDN5zwNFVpQlTq3jNHsVUpjFU2nK\nourTZVCCLbAC60VTdxLN6eFO0f+lS2WjyJ7uZ9SGbS6uP0jMNphH/QjVF848bWXs\n1CuZty5QQY7+MTNUAhSWWntrpTkdXYqT0zUqiOc1YNnkfg3hvC4d0dbnFTfcyZnB\nSg8e7/9n6+ms75/deYgnLuA6h7pkIcflm7pUMfVKXKz5Vlc8FC9ia0UtobeKBKqi\njObfiO/zmNL0HQBeX0e8GkJrCyv6ikD8cUqsmVtgw7jdxGsV0SL5CddDnGKsc68O\npGDmkAuRqR3QtXju/4r7a8IEVveGWc3rUvddYrtqbbCNWCN0JKX13PEvbNAm+2eD\nMGQtcQARAQABiQI8BBgBCAAmAhsMFiEE4uNeJ5FPsAfA1LbdsRe6O+i0lKcFAl+n\ndwcFCQL7PnMACgkQsRe6O+i0lKeWfxAApopL5I9p4btmkcLIg2lkA1n+czFekbdr\n2tjFKrBER4QWkyDCUE8QaVo/ECveTHmnxrTB/djW6xqPVS77PL8xOATIYTo6qU38\noTCB1T7/P2L9qI72BzcRY5f9ZPyJhCtrkvjCPzjUjw+ZIPIOgQcWgKHWnE+OyUKD\n0GkVEUME3QP5S4Nr3XGrgS7oxDAmD52u7pn0mSk5WmEcLW0oGwsVdc4aDXxpX+u/\ngkBZysmAuomPov7iXVosMakl+4rz30yPcrL9A81m1WAeB3PGkpaO3B++8Ql+FBCQ\nOrLtPn/nnIzEuAXB1Hd8vYzxtRM2CZvhRExM7xofnhkBJOtR/ddfbJa7H5+Aruc0\n4S0JIaqMCrC6tZezjTACAzrWULmZZGmrHbLrmXBuLk0huRkeIRnDzHP+DoE2UciL\n3hR9EGOHX9O/dGb3bb3y11LAf7GI28ZG7So1GeoFkEOga1IJnsBnXCqwM8vbDDWq\n/7aLb3/m0gT7DUfjeXKfWPJXcnaq8r4llHzDn2i6ax4Uq/brCOLj9ovVGIctZTbt\nyvsFOc1bVkSuUM+pMkCtBx80/sJSB2Nu94S6osdaUlRE+jaCcqEbPd+G68Yd0Khi\nCL8zF1a3dX1dpuVFTLNpXOgrviGBzXQmzFeil7mWFs0l+1XZOPz9nhmRrMn6wV3n\ni4KItRSJAXy5Ag0EX6d5hQEQAMsVyLTXdybeei2nWDb5jtzzC3AtSnPWtKG4B86C\nBXncaZpU43hKI3oduW2+42eM8n8KTvO11r9xv4zKATfaHBZq2hkKZdDQjuSstovr\na3hapHHknHeNVTg3yuiakKzpr6FK23W/GE1lJfhz254v9+dRV0KazWksXvpGEdgI\n+6sC4Nr5bKgJVEQibyrrL0gmzlVB/oQU/W4eGvk21zmgMlHri+edBLpVtlCmn7k/\n0t+2X9D1Pq2nkjMUurB9EJ1z24LMldmPOl6P7iJCx9kSUjcHrEg56q5VSZq50FAj\nDeSjAqsdussI8cdstCMktE9nhizxVKFXpbXifqoYfJwCo23wFqQJpyPgQqHIT12s\nGWRUa/MF6hRYg/5CyeadDmkmnKPTPjmQ2S2SFNXX7xs+dZKvIvXP30z4cpuVY8i8\nchZSRNb8K0L9T0Jme7CPm28F6lvDUkNDQ1WErXZruHbOKwQOfQBdXK3nedOiUpBt\n401HVlGUJSInfEb3JXU01tRqnnzI/y5z7cWCGEMEa6TeaCrMbVvl8xeAA1w/nw0y\nzHz6/Pnf4TITuCH22aa7+xfgpq8gRLhUUws89mbQT+9fd8tT65+Q8xcaLCyzrLAq\nzND5sVZ4/PwaYc8UNZcHjeQR7aYWI1xgr/IwY1wyDWZLbWgkk0HVxpvYdMEpJryD\nAyMdABEBAAGJBHIEGAEIACYWIQTi414nkU+wB8DUtt2xF7o76LSUpwUCX6d5hQIb\nAgUJAim2AAJACRCxF7o76LSUp8F0IAQZAQgAHRYhBK8FZLGpNMztuW02YbJOz+X/\nddOBBQJfp3mFAAoJELJOz+X/ddOBNKQP/0nwIC4R9gQhY53vME7VA7elIrBiSM6d\nVa26a7J1nrCcpDAE7Lp0TqzrDMqyen+IL4X5QK5sKTgenYTgjppEJIQn+Wup54ix\nI+YOQ8MVLfN6/3QPACWMngSPRF+UKDg4hyTCEL+/GCgTp58oXrl/YIO6Oqt5drog\nw4+4ufU1/eKTb2ruGULGl9jZvFSZpLdsvJ19xJB2kC1k8GVNu7MnUL+S2pU/9kO4\n5EZ/jEa1wT45zev+HdmzX5TYW6SLaI9HKHMqbQz2EHc3tRYIDaz3FE3s4VdMjqpp\ne42SvkOYaguc6cXToDbzBmU+iWGlXCTHfNhxwxoUYcKZlDEkEtvSYHJOb0k9eqbT\ngvMb5GjbAgqqwOBwtN3v790j8jEG+cdXR3qHcEx0bw3F2Bd18U7j946OxHLKE5Xk\n2sWEG422maVrE9o1DdeTV5oDFNNPBzqfjgGBZCCKrjkpldhDOHeoDU2aFMJ7yVqw\nZwKwJ5f8fdNS13UnQVwGsZ2BsW1cox5ZGZ/C5A7mfSF1WAgJcYIw4M2JQbDn4Yuw\nyqjyg53lT3OurBONbEZ7unnsLqpT9qKwZ1qCemqGRJieXXxJwl7G4gBgZbH0rBJR\n6dhbyt4c2JE8MMdC65mDWneltNM6pttC/j5jCuvIlZGACZ91UuLLediJJWAlOJ+1\nfBQ0m8TD6d8ZrakP/RFMLZrxh9WPaFB43sW/b1Fq2h933HQ29oSQFuXhsHsx1Vaq\nHTRTcBB7kywAr9+zMYsOsk0/WnoZNGoMkUWu/gFkb6CdUcsdEumgyZ8S24VoBCHB\nT1fD/8eOA5K82hwAFcKbPwuuTLtf9b9HB4/xsObfcczTeqIknzIPsGlgVz4w1c9a\nStSo4iI4bCSLL+/mqiXZ+ArXJ/z4Vejl92fNLWVOlOrjkBV+AY6iAFCCsxJ1O5ud\n5a5r1bUeBXd0BcQ1m/hpjawMC1y0SkIBTQCgxIQoPoxJ27hHNIN1R2nkqfY9vboQ\n7O0uIHF8fmuz93xg68ZTW0JHwOw4Mz88lGibE2laHApjKWZAtF/i+LlhbnewtESL\nEuGTT7gt7cSHgnBiDEIm5UJVEGeM0sMReztxy9V7glohH5DV8GpVK/GncKlsrh1K\nBuEuz7IrqKlBzhsDy0SrNZpX7EzsiU1uvoA6teT4EPey8qXH+7WR9B2ad1Zc5yE3\nzv4BpnWkkJp8qdYu4fdCs/mrmnBR5G1YdOAIlNWhU74Wdyq+W4HfTWMgvJHmElnZ\nUvQ9RDTWnw2+3n2ATeLf9ZwW1g4/Dqh55OaLtJZo5me8vU9W+vkm34xzfVfD/mus\nljogw5eiGyj8j3lUVjYWu28l/bz0zDUueWmHhV8E8z0Cn7OhrHPpUCHx2Aep\n=quYd\n-----END PGP PUBLIC KEY BLOCK-----\n\n\n```\n"
  },
  {
    "path": "annotations.go",
    "content": "package core\n\n// Annotation is a concept in V2Ray. This struct is only for documentation. It is not used anywhere.\n// Annotations begin with \"v2ray:\" in comment, as metadata of functions or types.\ntype Annotation struct {\n\t// API is for types or functions that can be used in other libs. Possible values are:\n\t//\n\t// * v2ray:api:beta for types or functions that are ready for use, but maybe changed in the future.\n\t// * v2ray:api:stable for types or functions with guarantee of backward compatibility.\n\t// * v2ray:api:deprecated for types or functions that should not be used anymore.\n\t//\n\t// Types or functions without api annotation should not be used externally.\n\tAPI string\n}\n"
  },
  {
    "path": "app/app.go",
    "content": "// Package app contains feature implementations of V2Ray. The features may be enabled during runtime.\npackage app\n"
  },
  {
    "path": "app/browserforwarder/config.pb.go",
    "content": "package browserforwarder\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// Config is the settings for BrowserForwarder.\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tListenAddr    string                 `protobuf:\"bytes,1,opt,name=listen_addr,json=listenAddr,proto3\" json:\"listen_addr,omitempty\"`\n\tListenPort    int32                  `protobuf:\"varint,2,opt,name=listen_port,json=listenPort,proto3\" json:\"listen_port,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_browserforwarder_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_browserforwarder_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_browserforwarder_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetListenAddr() string {\n\tif x != nil {\n\t\treturn x.ListenAddr\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetListenPort() int32 {\n\tif x != nil {\n\t\treturn x.ListenPort\n\t}\n\treturn 0\n}\n\nvar File_app_browserforwarder_config_proto protoreflect.FileDescriptor\n\nconst file_app_browserforwarder_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!app/browserforwarder/config.proto\\x12\\x1fv2ray.core.app.browserforwarder\\x1a common/protoext/extensions.proto\\\"b\\n\" +\n\t\"\\x06Config\\x12\\x1f\\n\" +\n\t\"\\vlisten_addr\\x18\\x01 \\x01(\\tR\\n\" +\n\t\"listenAddr\\x12\\x1f\\n\" +\n\t\"\\vlisten_port\\x18\\x02 \\x01(\\x05R\\n\" +\n\t\"listenPort:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\aservice\\x12\\abrowserB~\\n\" +\n\t\"#com.v2ray.core.app.browserforwarderP\\x01Z3github.com/v2fly/v2ray-core/v5/app/browserforwarder\\xaa\\x02\\x1fV2Ray.Core.App.Browserforwarderb\\x06proto3\"\n\nvar (\n\tfile_app_browserforwarder_config_proto_rawDescOnce sync.Once\n\tfile_app_browserforwarder_config_proto_rawDescData []byte\n)\n\nfunc file_app_browserforwarder_config_proto_rawDescGZIP() []byte {\n\tfile_app_browserforwarder_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_browserforwarder_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_browserforwarder_config_proto_rawDesc), len(file_app_browserforwarder_config_proto_rawDesc)))\n\t})\n\treturn file_app_browserforwarder_config_proto_rawDescData\n}\n\nvar file_app_browserforwarder_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_browserforwarder_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.app.browserforwarder.Config\n}\nvar file_app_browserforwarder_config_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_app_browserforwarder_config_proto_init() }\nfunc file_app_browserforwarder_config_proto_init() {\n\tif File_app_browserforwarder_config_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: unsafe.Slice(unsafe.StringData(file_app_browserforwarder_config_proto_rawDesc), len(file_app_browserforwarder_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_browserforwarder_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_browserforwarder_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_browserforwarder_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_browserforwarder_config_proto = out.File\n\tfile_app_browserforwarder_config_proto_goTypes = nil\n\tfile_app_browserforwarder_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/browserforwarder/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.browserforwarder;\n\noption csharp_namespace = \"V2Ray.Core.App.Browserforwarder\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/browserforwarder\";\noption java_package = \"com.v2ray.core.app.browserforwarder\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\n// Config is the settings for BrowserForwarder.\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"browser\";\n\n  string listen_addr = 1;\n  int32 listen_port = 2;\n}"
  },
  {
    "path": "app/browserforwarder/errors.generated.go",
    "content": "package browserforwarder\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/browserforwarder/forwarder.go",
    "content": "package browserforwarder\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/v2fly/BrowserBridge/handler\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/securedload\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype Forwarder struct {\n\tctx context.Context\n\n\tforwarder  *handler.HTTPHandle\n\thttpserver *http.Server\n\n\tconfig *Config\n}\n\nfunc (f *Forwarder) ServeHTTP(writer http.ResponseWriter, request *http.Request) {\n\trequestPath := request.URL.Path[1:]\n\n\tswitch requestPath {\n\tcase \"\":\n\t\tfallthrough\n\tcase \"index.js\":\n\t\tBridgeResource(writer, request, requestPath)\n\tcase \"link\":\n\t\tf.forwarder.ServeBridge(writer, request)\n\t}\n}\n\nfunc (f *Forwarder) DialWebsocket(url string, header http.Header) (io.ReadWriteCloser, error) {\n\tprotocolHeader := false\n\tprotocolHeaderValue := \"\"\n\tunsupportedHeader := false\n\tfor k, v := range header {\n\t\tif k == \"Sec-Websocket-Protocol\" {\n\t\t\tprotocolHeader = true\n\t\t\tprotocolHeaderValue = v[0]\n\t\t} else {\n\t\t\tunsupportedHeader = true\n\t\t}\n\t}\n\tif unsupportedHeader {\n\t\treturn nil, newError(\"unsupported header used, only Sec-Websocket-Protocol is supported for forwarder\")\n\t}\n\tif !protocolHeader {\n\t\treturn f.forwarder.Dial(url)\n\t}\n\treturn f.forwarder.Dial2(url, protocolHeaderValue)\n}\n\nfunc (f *Forwarder) Type() interface{} {\n\treturn extension.BrowserForwarderType()\n}\n\nfunc (f *Forwarder) Start() error {\n\tif f.config.ListenAddr != \"\" {\n\t\tf.forwarder = handler.NewHttpHandle()\n\t\tf.httpserver = &http.Server{Handler: f}\n\n\t\tvar listener net.Listener\n\t\tvar err error\n\t\taddress := net.ParseAddress(f.config.ListenAddr)\n\n\t\tswitch {\n\t\tcase address.Family().IsIP():\n\t\t\tlistener, err = internet.ListenSystem(f.ctx, &net.TCPAddr{IP: address.IP(), Port: int(f.config.ListenPort)}, nil)\n\t\tcase strings.EqualFold(address.Domain(), \"localhost\"):\n\t\t\tlistener, err = internet.ListenSystem(f.ctx, &net.TCPAddr{IP: net.IP{127, 0, 0, 1}, Port: int(f.config.ListenPort)}, nil)\n\t\tdefault:\n\t\t\treturn newError(\"forwarder cannot listen on the address: \", address)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn newError(\"forwarder cannot listen on the port \", f.config.ListenPort).Base(err)\n\t\t}\n\n\t\tgo func() {\n\t\t\tif err := f.httpserver.Serve(listener); err != nil {\n\t\t\t\tnewError(\"cannot serve http forward server\").Base(err).WriteToLog()\n\t\t\t}\n\t\t}()\n\t}\n\treturn nil\n}\n\nfunc (f *Forwarder) Close() error {\n\tif f.httpserver != nil {\n\t\treturn f.httpserver.Close()\n\t}\n\treturn nil\n}\n\nfunc BridgeResource(rw http.ResponseWriter, r *http.Request, path string) {\n\tcontent := path\n\tif content == \"\" {\n\t\tcontent = \"index.html\"\n\t}\n\tdata, err := securedload.GetAssetSecured(\"browserforwarder/\" + content)\n\tif err != nil {\n\t\terr = newError(\"cannot load necessary resources\").Base(err)\n\t\thttp.Error(rw, err.Error(), http.StatusForbidden)\n\t\treturn\n\t}\n\n\thttp.ServeContent(rw, r, path, time.Now(), bytes.NewReader(data))\n}\n\nfunc NewForwarder(ctx context.Context, cfg *Config) *Forwarder {\n\treturn &Forwarder{config: cfg, ctx: ctx}\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\treturn NewForwarder(ctx, cfg.(*Config)), nil\n\t}))\n}\n"
  },
  {
    "path": "app/commander/commander.go",
    "content": "package commander\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\n\t\"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/v5cfg\"\n)\n\ntype CommanderIfce interface {\n\tfeatures.Feature\n\n\tExtractGrpcServer() *grpc.Server\n}\n\n// Commander is a V2Ray feature that provides gRPC methods to external clients.\ntype Commander struct {\n\tsync.Mutex\n\tserver   *grpc.Server\n\tservices []Service\n\tohm      outbound.Manager\n\ttag      string\n}\n\n// NewCommander creates a new Commander based on the given config.\nfunc NewCommander(ctx context.Context, config *Config) (*Commander, error) {\n\tc := &Commander{\n\t\ttag: config.Tag,\n\t}\n\n\tcommon.Must(core.RequireFeatures(ctx, func(om outbound.Manager) {\n\t\tc.ohm = om\n\t}))\n\n\tfor _, rawConfig := range config.Service {\n\t\tconfig, err := serial.GetInstanceOf(rawConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trawService, err := common.CreateObject(ctx, config)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tservice, ok := rawService.(Service)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a Service.\")\n\t\t}\n\t\tc.services = append(c.services, service)\n\t}\n\n\treturn c, nil\n}\n\n// Type implements common.HasType.\nfunc (c *Commander) Type() interface{} {\n\treturn (*CommanderIfce)(nil)\n}\n\n// Start implements common.Runnable.\nfunc (c *Commander) Start() error {\n\tc.Lock()\n\tc.server = grpc.NewServer()\n\tfor _, service := range c.services {\n\t\tservice.Register(c.server)\n\t}\n\tc.Unlock()\n\n\tlistener := &OutboundListener{\n\t\tbuffer: make(chan net.Conn, 4),\n\t\tdone:   done.New(),\n\t}\n\n\tgo func() {\n\t\tif err := c.server.Serve(listener); err != nil {\n\t\t\tnewError(\"failed to start grpc server\").Base(err).AtError().WriteToLog()\n\t\t}\n\t}()\n\n\tif err := c.ohm.RemoveHandler(context.Background(), c.tag); err != nil {\n\t\tnewError(\"failed to remove existing handler\").WriteToLog()\n\t}\n\n\treturn c.ohm.AddHandler(context.Background(), &Outbound{\n\t\ttag:      c.tag,\n\t\tlistener: listener,\n\t})\n}\n\n// Close implements common.Closable.\nfunc (c *Commander) Close() error {\n\tc.Lock()\n\tdefer c.Unlock()\n\n\tif c.server != nil {\n\t\tc.server.Stop()\n\t\tc.server = nil\n\t}\n\n\treturn nil\n}\n\n// ExtractGrpcServer extracts the gRPC server from Commander.\n// Private function for core code base.\nfunc (c *Commander) ExtractGrpcServer() *grpc.Server {\n\tc.Lock()\n\tdefer c.Unlock()\n\treturn c.server\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\treturn NewCommander(ctx, cfg.(*Config))\n\t}))\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\tsimplifiedConfig := cfg.(*SimplifiedConfig)\n\t\tfullConfig := &Config{\n\t\t\tTag:     simplifiedConfig.Tag,\n\t\t\tService: nil,\n\t\t}\n\t\tfor _, v := range simplifiedConfig.Name {\n\t\t\tpack, err := v5cfg.LoadHeterogeneousConfigFromRawJSON(ctx, \"grpcservice\", v, []byte(\"{}\"))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tfullConfig.Service = append(fullConfig.Service, serial.ToTypedMessage(pack))\n\t\t}\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n"
  },
  {
    "path": "app/commander/config.pb.go",
    "content": "package commander\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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// Config is the settings for Commander.\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Tag of the outbound handler that handles grpc connections.\n\tTag string `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\t// Services that supported by this server. All services must implement Service\n\t// interface.\n\tService       []*anypb.Any `protobuf:\"bytes,2,rep,name=service,proto3\" json:\"service,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_commander_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_commander_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_commander_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetService() []*anypb.Any {\n\tif x != nil {\n\t\treturn x.Service\n\t}\n\treturn nil\n}\n\n// ReflectionConfig is the placeholder config for ReflectionService.\ntype ReflectionConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ReflectionConfig) Reset() {\n\t*x = ReflectionConfig{}\n\tmi := &file_app_commander_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ReflectionConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ReflectionConfig) ProtoMessage() {}\n\nfunc (x *ReflectionConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_commander_config_proto_msgTypes[1]\n\tif 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 ReflectionConfig.ProtoReflect.Descriptor instead.\nfunc (*ReflectionConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_commander_config_proto_rawDescGZIP(), []int{1}\n}\n\ntype SimplifiedConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tName          []string               `protobuf:\"bytes,2,rep,name=name,proto3\" json:\"name,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_app_commander_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_commander_config_proto_msgTypes[2]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_commander_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SimplifiedConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedConfig) GetName() []string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn nil\n}\n\nvar File_app_commander_config_proto protoreflect.FileDescriptor\n\nconst file_app_commander_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1aapp/commander/config.proto\\x12\\x18v2ray.core.app.commander\\x1a\\x19google/protobuf/any.proto\\x1a common/protoext/extensions.proto\\\"J\\n\" +\n\t\"\\x06Config\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12.\\n\" +\n\t\"\\aservice\\x18\\x02 \\x03(\\v2\\x14.google.protobuf.AnyR\\aservice\\\"1\\n\" +\n\t\"\\x10ReflectionConfig:\\x1d\\x82\\xb5\\x18\\x19\\n\" +\n\t\"\\vgrpcservice\\x12\\n\" +\n\t\"reflection\\\"R\\n\" +\n\t\"\\x10SimplifiedConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x02 \\x03(\\tR\\x04name:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\aservice\\x12\\tcommanderBi\\n\" +\n\t\"\\x1ccom.v2ray.core.app.commanderP\\x01Z,github.com/v2fly/v2ray-core/v5/app/commander\\xaa\\x02\\x18V2Ray.Core.App.Commanderb\\x06proto3\"\n\nvar (\n\tfile_app_commander_config_proto_rawDescOnce sync.Once\n\tfile_app_commander_config_proto_rawDescData []byte\n)\n\nfunc file_app_commander_config_proto_rawDescGZIP() []byte {\n\tfile_app_commander_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_commander_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_commander_config_proto_rawDesc), len(file_app_commander_config_proto_rawDesc)))\n\t})\n\treturn file_app_commander_config_proto_rawDescData\n}\n\nvar file_app_commander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_app_commander_config_proto_goTypes = []any{\n\t(*Config)(nil),           // 0: v2ray.core.app.commander.Config\n\t(*ReflectionConfig)(nil), // 1: v2ray.core.app.commander.ReflectionConfig\n\t(*SimplifiedConfig)(nil), // 2: v2ray.core.app.commander.SimplifiedConfig\n\t(*anypb.Any)(nil),        // 3: google.protobuf.Any\n}\nvar file_app_commander_config_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.app.commander.Config.service:type_name -> google.protobuf.Any\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_commander_config_proto_init() }\nfunc file_app_commander_config_proto_init() {\n\tif File_app_commander_config_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: unsafe.Slice(unsafe.StringData(file_app_commander_config_proto_rawDesc), len(file_app_commander_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_commander_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_commander_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_commander_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_commander_config_proto = out.File\n\tfile_app_commander_config_proto_goTypes = nil\n\tfile_app_commander_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/commander/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.commander;\noption csharp_namespace = \"V2Ray.Core.App.Commander\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/commander\";\noption java_package = \"com.v2ray.core.app.commander\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\nimport \"common/protoext/extensions.proto\";\n\n// Config is the settings for Commander.\nmessage Config {\n  // Tag of the outbound handler that handles grpc connections.\n  string tag = 1;\n  // Services that supported by this server. All services must implement Service\n  // interface.\n  repeated google.protobuf.Any service = 2;\n}\n\n// ReflectionConfig is the placeholder config for ReflectionService.\nmessage ReflectionConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"reflection\";\n}\n\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"commander\";\n\n  string tag = 1;\n  repeated string name = 2;\n}"
  },
  {
    "path": "app/commander/errors.generated.go",
    "content": "package commander\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/commander/outbound.go",
    "content": "package commander\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\nfunc NewOutboundListener() *OutboundListener {\n\treturn &OutboundListener{\n\t\tbuffer: make(chan net.Conn, 4),\n\t\tdone:   done.New(),\n\t}\n}\n\n// OutboundListener is a net.Listener for listening gRPC connections.\ntype OutboundListener struct {\n\tbuffer chan net.Conn\n\tdone   *done.Instance\n}\n\nfunc (l *OutboundListener) add(conn net.Conn) {\n\tselect {\n\tcase l.buffer <- conn:\n\tcase <-l.done.Wait():\n\t\tconn.Close()\n\tdefault:\n\t\tconn.Close()\n\t}\n}\n\n// Accept implements net.Listener.\nfunc (l *OutboundListener) Accept() (net.Conn, error) {\n\tselect {\n\tcase <-l.done.Wait():\n\t\treturn nil, newError(\"listen closed\")\n\tcase c := <-l.buffer:\n\t\treturn c, nil\n\t}\n}\n\n// Close implement net.Listener.\nfunc (l *OutboundListener) Close() error {\n\tcommon.Must(l.done.Close())\nL:\n\tfor {\n\t\tselect {\n\t\tcase c := <-l.buffer:\n\t\t\tc.Close()\n\t\tdefault:\n\t\t\tbreak L\n\t\t}\n\t}\n\treturn nil\n}\n\n// Addr implements net.Listener.\nfunc (l *OutboundListener) Addr() net.Addr {\n\treturn &net.TCPAddr{\n\t\tIP:   net.IP{0, 0, 0, 0},\n\t\tPort: 0,\n\t}\n}\n\nfunc NewOutbound(tag string, listener *OutboundListener) *Outbound {\n\treturn &Outbound{\n\t\ttag:      tag,\n\t\tlistener: listener,\n\t}\n}\n\n// Outbound is a outbound.Handler that handles gRPC connections.\ntype Outbound struct {\n\ttag      string\n\tlistener *OutboundListener\n\taccess   sync.RWMutex\n\tclosed   bool\n}\n\n// Dispatch implements outbound.Handler.\nfunc (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {\n\tco.access.RLock()\n\n\tif co.closed {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\tco.access.RUnlock()\n\t\treturn\n\t}\n\n\tcloseSignal := done.New()\n\tc := net.NewConnection(net.ConnectionInputMulti(link.Writer), net.ConnectionOutputMulti(link.Reader), net.ConnectionOnClose(closeSignal))\n\tco.listener.add(c)\n\tco.access.RUnlock()\n\t<-closeSignal.Wait()\n}\n\n// Tag implements outbound.Handler.\nfunc (co *Outbound) Tag() string {\n\treturn co.tag\n}\n\n// Start implements common.Runnable.\nfunc (co *Outbound) Start() error {\n\tco.access.Lock()\n\tco.closed = false\n\tco.access.Unlock()\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (co *Outbound) Close() error {\n\tco.access.Lock()\n\tdefer co.access.Unlock()\n\n\tco.closed = true\n\treturn co.listener.Close()\n}\n"
  },
  {
    "path": "app/commander/service.go",
    "content": "package commander\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/reflection\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n// Service is a Commander service.\ntype Service interface {\n\t// Register registers the service itself to a gRPC server.\n\tRegister(*grpc.Server)\n}\n\ntype reflectionService struct{}\n\nfunc (r reflectionService) Register(s *grpc.Server) {\n\treflection.Register(s)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ReflectionConfig)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\treturn reflectionService{}, nil\n\t}))\n}\n"
  },
  {
    "path": "app/commander/webcommander/config.pb.go",
    "content": "package webcommander\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tWebRoot       []byte                 `protobuf:\"bytes,2,opt,name=web_root,json=webRoot,proto3\" json:\"web_root,omitempty\"`\n\tWebRootFile   string                 `protobuf:\"bytes,96002,opt,name=web_root_file,json=webRootFile,proto3\" json:\"web_root_file,omitempty\"`\n\tApiMountpoint string                 `protobuf:\"bytes,3,opt,name=api_mountpoint,json=apiMountpoint,proto3\" json:\"api_mountpoint,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_commander_webcommander_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_commander_webcommander_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_commander_webcommander_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetWebRoot() []byte {\n\tif x != nil {\n\t\treturn x.WebRoot\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetWebRootFile() string {\n\tif x != nil {\n\t\treturn x.WebRootFile\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetApiMountpoint() string {\n\tif x != nil {\n\t\treturn x.ApiMountpoint\n\t}\n\treturn \"\"\n}\n\nvar File_app_commander_webcommander_config_proto protoreflect.FileDescriptor\n\nconst file_app_commander_webcommander_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"'app/commander/webcommander/config.proto\\x12%v2ray.core.app.commander.webcommander\\x1a common/protoext/extensions.proto\\\"\\xaf\\x01\\n\" +\n\t\"\\x06Config\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12\\x19\\n\" +\n\t\"\\bweb_root\\x18\\x02 \\x01(\\fR\\awebRoot\\x124\\n\" +\n\t\"\\rweb_root_file\\x18\\x82\\xee\\x05 \\x01(\\tB\\x0e\\x82\\xb5\\x18\\n\" +\n\t\"\\\"\\bweb_rootR\\vwebRootFile\\x12%\\n\" +\n\t\"\\x0eapi_mountpoint\\x18\\x03 \\x01(\\tR\\rapiMountpoint:\\x1b\\x82\\xb5\\x18\\x17\\n\" +\n\t\"\\aservice\\x12\\fwebcommanderB\\x90\\x01\\n\" +\n\t\")com.v2ray.core.app.commander.webcommanderP\\x01Z9github.com/v2fly/v2ray-core/v5/app/commander/webcommander\\xaa\\x02%V2Ray.Core.App.Commander.WebCommanderb\\x06proto3\"\n\nvar (\n\tfile_app_commander_webcommander_config_proto_rawDescOnce sync.Once\n\tfile_app_commander_webcommander_config_proto_rawDescData []byte\n)\n\nfunc file_app_commander_webcommander_config_proto_rawDescGZIP() []byte {\n\tfile_app_commander_webcommander_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_commander_webcommander_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_commander_webcommander_config_proto_rawDesc), len(file_app_commander_webcommander_config_proto_rawDesc)))\n\t})\n\treturn file_app_commander_webcommander_config_proto_rawDescData\n}\n\nvar file_app_commander_webcommander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_commander_webcommander_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.app.commander.webcommander.Config\n}\nvar file_app_commander_webcommander_config_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_app_commander_webcommander_config_proto_init() }\nfunc file_app_commander_webcommander_config_proto_init() {\n\tif File_app_commander_webcommander_config_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: unsafe.Slice(unsafe.StringData(file_app_commander_webcommander_config_proto_rawDesc), len(file_app_commander_webcommander_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_commander_webcommander_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_commander_webcommander_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_commander_webcommander_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_commander_webcommander_config_proto = out.File\n\tfile_app_commander_webcommander_config_proto_goTypes = nil\n\tfile_app_commander_webcommander_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/commander/webcommander/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.commander.webcommander;\noption csharp_namespace = \"V2Ray.Core.App.Commander.WebCommander\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/commander/webcommander\";\noption java_package = \"com.v2ray.core.app.commander.webcommander\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"webcommander\";\n\n  string tag = 1;\n\n  bytes web_root = 2;\n  string web_root_file = 96002 [(v2ray.core.common.protoext.field_opt).convert_time_read_file_into = \"web_root\"];\n\n  string api_mountpoint = 3;\n}"
  },
  {
    "path": "app/commander/webcommander/errors.generated.go",
    "content": "package webcommander\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/commander/webcommander/webcommander.go",
    "content": "package webcommander\n\nimport (\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"context\"\n\t\"io/fs\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/improbable-eng/grpc-web/go/grpcweb\"\n\t\"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/commander\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc newWebCommander(ctx context.Context, config *Config) (*WebCommander, error) {\n\tif config == nil {\n\t\treturn nil, newError(\"config is nil\")\n\t}\n\tif config.Tag == \"\" {\n\t\treturn nil, newError(\"config.Tag is empty\")\n\t}\n\tvar webRootfs fs.FS\n\tif config.WebRoot != nil {\n\t\tzipReader, err := zip.NewReader(bytes.NewReader(config.WebRoot), int64(len(config.WebRoot)))\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create zip reader\").Base(err)\n\t\t}\n\t\twebRootfs = zipReader\n\t}\n\n\treturn &WebCommander{ctx: ctx, config: config, webRootfs: webRootfs}, nil\n}\n\ntype WebCommander struct {\n\tsync.Mutex\n\n\tctx context.Context\n\tohm outbound.Manager\n\tcm  commander.CommanderIfce\n\n\tserver      *http.Server\n\twrappedGrpc *grpcweb.WrappedGrpcServer\n\twebRootfs   fs.FS\n\n\tconfig *Config\n}\n\nfunc (w *WebCommander) ServeHTTP(writer http.ResponseWriter, request *http.Request) {\n\tapiPath := w.config.ApiMountpoint\n\tif strings.HasPrefix(request.URL.Path, apiPath) {\n\t\trequest.URL.Path = strings.TrimPrefix(request.URL.Path, apiPath)\n\t\tif w.wrappedGrpc.IsGrpcWebRequest(request) {\n\t\t\tw.wrappedGrpc.ServeHTTP(writer, request)\n\t\t\treturn\n\t\t}\n\t}\n\tif w.webRootfs != nil {\n\t\thttp.ServeFileFS(writer, request, w.webRootfs, request.URL.Path)\n\t\treturn\n\t}\n\twriter.WriteHeader(http.StatusNotFound)\n}\n\nfunc (w *WebCommander) asyncStart() {\n\tvar grpcServer *grpc.Server\n\tfor {\n\t\tgrpcServer = w.cm.ExtractGrpcServer()\n\t\tif grpcServer != nil {\n\t\t\tbreak\n\t\t}\n\t\ttime.Sleep(time.Second)\n\t}\n\n\tlistener := commander.NewOutboundListener()\n\n\twrappedGrpc := grpcweb.WrapServer(grpcServer)\n\tw.server = &http.Server{}\n\tw.wrappedGrpc = wrappedGrpc\n\tw.server.Handler = w\n\n\tgo func() {\n\t\terr := w.server.Serve(listener)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to serve HTTP\").Base(err).WriteToLog()\n\t\t}\n\t}()\n\n\tif err := w.ohm.RemoveHandler(context.Background(), w.config.Tag); err != nil {\n\t\tnewError(\"failed to remove existing handler\").WriteToLog()\n\t}\n\n\tif err := w.ohm.AddHandler(context.Background(), commander.NewOutbound(w.config.Tag, listener)); err != nil {\n\t\tnewError(\"failed to add handler\").Base(err).WriteToLog()\n\t}\n}\n\nfunc (w *WebCommander) Type() interface{} {\n\treturn (*WebCommander)(nil)\n}\n\nfunc (w *WebCommander) Start() error {\n\tif err := core.RequireFeatures(w.ctx, func(cm commander.CommanderIfce, om outbound.Manager) {\n\t\tw.Lock()\n\t\tdefer w.Unlock()\n\n\t\tw.cm = cm\n\t\tw.ohm = om\n\n\t\tgo w.asyncStart()\n\t}); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (w *WebCommander) Close() error {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif w.server != nil {\n\t\tif err := w.server.Close(); err != nil {\n\t\t\treturn newError(\"failed to close http server\").Base(err)\n\t\t}\n\n\t\tw.server = nil\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn newWebCommander(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/dispatcher/config.pb.go",
    "content": "package dispatcher\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 SessionConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SessionConfig) Reset() {\n\t*x = SessionConfig{}\n\tmi := &file_app_dispatcher_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SessionConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SessionConfig) ProtoMessage() {}\n\nfunc (x *SessionConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dispatcher_config_proto_msgTypes[0]\n\tif 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 SessionConfig.ProtoReflect.Descriptor instead.\nfunc (*SessionConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_dispatcher_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tSettings      *SessionConfig         `protobuf:\"bytes,1,opt,name=settings,proto3\" json:\"settings,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_dispatcher_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dispatcher_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_dispatcher_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetSettings() *SessionConfig {\n\tif x != nil {\n\t\treturn x.Settings\n\t}\n\treturn nil\n}\n\nvar File_app_dispatcher_config_proto protoreflect.FileDescriptor\n\nconst file_app_dispatcher_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1bapp/dispatcher/config.proto\\x12\\x19v2ray.core.app.dispatcher\\\"\\x15\\n\" +\n\t\"\\rSessionConfigJ\\x04\\b\\x01\\x10\\x02\\\"N\\n\" +\n\t\"\\x06Config\\x12D\\n\" +\n\t\"\\bsettings\\x18\\x01 \\x01(\\v2(.v2ray.core.app.dispatcher.SessionConfigR\\bsettingsBl\\n\" +\n\t\"\\x1dcom.v2ray.core.app.dispatcherP\\x01Z-github.com/v2fly/v2ray-core/v5/app/dispatcher\\xaa\\x02\\x19V2Ray.Core.App.Dispatcherb\\x06proto3\"\n\nvar (\n\tfile_app_dispatcher_config_proto_rawDescOnce sync.Once\n\tfile_app_dispatcher_config_proto_rawDescData []byte\n)\n\nfunc file_app_dispatcher_config_proto_rawDescGZIP() []byte {\n\tfile_app_dispatcher_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_dispatcher_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_dispatcher_config_proto_rawDesc), len(file_app_dispatcher_config_proto_rawDesc)))\n\t})\n\treturn file_app_dispatcher_config_proto_rawDescData\n}\n\nvar file_app_dispatcher_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_app_dispatcher_config_proto_goTypes = []any{\n\t(*SessionConfig)(nil), // 0: v2ray.core.app.dispatcher.SessionConfig\n\t(*Config)(nil),        // 1: v2ray.core.app.dispatcher.Config\n}\nvar file_app_dispatcher_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.dispatcher.Config.settings:type_name -> v2ray.core.app.dispatcher.SessionConfig\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_dispatcher_config_proto_init() }\nfunc file_app_dispatcher_config_proto_init() {\n\tif File_app_dispatcher_config_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: unsafe.Slice(unsafe.StringData(file_app_dispatcher_config_proto_rawDesc), len(file_app_dispatcher_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_dispatcher_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_dispatcher_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_dispatcher_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_dispatcher_config_proto = out.File\n\tfile_app_dispatcher_config_proto_goTypes = nil\n\tfile_app_dispatcher_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/dispatcher/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.dispatcher;\noption csharp_namespace = \"V2Ray.Core.App.Dispatcher\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/dispatcher\";\noption java_package = \"com.v2ray.core.app.dispatcher\";\noption java_multiple_files = true;\n\nmessage SessionConfig {\n  reserved 1;\n}\n\nmessage Config {\n  SessionConfig settings = 1;\n}\n"
  },
  {
    "path": "app/dispatcher/default.go",
    "content": "package dispatcher\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\trouting_session \"github.com/v2fly/v2ray-core/v5/features/routing/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nvar errSniffingTimeout = newError(\"timeout on sniffing\")\n\ntype cachedReader struct {\n\tsync.Mutex\n\treader *pipe.Reader\n\tcache  buf.MultiBuffer\n}\n\nfunc (r *cachedReader) Cache(b *buf.Buffer, deadline time.Duration) error {\n\tmb, err := r.reader.ReadMultiBufferTimeout(deadline)\n\tif err != nil {\n\t\treturn err\n\t}\n\tr.Lock()\n\tif !mb.IsEmpty() {\n\t\tr.cache, _ = buf.MergeMulti(r.cache, mb)\n\t}\n\tb.Clear()\n\trawBytes := b.Extend(b.Cap())\n\tn := r.cache.Copy(rawBytes)\n\tb.Resize(0, int32(n))\n\tr.Unlock()\n\treturn nil\n}\n\nfunc (r *cachedReader) readInternal() buf.MultiBuffer {\n\tr.Lock()\n\tdefer r.Unlock()\n\n\tif r.cache != nil && !r.cache.IsEmpty() {\n\t\tmb := r.cache\n\t\tr.cache = nil\n\t\treturn mb\n\t}\n\n\treturn nil\n}\n\nfunc (r *cachedReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tmb := r.readInternal()\n\tif mb != nil {\n\t\treturn mb, nil\n\t}\n\n\treturn r.reader.ReadMultiBuffer()\n}\n\nfunc (r *cachedReader) ReadMultiBufferTimeout(timeout time.Duration) (buf.MultiBuffer, error) {\n\tmb := r.readInternal()\n\tif mb != nil {\n\t\treturn mb, nil\n\t}\n\n\treturn r.reader.ReadMultiBufferTimeout(timeout)\n}\n\nfunc (r *cachedReader) Interrupt() {\n\tr.Lock()\n\tif r.cache != nil {\n\t\tr.cache = buf.ReleaseMulti(r.cache)\n\t}\n\tr.Unlock()\n\tr.reader.Interrupt()\n}\n\n// DefaultDispatcher is a default implementation of Dispatcher.\ntype DefaultDispatcher struct {\n\tohm    outbound.Manager\n\trouter routing.Router\n\tpolicy policy.Manager\n\tstats  stats.Manager\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\td := new(DefaultDispatcher)\n\t\tif err := core.RequireFeatures(ctx, func(om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager) error {\n\t\t\treturn d.Init(config.(*Config), om, router, pm, sm)\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn d, nil\n\t}))\n}\n\n// Init initializes DefaultDispatcher.\nfunc (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager) error {\n\td.ohm = om\n\td.router = router\n\td.policy = pm\n\td.stats = sm\n\treturn nil\n}\n\n// Type implements common.HasType.\nfunc (*DefaultDispatcher) Type() interface{} {\n\treturn routing.DispatcherType()\n}\n\n// Start implements common.Runnable.\nfunc (*DefaultDispatcher) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (*DefaultDispatcher) Close() error { return nil }\n\nfunc (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *transport.Link) {\n\topt := pipe.OptionsFromContext(ctx)\n\tuplinkReader, uplinkWriter := pipe.New(opt...)\n\tdownlinkReader, downlinkWriter := pipe.New(opt...)\n\n\tinboundLink := &transport.Link{\n\t\tReader: downlinkReader,\n\t\tWriter: uplinkWriter,\n\t}\n\n\toutboundLink := &transport.Link{\n\t\tReader: uplinkReader,\n\t\tWriter: downlinkWriter,\n\t}\n\n\tsessionInbound := session.InboundFromContext(ctx)\n\tvar user *protocol.MemoryUser\n\tif sessionInbound != nil {\n\t\tuser = sessionInbound.User\n\t}\n\n\tif user != nil && len(user.Email) > 0 {\n\t\tp := d.policy.ForLevel(user.Level)\n\t\tif p.Stats.UserUplink {\n\t\t\tname := \"user>>>\" + user.Email + \">>>traffic>>>uplink\"\n\t\t\tif c, _ := stats.GetOrRegisterCounter(d.stats, name); c != nil {\n\t\t\t\tinboundLink.Writer = &SizeStatWriter{\n\t\t\t\t\tCounter: c,\n\t\t\t\t\tWriter:  inboundLink.Writer,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif p.Stats.UserDownlink {\n\t\t\tname := \"user>>>\" + user.Email + \">>>traffic>>>downlink\"\n\t\t\tif c, _ := stats.GetOrRegisterCounter(d.stats, name); c != nil {\n\t\t\t\toutboundLink.Writer = &SizeStatWriter{\n\t\t\t\t\tCounter: c,\n\t\t\t\t\tWriter:  outboundLink.Writer,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn inboundLink, outboundLink\n}\n\nfunc shouldOverride(result SniffResult, domainOverride []string) bool {\n\tif result.Domain() == \"\" {\n\t\treturn false\n\t}\n\tprotocolString := result.Protocol()\n\tif resComp, ok := result.(SnifferResultComposite); ok {\n\t\tprotocolString = resComp.ProtocolForDomainResult()\n\t}\n\tfor _, p := range domainOverride {\n\t\tif strings.HasPrefix(protocolString, p) || strings.HasSuffix(protocolString, p) {\n\t\t\treturn true\n\t\t}\n\t\tif resultSubset, ok := result.(SnifferIsProtoSubsetOf); ok {\n\t\t\tif resultSubset.IsProtoSubsetOf(p) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// Dispatch implements routing.Dispatcher.\nfunc (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destination) (*transport.Link, error) {\n\tif !destination.IsValid() {\n\t\tpanic(\"Dispatcher: Invalid destination.\")\n\t}\n\tob := &session.Outbound{\n\t\tTarget: destination,\n\t}\n\tctx = session.ContextWithOutbound(ctx, ob)\n\n\tinbound, outbound := d.getLink(ctx)\n\tcontent := session.ContentFromContext(ctx)\n\tif content == nil {\n\t\tcontent = new(session.Content)\n\t\tctx = session.ContextWithContent(ctx, content)\n\t}\n\tsniffingRequest := content.SniffingRequest\n\tif !sniffingRequest.Enabled {\n\t\tgo d.routedDispatch(ctx, outbound, destination)\n\t} else {\n\t\tgo func() {\n\t\t\tcReader := &cachedReader{\n\t\t\t\treader: outbound.Reader.(*pipe.Reader),\n\t\t\t}\n\t\t\toutbound.Reader = cReader\n\t\t\tresult, err := sniffer(ctx, cReader, sniffingRequest.MetadataOnly, destination.Network)\n\t\t\tif err == nil {\n\t\t\t\tcontent.Protocol = result.Protocol()\n\t\t\t}\n\t\t\tif err == nil && shouldOverride(result, sniffingRequest.OverrideDestinationForProtocol) {\n\t\t\t\tif domain, err := strmatcher.ToDomain(result.Domain()); err == nil {\n\t\t\t\t\tnewError(\"sniffed domain: \", domain, \" for \", destination).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t\tdestination.Address = net.ParseAddress(domain)\n\t\t\t\t\tob.Target = destination\n\t\t\t\t}\n\t\t\t}\n\t\t\td.routedDispatch(ctx, outbound, destination)\n\t\t}()\n\t}\n\n\treturn inbound, nil\n}\n\nfunc sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, network net.Network) (SniffResult, error) {\n\tpayload := buf.NewWithSize(32767)\n\n\tdefer payload.Release()\n\n\tsniffer := NewSniffer(ctx)\n\n\tmetaresult, metadataErr := sniffer.SniffMetadata(ctx)\n\n\tif metadataOnly {\n\t\treturn metaresult, metadataErr\n\t}\n\n\tcontentResult, contentErr := func() (SniffResult, error) {\n\t\tcacheDeadline := 200 * time.Millisecond\n\t\ttotalAttempt := 0\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn nil, ctx.Err()\n\t\t\tdefault:\n\t\t\t\tcachingStartingTimeStamp := time.Now()\n\t\t\t\tcacheErr := cReader.Cache(payload, cacheDeadline)\n\t\t\t\tcachingTimeElapsed := time.Since(cachingStartingTimeStamp)\n\t\t\t\tcacheDeadline -= cachingTimeElapsed\n\n\t\t\t\tif !payload.IsEmpty() {\n\t\t\t\t\tresult, err := sniffer.Sniff(ctx, payload.Bytes(), network)\n\t\t\t\t\tswitch err {\n\t\t\t\t\tcase common.ErrNoClue: // No Clue: protocol not matches, and sniffer cannot determine whether there will be a match or not\n\t\t\t\t\t\ttotalAttempt++\n\t\t\t\t\tcase protocol.ErrProtoNeedMoreData: // Protocol Need More Data: protocol matches, but need more data to complete sniffing\n\t\t\t\t\t\tif cacheErr != nil { // Cache error (e.g. timeout) counts for failed attempt\n\t\t\t\t\t\t\ttotalAttempt++\n\t\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn result, err\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif totalAttempt >= 2 || cacheDeadline <= 0 {\n\t\t\t\t\treturn nil, errSniffingTimeout\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\tif contentErr != nil && metadataErr == nil {\n\t\treturn metaresult, nil\n\t}\n\tif contentErr == nil && metadataErr == nil {\n\t\treturn CompositeResult(metaresult, contentResult), nil\n\t}\n\treturn contentResult, contentErr\n}\n\nfunc (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {\n\tvar handler outbound.Handler\n\n\tif forcedOutboundTag := session.GetForcedOutboundTagFromContext(ctx); forcedOutboundTag != \"\" {\n\t\tctx = session.SetForcedOutboundTagToContext(ctx, \"\")\n\t\tif h := d.ohm.GetHandler(forcedOutboundTag); h != nil {\n\t\t\tnewError(\"taking platform initialized detour [\", forcedOutboundTag, \"] for [\", destination, \"]\").WriteToLog(session.ExportIDToError(ctx))\n\t\t\thandler = h\n\t\t} else {\n\t\t\tnewError(\"non existing tag for platform initialized detour: \", forcedOutboundTag).AtError().WriteToLog(session.ExportIDToError(ctx))\n\t\t\tcommon.Close(link.Writer)\n\t\t\tcommon.Interrupt(link.Reader)\n\t\t\treturn\n\t\t}\n\t} else if d.router != nil {\n\t\tif route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {\n\t\t\ttag := route.GetOutboundTag()\n\t\t\tif h := d.ohm.GetHandler(tag); h != nil {\n\t\t\t\tnewError(\"taking detour [\", tag, \"] for [\", destination, \"]\").WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\thandler = h\n\t\t\t} else {\n\t\t\t\tnewError(\"non existing tag: \", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t}\n\t\t} else {\n\t\t\tnewError(\"default route for \", destination).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t}\n\n\tif handler == nil {\n\t\thandler = d.ohm.GetDefaultHandler()\n\t}\n\n\tif handler == nil {\n\t\tnewError(\"default outbound handler not exist\").WriteToLog(session.ExportIDToError(ctx))\n\t\tcommon.Close(link.Writer)\n\t\tcommon.Interrupt(link.Reader)\n\t\treturn\n\t}\n\n\tif accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil {\n\t\tif tag := handler.Tag(); tag != \"\" {\n\t\t\taccessMessage.Detour = tag\n\t\t\tif d.policy.ForSystem().OverrideAccessLogDest {\n\t\t\t\taccessMessage.To = destination\n\t\t\t}\n\t\t}\n\t\tlog.Record(accessMessage)\n\t}\n\n\thandler.Dispatch(ctx, link)\n}\n"
  },
  {
    "path": "app/dispatcher/dispatcher.go",
    "content": "package dispatcher\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/dispatcher/errors.generated.go",
    "content": "package dispatcher\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/dispatcher/fakednssniffer.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dispatcher\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\n// newFakeDNSSniffer Creates a Fake DNS metadata sniffer\nfunc newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error) {\n\tvar fakeDNSEngine dns.FakeDNSEngine\n\t{\n\t\tfakeDNSEngineFeat := core.MustFromContext(ctx).GetFeature((*dns.FakeDNSEngine)(nil))\n\t\tif fakeDNSEngineFeat != nil {\n\t\t\tfakeDNSEngine = fakeDNSEngineFeat.(dns.FakeDNSEngine)\n\t\t}\n\t}\n\n\tif fakeDNSEngine == nil {\n\t\terrNotInit := newError(\"FakeDNSEngine is not initialized, but such a sniffer is used\").AtError()\n\t\treturn protocolSnifferWithMetadata{}, errNotInit\n\t}\n\treturn protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {\n\t\tTarget := session.OutboundFromContext(ctx).Target\n\t\tif Target.Network == net.Network_TCP || Target.Network == net.Network_UDP {\n\t\t\tdomainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(Target.Address)\n\t\t\tif domainFromFakeDNS != \"\" {\n\t\t\t\tnewError(\"fake dns got domain: \", domainFromFakeDNS, \" for ip: \", Target.Address.String()).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil\n\t\t\t}\n\t\t}\n\n\t\tif ipAddressInRangeValueI := ctx.Value(ipAddressInRange); ipAddressInRangeValueI != nil {\n\t\t\tipAddressInRangeValue := ipAddressInRangeValueI.(*ipAddressInRangeOpt)\n\t\t\tif fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {\n\t\t\t\tinPool := fkr0.IsIPInIPPool(Target.Address)\n\t\t\t\tipAddressInRangeValue.addressInRange = &inPool\n\t\t\t}\n\t\t}\n\n\t\treturn nil, common.ErrNoClue\n\t}, metadataSniffer: true}, nil\n}\n\ntype fakeDNSSniffResult struct {\n\tdomainName string\n}\n\nfunc (fakeDNSSniffResult) Protocol() string {\n\treturn \"fakedns\"\n}\n\nfunc (f fakeDNSSniffResult) Domain() string {\n\treturn f.domainName\n}\n\ntype fakeDNSExtraOpts int\n\nconst ipAddressInRange fakeDNSExtraOpts = 1\n\ntype ipAddressInRangeOpt struct {\n\taddressInRange *bool\n}\n\ntype DNSThenOthersSniffResult struct {\n\tdomainName           string\n\tprotocolOriginalName string\n}\n\nfunc (f DNSThenOthersSniffResult) IsProtoSubsetOf(protocolName string) bool {\n\treturn strings.HasPrefix(protocolName, f.protocolOriginalName)\n}\n\nfunc (DNSThenOthersSniffResult) Protocol() string {\n\treturn \"fakedns+others\"\n}\n\nfunc (f DNSThenOthersSniffResult) Domain() string {\n\treturn f.domainName\n}\n\nfunc newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWithMetadata, others []protocolSnifferWithMetadata) (protocolSnifferWithMetadata, error) { // nolint: unparam\n\t// ctx may be used in the future\n\t_ = ctx\n\treturn protocolSnifferWithMetadata{\n\t\tprotocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {\n\t\t\tipAddressInRangeValue := &ipAddressInRangeOpt{}\n\t\t\tctx = context.WithValue(ctx, ipAddressInRange, ipAddressInRangeValue)\n\t\t\tresult, err := fakeDNSSniffer.protocolSniffer(ctx, bytes)\n\t\t\tif err == nil {\n\t\t\t\treturn result, nil\n\t\t\t}\n\t\t\tif ipAddressInRangeValue.addressInRange != nil {\n\t\t\t\tif *ipAddressInRangeValue.addressInRange {\n\t\t\t\t\tfor _, v := range others {\n\t\t\t\t\t\tif v.metadataSniffer || bytes != nil {\n\t\t\t\t\t\t\tif result, err := v.protocolSniffer(ctx, bytes); err == nil {\n\t\t\t\t\t\t\t\treturn DNSThenOthersSniffResult{domainName: result.Domain(), protocolOriginalName: result.Protocol()}, 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\treturn nil, common.ErrNoClue\n\t\t\t\t}\n\t\t\t\tnewError(\"ip address not in fake dns range, return as is\").AtDebug().WriteToLog()\n\t\t\t\treturn nil, common.ErrNoClue\n\t\t\t}\n\t\t\tnewError(\"fake dns sniffer did not set address in range option, assume false.\").AtWarning().WriteToLog()\n\t\t\treturn nil, common.ErrNoClue\n\t\t},\n\t\tmetadataSniffer: false,\n\t}, nil\n}\n"
  },
  {
    "path": "app/dispatcher/sniffer.go",
    "content": "package dispatcher\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/bittorrent\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/quic\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls\"\n)\n\ntype SniffResult interface {\n\tProtocol() string\n\tDomain() string\n}\n\ntype protocolSniffer func(context.Context, []byte) (SniffResult, error)\n\ntype protocolSnifferWithMetadata struct {\n\tprotocolSniffer protocolSniffer\n\t// A Metadata sniffer will be invoked on connection establishment only, with nil body,\n\t// for both TCP and UDP connections\n\t// It will not be shown as a traffic type for routing unless there is no other successful sniffing.\n\tmetadataSniffer bool\n\tnetwork         net.Network\n}\n\ntype Sniffer struct {\n\tsniffer []protocolSnifferWithMetadata\n}\n\nfunc NewSniffer(ctx context.Context) *Sniffer {\n\tret := &Sniffer{\n\t\tsniffer: []protocolSnifferWithMetadata{\n\t\t\t{func(c context.Context, b []byte) (SniffResult, error) { return http.SniffHTTP(b) }, false, net.Network_TCP},\n\t\t\t{func(c context.Context, b []byte) (SniffResult, error) { return tls.SniffTLS(b) }, false, net.Network_TCP},\n\t\t\t{func(c context.Context, b []byte) (SniffResult, error) { return quic.SniffQUIC(b) }, false, net.Network_UDP},\n\t\t\t{func(c context.Context, b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) }, false, net.Network_TCP},\n\t\t\t{func(c context.Context, b []byte) (SniffResult, error) { return bittorrent.SniffUTP(b) }, false, net.Network_UDP},\n\t\t},\n\t}\n\tif sniffer, err := newFakeDNSSniffer(ctx); err == nil {\n\t\tothers := ret.sniffer\n\t\tret.sniffer = append(ret.sniffer, sniffer)\n\t\tfakeDNSThenOthers, err := newFakeDNSThenOthers(ctx, sniffer, others)\n\t\tif err == nil {\n\t\t\tret.sniffer = append([]protocolSnifferWithMetadata{fakeDNSThenOthers}, ret.sniffer...)\n\t\t}\n\t}\n\treturn ret\n}\n\nvar errUnknownContent = newError(\"unknown content\")\n\nfunc (s *Sniffer) Sniff(c context.Context, payload []byte, network net.Network) (SniffResult, error) {\n\tvar pendingSniffer []protocolSnifferWithMetadata\n\tfor _, si := range s.sniffer {\n\t\tsniffer := si.protocolSniffer\n\t\tif si.metadataSniffer {\n\t\t\tcontinue\n\t\t}\n\t\tif si.network != network {\n\t\t\tcontinue\n\t\t}\n\t\tresult, err := sniffer(c, payload)\n\t\tif err == common.ErrNoClue {\n\t\t\tpendingSniffer = append(pendingSniffer, si)\n\t\t\tcontinue\n\t\t} else if err == protocol.ErrProtoNeedMoreData { // Sniffer protocol matched, but need more data to complete sniffing\n\t\t\ts.sniffer = []protocolSnifferWithMetadata{si}\n\t\t\treturn nil, protocol.ErrProtoNeedMoreData\n\t\t}\n\n\t\tif err == nil && result != nil {\n\t\t\treturn result, nil\n\t\t}\n\t}\n\n\tif len(pendingSniffer) > 0 {\n\t\ts.sniffer = pendingSniffer\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\treturn nil, errUnknownContent\n}\n\nfunc (s *Sniffer) SniffMetadata(c context.Context) (SniffResult, error) {\n\tvar pendingSniffer []protocolSnifferWithMetadata\n\tfor _, si := range s.sniffer {\n\t\ts := si.protocolSniffer\n\t\tif !si.metadataSniffer {\n\t\t\tpendingSniffer = append(pendingSniffer, si)\n\t\t\tcontinue\n\t\t}\n\t\tresult, err := s(c, nil)\n\t\tif err == common.ErrNoClue {\n\t\t\tpendingSniffer = append(pendingSniffer, si)\n\t\t\tcontinue\n\t\t}\n\n\t\tif err == nil && result != nil {\n\t\t\treturn result, nil\n\t\t}\n\t}\n\n\tif len(pendingSniffer) > 0 {\n\t\ts.sniffer = pendingSniffer\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\treturn nil, errUnknownContent\n}\n\nfunc CompositeResult(domainResult SniffResult, protocolResult SniffResult) SniffResult {\n\treturn &compositeResult{domainResult: domainResult, protocolResult: protocolResult}\n}\n\ntype compositeResult struct {\n\tdomainResult   SniffResult\n\tprotocolResult SniffResult\n}\n\nfunc (c compositeResult) Protocol() string {\n\treturn c.protocolResult.Protocol()\n}\n\nfunc (c compositeResult) Domain() string {\n\treturn c.domainResult.Domain()\n}\n\nfunc (c compositeResult) ProtocolForDomainResult() string {\n\treturn c.domainResult.Protocol()\n}\n\ntype SnifferResultComposite interface {\n\tProtocolForDomainResult() string\n}\n\ntype SnifferIsProtoSubsetOf interface {\n\tIsProtoSubsetOf(protocolName string) bool\n}\n"
  },
  {
    "path": "app/dispatcher/stats.go",
    "content": "package dispatcher\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\ntype SizeStatWriter struct {\n\tCounter stats.Counter\n\tWriter  buf.Writer\n}\n\nfunc (w *SizeStatWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tw.Counter.Add(int64(mb.Len()))\n\treturn w.Writer.WriteMultiBuffer(mb)\n}\n\nfunc (w *SizeStatWriter) Close() error {\n\treturn common.Close(w.Writer)\n}\n\nfunc (w *SizeStatWriter) Interrupt() {\n\tcommon.Interrupt(w.Writer)\n}\n"
  },
  {
    "path": "app/dispatcher/stats_test.go",
    "content": "package dispatcher_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\ntype TestCounter int64\n\nfunc (c *TestCounter) Value() int64 {\n\treturn int64(*c)\n}\n\nfunc (c *TestCounter) Add(v int64) int64 {\n\tx := int64(*c) + v\n\t*c = TestCounter(x)\n\treturn x\n}\n\nfunc (c *TestCounter) Set(v int64) int64 {\n\t*c = TestCounter(v)\n\treturn v\n}\n\nfunc TestStatsWriter(t *testing.T) {\n\tvar c TestCounter\n\twriter := &SizeStatWriter{\n\t\tCounter: &c,\n\t\tWriter:  buf.Discard,\n\t}\n\n\tmb := buf.MergeBytes(nil, []byte(\"abcd\"))\n\tcommon.Must(writer.WriteMultiBuffer(mb))\n\n\tmb = buf.MergeBytes(nil, []byte(\"efg\"))\n\tcommon.Must(writer.WriteMultiBuffer(mb))\n\n\tif c.Value() != 7 {\n\t\tt.Fatal(\"unexpected counter value. want 7, but got \", c.Value())\n\t}\n}\n"
  },
  {
    "path": "app/dns/config.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nvar typeMap = map[DomainMatchingType]strmatcher.Type{\n\tDomainMatchingType_Full:      strmatcher.Full,\n\tDomainMatchingType_Subdomain: strmatcher.Domain,\n\tDomainMatchingType_Keyword:   strmatcher.Substr,\n\tDomainMatchingType_Regex:     strmatcher.Regex,\n}\n\n// References:\n// https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml\n// https://unix.stackexchange.com/questions/92441/whats-the-difference-between-local-home-and-lan\nvar localTLDsAndDotlessDomains = []*NameServer_PriorityDomain{\n\t{Type: DomainMatchingType_Regex, Domain: \"^[^.]+$\"}, // This will only match domains without any dot\n\t{Type: DomainMatchingType_Subdomain, Domain: \"local\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"localdomain\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"localhost\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"lan\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"home.arpa\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"example\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"invalid\"},\n\t{Type: DomainMatchingType_Subdomain, Domain: \"test\"},\n}\n\nvar localTLDsAndDotlessDomainsRule = &NameServer_OriginalRule{\n\tRule: \"geosite:private\",\n\tSize: uint32(len(localTLDsAndDotlessDomains)),\n}\n\nfunc toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {\n\tstrMType, f := typeMap[t]\n\tif !f {\n\t\treturn nil, newError(\"unknown mapping type\", t).AtWarning()\n\t}\n\tmatcher, err := strMType.New(domain)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create str matcher\").Base(err)\n\t}\n\treturn matcher, nil\n}\n\nfunc toNetIP(addrs []net.Address) ([]net.IP, error) {\n\tips := make([]net.IP, 0, len(addrs))\n\tfor _, addr := range addrs {\n\t\tif addr.Family().IsIP() {\n\t\t\tips = append(ips, addr.IP())\n\t\t} else {\n\t\t\treturn nil, newError(\"Failed to convert address\", addr, \"to Net IP.\").AtWarning()\n\t\t}\n\t}\n\treturn ips, nil\n}\n\nfunc toIPOption(s QueryStrategy) dns.IPOption {\n\treturn dns.IPOption{\n\t\tIPv4Enable: s == QueryStrategy_USE_IP || s == QueryStrategy_USE_IP4,\n\t\tIPv6Enable: s == QueryStrategy_USE_IP || s == QueryStrategy_USE_IP6,\n\t\tFakeEnable: false,\n\t}\n}\n\nfunc toReqTypes(option dns.IPOption) []dnsmessage.Type {\n\tvar reqTypes []dnsmessage.Type\n\tif option.IPv4Enable {\n\t\treqTypes = append(reqTypes, dnsmessage.TypeA)\n\t}\n\tif option.IPv6Enable {\n\t\treqTypes = append(reqTypes, dnsmessage.TypeAAAA)\n\t}\n\treturn reqTypes\n}\n\nfunc generateRandomTag() string {\n\tid := uuid.New()\n\treturn \"v2ray.system.\" + id.String()\n}\n"
  },
  {
    "path": "app/dns/config.pb.go",
    "content": "package dns\n\nimport (\n\tfakedns \"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\troutercommon \"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 DomainMatchingType int32\n\nconst (\n\tDomainMatchingType_Full      DomainMatchingType = 0\n\tDomainMatchingType_Subdomain DomainMatchingType = 1\n\tDomainMatchingType_Keyword   DomainMatchingType = 2\n\tDomainMatchingType_Regex     DomainMatchingType = 3\n)\n\n// Enum value maps for DomainMatchingType.\nvar (\n\tDomainMatchingType_name = map[int32]string{\n\t\t0: \"Full\",\n\t\t1: \"Subdomain\",\n\t\t2: \"Keyword\",\n\t\t3: \"Regex\",\n\t}\n\tDomainMatchingType_value = map[string]int32{\n\t\t\"Full\":      0,\n\t\t\"Subdomain\": 1,\n\t\t\"Keyword\":   2,\n\t\t\"Regex\":     3,\n\t}\n)\n\nfunc (x DomainMatchingType) Enum() *DomainMatchingType {\n\tp := new(DomainMatchingType)\n\t*p = x\n\treturn p\n}\n\nfunc (x DomainMatchingType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (DomainMatchingType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_dns_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (DomainMatchingType) Type() protoreflect.EnumType {\n\treturn &file_app_dns_config_proto_enumTypes[0]\n}\n\nfunc (x DomainMatchingType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use DomainMatchingType.Descriptor instead.\nfunc (DomainMatchingType) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype QueryStrategy int32\n\nconst (\n\tQueryStrategy_USE_IP  QueryStrategy = 0\n\tQueryStrategy_USE_IP4 QueryStrategy = 1\n\tQueryStrategy_USE_IP6 QueryStrategy = 2\n)\n\n// Enum value maps for QueryStrategy.\nvar (\n\tQueryStrategy_name = map[int32]string{\n\t\t0: \"USE_IP\",\n\t\t1: \"USE_IP4\",\n\t\t2: \"USE_IP6\",\n\t}\n\tQueryStrategy_value = map[string]int32{\n\t\t\"USE_IP\":  0,\n\t\t\"USE_IP4\": 1,\n\t\t\"USE_IP6\": 2,\n\t}\n)\n\nfunc (x QueryStrategy) Enum() *QueryStrategy {\n\tp := new(QueryStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x QueryStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (QueryStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_dns_config_proto_enumTypes[1].Descriptor()\n}\n\nfunc (QueryStrategy) Type() protoreflect.EnumType {\n\treturn &file_app_dns_config_proto_enumTypes[1]\n}\n\nfunc (x QueryStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use QueryStrategy.Descriptor instead.\nfunc (QueryStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{1}\n}\n\ntype CacheStrategy int32\n\nconst (\n\tCacheStrategy_CacheEnabled  CacheStrategy = 0\n\tCacheStrategy_CacheDisabled CacheStrategy = 1\n)\n\n// Enum value maps for CacheStrategy.\nvar (\n\tCacheStrategy_name = map[int32]string{\n\t\t0: \"CacheEnabled\",\n\t\t1: \"CacheDisabled\",\n\t}\n\tCacheStrategy_value = map[string]int32{\n\t\t\"CacheEnabled\":  0,\n\t\t\"CacheDisabled\": 1,\n\t}\n)\n\nfunc (x CacheStrategy) Enum() *CacheStrategy {\n\tp := new(CacheStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x CacheStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (CacheStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_dns_config_proto_enumTypes[2].Descriptor()\n}\n\nfunc (CacheStrategy) Type() protoreflect.EnumType {\n\treturn &file_app_dns_config_proto_enumTypes[2]\n}\n\nfunc (x CacheStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use CacheStrategy.Descriptor instead.\nfunc (CacheStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{2}\n}\n\ntype FallbackStrategy int32\n\nconst (\n\tFallbackStrategy_Enabled            FallbackStrategy = 0\n\tFallbackStrategy_Disabled           FallbackStrategy = 1\n\tFallbackStrategy_DisabledIfAnyMatch FallbackStrategy = 2\n)\n\n// Enum value maps for FallbackStrategy.\nvar (\n\tFallbackStrategy_name = map[int32]string{\n\t\t0: \"Enabled\",\n\t\t1: \"Disabled\",\n\t\t2: \"DisabledIfAnyMatch\",\n\t}\n\tFallbackStrategy_value = map[string]int32{\n\t\t\"Enabled\":            0,\n\t\t\"Disabled\":           1,\n\t\t\"DisabledIfAnyMatch\": 2,\n\t}\n)\n\nfunc (x FallbackStrategy) Enum() *FallbackStrategy {\n\tp := new(FallbackStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x FallbackStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (FallbackStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_dns_config_proto_enumTypes[3].Descriptor()\n}\n\nfunc (FallbackStrategy) Type() protoreflect.EnumType {\n\treturn &file_app_dns_config_proto_enumTypes[3]\n}\n\nfunc (x FallbackStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use FallbackStrategy.Descriptor instead.\nfunc (FallbackStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{3}\n}\n\ntype NameServer struct {\n\tstate             protoimpl.MessageState       `protogen:\"open.v1\"`\n\tAddress           *net.Endpoint                `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tClientIp          []byte                       `protobuf:\"bytes,5,opt,name=client_ip,json=clientIp,proto3\" json:\"client_ip,omitempty\"`\n\tTag               string                       `protobuf:\"bytes,7,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tPrioritizedDomain []*NameServer_PriorityDomain `protobuf:\"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3\" json:\"prioritized_domain,omitempty\"`\n\tGeoip             []*routercommon.GeoIP        `protobuf:\"bytes,3,rep,name=geoip,proto3\" json:\"geoip,omitempty\"`\n\tOriginalRules     []*NameServer_OriginalRule   `protobuf:\"bytes,4,rep,name=original_rules,json=originalRules,proto3\" json:\"original_rules,omitempty\"`\n\tFakeDns           *fakedns.FakeDnsPoolMulti    `protobuf:\"bytes,11,opt,name=fake_dns,json=fakeDns,proto3\" json:\"fake_dns,omitempty\"`\n\t// Deprecated. Use fallback_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tSkipFallback     bool              `protobuf:\"varint,6,opt,name=skipFallback,proto3\" json:\"skipFallback,omitempty\"`\n\tQueryStrategy    *QueryStrategy    `protobuf:\"varint,8,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy,oneof\" json:\"query_strategy,omitempty\"`\n\tCacheStrategy    *CacheStrategy    `protobuf:\"varint,9,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy,oneof\" json:\"cache_strategy,omitempty\"`\n\tFallbackStrategy *FallbackStrategy `protobuf:\"varint,10,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy,oneof\" json:\"fallback_strategy,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *NameServer) Reset() {\n\t*x = NameServer{}\n\tmi := &file_app_dns_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *NameServer) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NameServer) ProtoMessage() {}\n\nfunc (x *NameServer) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[0]\n\tif 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 NameServer.ProtoReflect.Descriptor instead.\nfunc (*NameServer) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *NameServer) GetAddress() *net.Endpoint {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *NameServer) GetClientIp() []byte {\n\tif x != nil {\n\t\treturn x.ClientIp\n\t}\n\treturn nil\n}\n\nfunc (x *NameServer) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *NameServer) GetPrioritizedDomain() []*NameServer_PriorityDomain {\n\tif x != nil {\n\t\treturn x.PrioritizedDomain\n\t}\n\treturn nil\n}\n\nfunc (x *NameServer) GetGeoip() []*routercommon.GeoIP {\n\tif x != nil {\n\t\treturn x.Geoip\n\t}\n\treturn nil\n}\n\nfunc (x *NameServer) GetOriginalRules() []*NameServer_OriginalRule {\n\tif x != nil {\n\t\treturn x.OriginalRules\n\t}\n\treturn nil\n}\n\nfunc (x *NameServer) GetFakeDns() *fakedns.FakeDnsPoolMulti {\n\tif x != nil {\n\t\treturn x.FakeDns\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *NameServer) GetSkipFallback() bool {\n\tif x != nil {\n\t\treturn x.SkipFallback\n\t}\n\treturn false\n}\n\nfunc (x *NameServer) GetQueryStrategy() QueryStrategy {\n\tif x != nil && x.QueryStrategy != nil {\n\t\treturn *x.QueryStrategy\n\t}\n\treturn QueryStrategy_USE_IP\n}\n\nfunc (x *NameServer) GetCacheStrategy() CacheStrategy {\n\tif x != nil && x.CacheStrategy != nil {\n\t\treturn *x.CacheStrategy\n\t}\n\treturn CacheStrategy_CacheEnabled\n}\n\nfunc (x *NameServer) GetFallbackStrategy() FallbackStrategy {\n\tif x != nil && x.FallbackStrategy != nil {\n\t\treturn *x.FallbackStrategy\n\t}\n\treturn FallbackStrategy_Enabled\n}\n\ntype HostMapping struct {\n\tstate  protoimpl.MessageState `protogen:\"open.v1\"`\n\tType   DomainMatchingType     `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType\" json:\"type,omitempty\"`\n\tDomain string                 `protobuf:\"bytes,2,opt,name=domain,proto3\" json:\"domain,omitempty\"`\n\tIp     [][]byte               `protobuf:\"bytes,3,rep,name=ip,proto3\" json:\"ip,omitempty\"`\n\t// ProxiedDomain indicates the mapped domain has the same IP address on this\n\t// domain. V2Ray will use this domain for IP queries.\n\tProxiedDomain string `protobuf:\"bytes,4,opt,name=proxied_domain,json=proxiedDomain,proto3\" json:\"proxied_domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *HostMapping) Reset() {\n\t*x = HostMapping{}\n\tmi := &file_app_dns_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *HostMapping) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HostMapping) ProtoMessage() {}\n\nfunc (x *HostMapping) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[1]\n\tif 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 HostMapping.ProtoReflect.Descriptor instead.\nfunc (*HostMapping) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HostMapping) GetType() DomainMatchingType {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn DomainMatchingType_Full\n}\n\nfunc (x *HostMapping) GetDomain() string {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn \"\"\n}\n\nfunc (x *HostMapping) GetIp() [][]byte {\n\tif x != nil {\n\t\treturn x.Ip\n\t}\n\treturn nil\n}\n\nfunc (x *HostMapping) GetProxiedDomain() string {\n\tif x != nil {\n\t\treturn x.ProxiedDomain\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Nameservers used by this DNS. Only traditional UDP servers are support at\n\t// the moment. A special value 'localhost' as a domain address can be set to\n\t// use DNS on local system.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tNameServers []*net.Endpoint `protobuf:\"bytes,1,rep,name=NameServers,proto3\" json:\"NameServers,omitempty\"`\n\t// NameServer list used by this DNS client.\n\tNameServer []*NameServer `protobuf:\"bytes,5,rep,name=name_server,json=nameServer,proto3\" json:\"name_server,omitempty\"`\n\t// Static hosts. Domain to IP.\n\t// Deprecated. Use static_hosts.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tHosts map[string]*net.IPOrDomain `protobuf:\"bytes,2,rep,name=Hosts,proto3\" json:\"Hosts,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\t// Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes\n\t// (IPv6).\n\tClientIp []byte `protobuf:\"bytes,3,opt,name=client_ip,json=clientIp,proto3\" json:\"client_ip,omitempty\"`\n\t// Static domain-ip mapping in DNS server.\n\tStaticHosts []*HostMapping `protobuf:\"bytes,4,rep,name=static_hosts,json=staticHosts,proto3\" json:\"static_hosts,omitempty\"`\n\t// Global fakedns object.\n\tFakeDns *fakedns.FakeDnsPoolMulti `protobuf:\"bytes,16,opt,name=fake_dns,json=fakeDns,proto3\" json:\"fake_dns,omitempty\"`\n\t// Tag is the inbound tag of DNS client.\n\tTag string `protobuf:\"bytes,6,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\t// Domain matcher to use\n\tDomainMatcher string `protobuf:\"bytes,15,opt,name=domain_matcher,json=domainMatcher,proto3\" json:\"domain_matcher,omitempty\"`\n\t// DisableCache disables DNS cache\n\t// Deprecated. Use cache_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tDisableCache bool `protobuf:\"varint,8,opt,name=disableCache,proto3\" json:\"disableCache,omitempty\"`\n\t// Deprecated. Use fallback_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tDisableFallback bool `protobuf:\"varint,10,opt,name=disableFallback,proto3\" json:\"disableFallback,omitempty\"`\n\t// Deprecated. Use fallback_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tDisableFallbackIfMatch bool `protobuf:\"varint,11,opt,name=disableFallbackIfMatch,proto3\" json:\"disableFallbackIfMatch,omitempty\"`\n\t// Default query strategy (IPv4, IPv6, or both) for each name server.\n\tQueryStrategy QueryStrategy `protobuf:\"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy\" json:\"query_strategy,omitempty\"`\n\t// Default cache strategy for each name server.\n\tCacheStrategy CacheStrategy `protobuf:\"varint,12,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy\" json:\"cache_strategy,omitempty\"`\n\t// Default fallback strategy for each name server.\n\tFallbackStrategy FallbackStrategy `protobuf:\"varint,13,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy\" json:\"fallback_strategy,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_dns_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[2]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{2}\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *Config) GetNameServers() []*net.Endpoint {\n\tif x != nil {\n\t\treturn x.NameServers\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetNameServer() []*NameServer {\n\tif x != nil {\n\t\treturn x.NameServer\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *Config) GetHosts() map[string]*net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Hosts\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetClientIp() []byte {\n\tif x != nil {\n\t\treturn x.ClientIp\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetStaticHosts() []*HostMapping {\n\tif x != nil {\n\t\treturn x.StaticHosts\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetFakeDns() *fakedns.FakeDnsPoolMulti {\n\tif x != nil {\n\t\treturn x.FakeDns\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetDomainMatcher() string {\n\tif x != nil {\n\t\treturn x.DomainMatcher\n\t}\n\treturn \"\"\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *Config) GetDisableCache() bool {\n\tif x != nil {\n\t\treturn x.DisableCache\n\t}\n\treturn false\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *Config) GetDisableFallback() bool {\n\tif x != nil {\n\t\treturn x.DisableFallback\n\t}\n\treturn false\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *Config) GetDisableFallbackIfMatch() bool {\n\tif x != nil {\n\t\treturn x.DisableFallbackIfMatch\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetQueryStrategy() QueryStrategy {\n\tif x != nil {\n\t\treturn x.QueryStrategy\n\t}\n\treturn QueryStrategy_USE_IP\n}\n\nfunc (x *Config) GetCacheStrategy() CacheStrategy {\n\tif x != nil {\n\t\treturn x.CacheStrategy\n\t}\n\treturn CacheStrategy_CacheEnabled\n}\n\nfunc (x *Config) GetFallbackStrategy() FallbackStrategy {\n\tif x != nil {\n\t\treturn x.FallbackStrategy\n\t}\n\treturn FallbackStrategy_Enabled\n}\n\ntype SimplifiedConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// NameServer list used by this DNS client.\n\tNameServer []*SimplifiedNameServer `protobuf:\"bytes,5,rep,name=name_server,json=nameServer,proto3\" json:\"name_server,omitempty\"`\n\t// Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes\n\t// (IPv6).\n\tClientIp string `protobuf:\"bytes,3,opt,name=client_ip,json=clientIp,proto3\" json:\"client_ip,omitempty\"`\n\t// Static domain-ip mapping in DNS server.\n\tStaticHosts []*SimplifiedHostMapping `protobuf:\"bytes,4,rep,name=static_hosts,json=staticHosts,proto3\" json:\"static_hosts,omitempty\"`\n\t// Global fakedns object.\n\tFakeDns *fakedns.FakeDnsPoolMulti `protobuf:\"bytes,16,opt,name=fake_dns,json=fakeDns,proto3\" json:\"fake_dns,omitempty\"`\n\t// Tag is the inbound tag of DNS client.\n\tTag string `protobuf:\"bytes,6,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\t// Domain matcher to use\n\tDomainMatcher string `protobuf:\"bytes,15,opt,name=domain_matcher,json=domainMatcher,proto3\" json:\"domain_matcher,omitempty\"`\n\t// DisableCache disables DNS cache\n\t// Deprecated. Use cache_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tDisableCache bool `protobuf:\"varint,8,opt,name=disableCache,proto3\" json:\"disableCache,omitempty\"`\n\t// Deprecated. Use fallback_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tDisableFallback bool `protobuf:\"varint,10,opt,name=disableFallback,proto3\" json:\"disableFallback,omitempty\"`\n\t// Deprecated. Use fallback_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tDisableFallbackIfMatch bool `protobuf:\"varint,11,opt,name=disableFallbackIfMatch,proto3\" json:\"disableFallbackIfMatch,omitempty\"`\n\t// Default query strategy (IPv4, IPv6, or both) for each name server.\n\tQueryStrategy QueryStrategy `protobuf:\"varint,9,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy\" json:\"query_strategy,omitempty\"`\n\t// Default cache strategy for each name server.\n\tCacheStrategy CacheStrategy `protobuf:\"varint,12,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy\" json:\"cache_strategy,omitempty\"`\n\t// Default fallback strategy for each name server.\n\tFallbackStrategy FallbackStrategy `protobuf:\"varint,13,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy\" json:\"fallback_strategy,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_app_dns_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[3]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *SimplifiedConfig) GetNameServer() []*SimplifiedNameServer {\n\tif x != nil {\n\t\treturn x.NameServer\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetClientIp() string {\n\tif x != nil {\n\t\treturn x.ClientIp\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedConfig) GetStaticHosts() []*SimplifiedHostMapping {\n\tif x != nil {\n\t\treturn x.StaticHosts\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetFakeDns() *fakedns.FakeDnsPoolMulti {\n\tif x != nil {\n\t\treturn x.FakeDns\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedConfig) GetDomainMatcher() string {\n\tif x != nil {\n\t\treturn x.DomainMatcher\n\t}\n\treturn \"\"\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *SimplifiedConfig) GetDisableCache() bool {\n\tif x != nil {\n\t\treturn x.DisableCache\n\t}\n\treturn false\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *SimplifiedConfig) GetDisableFallback() bool {\n\tif x != nil {\n\t\treturn x.DisableFallback\n\t}\n\treturn false\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *SimplifiedConfig) GetDisableFallbackIfMatch() bool {\n\tif x != nil {\n\t\treturn x.DisableFallbackIfMatch\n\t}\n\treturn false\n}\n\nfunc (x *SimplifiedConfig) GetQueryStrategy() QueryStrategy {\n\tif x != nil {\n\t\treturn x.QueryStrategy\n\t}\n\treturn QueryStrategy_USE_IP\n}\n\nfunc (x *SimplifiedConfig) GetCacheStrategy() CacheStrategy {\n\tif x != nil {\n\t\treturn x.CacheStrategy\n\t}\n\treturn CacheStrategy_CacheEnabled\n}\n\nfunc (x *SimplifiedConfig) GetFallbackStrategy() FallbackStrategy {\n\tif x != nil {\n\t\treturn x.FallbackStrategy\n\t}\n\treturn FallbackStrategy_Enabled\n}\n\ntype SimplifiedHostMapping struct {\n\tstate  protoimpl.MessageState `protogen:\"open.v1\"`\n\tType   DomainMatchingType     `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType\" json:\"type,omitempty\"`\n\tDomain string                 `protobuf:\"bytes,2,opt,name=domain,proto3\" json:\"domain,omitempty\"`\n\tIp     []string               `protobuf:\"bytes,3,rep,name=ip,proto3\" json:\"ip,omitempty\"`\n\t// ProxiedDomain indicates the mapped domain has the same IP address on this\n\t// domain. V2Ray will use this domain for IP queries.\n\tProxiedDomain string `protobuf:\"bytes,4,opt,name=proxied_domain,json=proxiedDomain,proto3\" json:\"proxied_domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedHostMapping) Reset() {\n\t*x = SimplifiedHostMapping{}\n\tmi := &file_app_dns_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedHostMapping) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedHostMapping) ProtoMessage() {}\n\nfunc (x *SimplifiedHostMapping) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[4]\n\tif 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 SimplifiedHostMapping.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedHostMapping) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *SimplifiedHostMapping) GetType() DomainMatchingType {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn DomainMatchingType_Full\n}\n\nfunc (x *SimplifiedHostMapping) GetDomain() string {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedHostMapping) GetIp() []string {\n\tif x != nil {\n\t\treturn x.Ip\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedHostMapping) GetProxiedDomain() string {\n\tif x != nil {\n\t\treturn x.ProxiedDomain\n\t}\n\treturn \"\"\n}\n\ntype SimplifiedNameServer struct {\n\tstate             protoimpl.MessageState                 `protogen:\"open.v1\"`\n\tAddress           *net.Endpoint                          `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tClientIp          string                                 `protobuf:\"bytes,5,opt,name=client_ip,json=clientIp,proto3\" json:\"client_ip,omitempty\"`\n\tTag               string                                 `protobuf:\"bytes,7,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tPrioritizedDomain []*SimplifiedNameServer_PriorityDomain `protobuf:\"bytes,2,rep,name=prioritized_domain,json=prioritizedDomain,proto3\" json:\"prioritized_domain,omitempty\"`\n\tGeoip             []*routercommon.GeoIP                  `protobuf:\"bytes,3,rep,name=geoip,proto3\" json:\"geoip,omitempty\"`\n\tOriginalRules     []*SimplifiedNameServer_OriginalRule   `protobuf:\"bytes,4,rep,name=original_rules,json=originalRules,proto3\" json:\"original_rules,omitempty\"`\n\tFakeDns           *fakedns.FakeDnsPoolMulti              `protobuf:\"bytes,11,opt,name=fake_dns,json=fakeDns,proto3\" json:\"fake_dns,omitempty\"`\n\t// Deprecated. Use fallback_strategy.\n\t//\n\t// Deprecated: Marked as deprecated in app/dns/config.proto.\n\tSkipFallback     bool                    `protobuf:\"varint,6,opt,name=skipFallback,proto3\" json:\"skipFallback,omitempty\"`\n\tQueryStrategy    *QueryStrategy          `protobuf:\"varint,8,opt,name=query_strategy,json=queryStrategy,proto3,enum=v2ray.core.app.dns.QueryStrategy,oneof\" json:\"query_strategy,omitempty\"`\n\tCacheStrategy    *CacheStrategy          `protobuf:\"varint,9,opt,name=cache_strategy,json=cacheStrategy,proto3,enum=v2ray.core.app.dns.CacheStrategy,oneof\" json:\"cache_strategy,omitempty\"`\n\tFallbackStrategy *FallbackStrategy       `protobuf:\"varint,10,opt,name=fallback_strategy,json=fallbackStrategy,proto3,enum=v2ray.core.app.dns.FallbackStrategy,oneof\" json:\"fallback_strategy,omitempty\"`\n\tGeoDomain        []*routercommon.GeoSite `protobuf:\"bytes,68001,rep,name=geo_domain,json=geoDomain,proto3\" json:\"geo_domain,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedNameServer) Reset() {\n\t*x = SimplifiedNameServer{}\n\tmi := &file_app_dns_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedNameServer) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedNameServer) ProtoMessage() {}\n\nfunc (x *SimplifiedNameServer) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[5]\n\tif 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 SimplifiedNameServer.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedNameServer) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *SimplifiedNameServer) GetAddress() *net.Endpoint {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedNameServer) GetClientIp() string {\n\tif x != nil {\n\t\treturn x.ClientIp\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedNameServer) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedNameServer) GetPrioritizedDomain() []*SimplifiedNameServer_PriorityDomain {\n\tif x != nil {\n\t\treturn x.PrioritizedDomain\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedNameServer) GetGeoip() []*routercommon.GeoIP {\n\tif x != nil {\n\t\treturn x.Geoip\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedNameServer) GetOriginalRules() []*SimplifiedNameServer_OriginalRule {\n\tif x != nil {\n\t\treturn x.OriginalRules\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedNameServer) GetFakeDns() *fakedns.FakeDnsPoolMulti {\n\tif x != nil {\n\t\treturn x.FakeDns\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/dns/config.proto.\nfunc (x *SimplifiedNameServer) GetSkipFallback() bool {\n\tif x != nil {\n\t\treturn x.SkipFallback\n\t}\n\treturn false\n}\n\nfunc (x *SimplifiedNameServer) GetQueryStrategy() QueryStrategy {\n\tif x != nil && x.QueryStrategy != nil {\n\t\treturn *x.QueryStrategy\n\t}\n\treturn QueryStrategy_USE_IP\n}\n\nfunc (x *SimplifiedNameServer) GetCacheStrategy() CacheStrategy {\n\tif x != nil && x.CacheStrategy != nil {\n\t\treturn *x.CacheStrategy\n\t}\n\treturn CacheStrategy_CacheEnabled\n}\n\nfunc (x *SimplifiedNameServer) GetFallbackStrategy() FallbackStrategy {\n\tif x != nil && x.FallbackStrategy != nil {\n\t\treturn *x.FallbackStrategy\n\t}\n\treturn FallbackStrategy_Enabled\n}\n\nfunc (x *SimplifiedNameServer) GetGeoDomain() []*routercommon.GeoSite {\n\tif x != nil {\n\t\treturn x.GeoDomain\n\t}\n\treturn nil\n}\n\ntype NameServer_PriorityDomain struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tType          DomainMatchingType     `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType\" json:\"type,omitempty\"`\n\tDomain        string                 `protobuf:\"bytes,2,opt,name=domain,proto3\" json:\"domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *NameServer_PriorityDomain) Reset() {\n\t*x = NameServer_PriorityDomain{}\n\tmi := &file_app_dns_config_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *NameServer_PriorityDomain) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NameServer_PriorityDomain) ProtoMessage() {}\n\nfunc (x *NameServer_PriorityDomain) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[6]\n\tif 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 NameServer_PriorityDomain.ProtoReflect.Descriptor instead.\nfunc (*NameServer_PriorityDomain) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{0, 0}\n}\n\nfunc (x *NameServer_PriorityDomain) GetType() DomainMatchingType {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn DomainMatchingType_Full\n}\n\nfunc (x *NameServer_PriorityDomain) GetDomain() string {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn \"\"\n}\n\ntype NameServer_OriginalRule struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tRule          string                 `protobuf:\"bytes,1,opt,name=rule,proto3\" json:\"rule,omitempty\"`\n\tSize          uint32                 `protobuf:\"varint,2,opt,name=size,proto3\" json:\"size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *NameServer_OriginalRule) Reset() {\n\t*x = NameServer_OriginalRule{}\n\tmi := &file_app_dns_config_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *NameServer_OriginalRule) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NameServer_OriginalRule) ProtoMessage() {}\n\nfunc (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[7]\n\tif 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 NameServer_OriginalRule.ProtoReflect.Descriptor instead.\nfunc (*NameServer_OriginalRule) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{0, 1}\n}\n\nfunc (x *NameServer_OriginalRule) GetRule() string {\n\tif x != nil {\n\t\treturn x.Rule\n\t}\n\treturn \"\"\n}\n\nfunc (x *NameServer_OriginalRule) GetSize() uint32 {\n\tif x != nil {\n\t\treturn x.Size\n\t}\n\treturn 0\n}\n\ntype SimplifiedNameServer_PriorityDomain struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tType          DomainMatchingType     `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.dns.DomainMatchingType\" json:\"type,omitempty\"`\n\tDomain        string                 `protobuf:\"bytes,2,opt,name=domain,proto3\" json:\"domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedNameServer_PriorityDomain) Reset() {\n\t*x = SimplifiedNameServer_PriorityDomain{}\n\tmi := &file_app_dns_config_proto_msgTypes[9]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedNameServer_PriorityDomain) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedNameServer_PriorityDomain) ProtoMessage() {}\n\nfunc (x *SimplifiedNameServer_PriorityDomain) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[9]\n\tif 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 SimplifiedNameServer_PriorityDomain.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedNameServer_PriorityDomain) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{5, 0}\n}\n\nfunc (x *SimplifiedNameServer_PriorityDomain) GetType() DomainMatchingType {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn DomainMatchingType_Full\n}\n\nfunc (x *SimplifiedNameServer_PriorityDomain) GetDomain() string {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn \"\"\n}\n\ntype SimplifiedNameServer_OriginalRule struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tRule          string                 `protobuf:\"bytes,1,opt,name=rule,proto3\" json:\"rule,omitempty\"`\n\tSize          uint32                 `protobuf:\"varint,2,opt,name=size,proto3\" json:\"size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedNameServer_OriginalRule) Reset() {\n\t*x = SimplifiedNameServer_OriginalRule{}\n\tmi := &file_app_dns_config_proto_msgTypes[10]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedNameServer_OriginalRule) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedNameServer_OriginalRule) ProtoMessage() {}\n\nfunc (x *SimplifiedNameServer_OriginalRule) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_config_proto_msgTypes[10]\n\tif 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 SimplifiedNameServer_OriginalRule.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedNameServer_OriginalRule) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_config_proto_rawDescGZIP(), []int{5, 1}\n}\n\nfunc (x *SimplifiedNameServer_OriginalRule) GetRule() string {\n\tif x != nil {\n\t\treturn x.Rule\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedNameServer_OriginalRule) GetSize() uint32 {\n\tif x != nil {\n\t\treturn x.Size\n\t}\n\treturn 0\n}\n\nvar File_app_dns_config_proto protoreflect.FileDescriptor\n\nconst file_app_dns_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x14app/dns/config.proto\\x12\\x12v2ray.core.app.dns\\x1a\\x18common/net/address.proto\\x1a\\x1ccommon/net/destination.proto\\x1a$app/router/routercommon/common.proto\\x1a\\x1dapp/dns/fakedns/fakedns.proto\\x1a common/protoext/extensions.proto\\\"\\xaa\\a\\n\" +\n\t\"\\n\" +\n\t\"NameServer\\x129\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2\\x1f.v2ray.core.common.net.EndpointR\\aaddress\\x12\\x1b\\n\" +\n\t\"\\tclient_ip\\x18\\x05 \\x01(\\fR\\bclientIp\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\a \\x01(\\tR\\x03tag\\x12\\\\\\n\" +\n\t\"\\x12prioritized_domain\\x18\\x02 \\x03(\\v2-.v2ray.core.app.dns.NameServer.PriorityDomainR\\x11prioritizedDomain\\x12?\\n\" +\n\t\"\\x05geoip\\x18\\x03 \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\x05geoip\\x12R\\n\" +\n\t\"\\x0eoriginal_rules\\x18\\x04 \\x03(\\v2+.v2ray.core.app.dns.NameServer.OriginalRuleR\\roriginalRules\\x12G\\n\" +\n\t\"\\bfake_dns\\x18\\v \\x01(\\v2,.v2ray.core.app.dns.fakedns.FakeDnsPoolMultiR\\afakeDns\\x12&\\n\" +\n\t\"\\fskipFallback\\x18\\x06 \\x01(\\bB\\x02\\x18\\x01R\\fskipFallback\\x12M\\n\" +\n\t\"\\x0equery_strategy\\x18\\b \\x01(\\x0e2!.v2ray.core.app.dns.QueryStrategyH\\x00R\\rqueryStrategy\\x88\\x01\\x01\\x12M\\n\" +\n\t\"\\x0ecache_strategy\\x18\\t \\x01(\\x0e2!.v2ray.core.app.dns.CacheStrategyH\\x01R\\rcacheStrategy\\x88\\x01\\x01\\x12V\\n\" +\n\t\"\\x11fallback_strategy\\x18\\n\" +\n\t\" \\x01(\\x0e2$.v2ray.core.app.dns.FallbackStrategyH\\x02R\\x10fallbackStrategy\\x88\\x01\\x01\\x1ad\\n\" +\n\t\"\\x0ePriorityDomain\\x12:\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2&.v2ray.core.app.dns.DomainMatchingTypeR\\x04type\\x12\\x16\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tR\\x06domain\\x1a6\\n\" +\n\t\"\\fOriginalRule\\x12\\x12\\n\" +\n\t\"\\x04rule\\x18\\x01 \\x01(\\tR\\x04rule\\x12\\x12\\n\" +\n\t\"\\x04size\\x18\\x02 \\x01(\\rR\\x04sizeB\\x11\\n\" +\n\t\"\\x0f_query_strategyB\\x11\\n\" +\n\t\"\\x0f_cache_strategyB\\x14\\n\" +\n\t\"\\x12_fallback_strategy\\\"\\x98\\x01\\n\" +\n\t\"\\vHostMapping\\x12:\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2&.v2ray.core.app.dns.DomainMatchingTypeR\\x04type\\x12\\x16\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tR\\x06domain\\x12\\x0e\\n\" +\n\t\"\\x02ip\\x18\\x03 \\x03(\\fR\\x02ip\\x12%\\n\" +\n\t\"\\x0eproxied_domain\\x18\\x04 \\x01(\\tR\\rproxiedDomain\\\"\\x90\\a\\n\" +\n\t\"\\x06Config\\x12E\\n\" +\n\t\"\\vNameServers\\x18\\x01 \\x03(\\v2\\x1f.v2ray.core.common.net.EndpointB\\x02\\x18\\x01R\\vNameServers\\x12?\\n\" +\n\t\"\\vname_server\\x18\\x05 \\x03(\\v2\\x1e.v2ray.core.app.dns.NameServerR\\n\" +\n\t\"nameServer\\x12?\\n\" +\n\t\"\\x05Hosts\\x18\\x02 \\x03(\\v2%.v2ray.core.app.dns.Config.HostsEntryB\\x02\\x18\\x01R\\x05Hosts\\x12\\x1b\\n\" +\n\t\"\\tclient_ip\\x18\\x03 \\x01(\\fR\\bclientIp\\x12B\\n\" +\n\t\"\\fstatic_hosts\\x18\\x04 \\x03(\\v2\\x1f.v2ray.core.app.dns.HostMappingR\\vstaticHosts\\x12G\\n\" +\n\t\"\\bfake_dns\\x18\\x10 \\x01(\\v2,.v2ray.core.app.dns.fakedns.FakeDnsPoolMultiR\\afakeDns\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x06 \\x01(\\tR\\x03tag\\x12%\\n\" +\n\t\"\\x0edomain_matcher\\x18\\x0f \\x01(\\tR\\rdomainMatcher\\x12&\\n\" +\n\t\"\\fdisableCache\\x18\\b \\x01(\\bB\\x02\\x18\\x01R\\fdisableCache\\x12,\\n\" +\n\t\"\\x0fdisableFallback\\x18\\n\" +\n\t\" \\x01(\\bB\\x02\\x18\\x01R\\x0fdisableFallback\\x12:\\n\" +\n\t\"\\x16disableFallbackIfMatch\\x18\\v \\x01(\\bB\\x02\\x18\\x01R\\x16disableFallbackIfMatch\\x12H\\n\" +\n\t\"\\x0equery_strategy\\x18\\t \\x01(\\x0e2!.v2ray.core.app.dns.QueryStrategyR\\rqueryStrategy\\x12H\\n\" +\n\t\"\\x0ecache_strategy\\x18\\f \\x01(\\x0e2!.v2ray.core.app.dns.CacheStrategyR\\rcacheStrategy\\x12Q\\n\" +\n\t\"\\x11fallback_strategy\\x18\\r \\x01(\\x0e2$.v2ray.core.app.dns.FallbackStrategyR\\x10fallbackStrategy\\x1a[\\n\" +\n\t\"\\n\" +\n\t\"HostsEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x127\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\x05value:\\x028\\x01J\\x04\\b\\a\\x10\\b\\\"\\xe9\\x05\\n\" +\n\t\"\\x10SimplifiedConfig\\x12I\\n\" +\n\t\"\\vname_server\\x18\\x05 \\x03(\\v2(.v2ray.core.app.dns.SimplifiedNameServerR\\n\" +\n\t\"nameServer\\x12\\x1b\\n\" +\n\t\"\\tclient_ip\\x18\\x03 \\x01(\\tR\\bclientIp\\x12L\\n\" +\n\t\"\\fstatic_hosts\\x18\\x04 \\x03(\\v2).v2ray.core.app.dns.SimplifiedHostMappingR\\vstaticHosts\\x12G\\n\" +\n\t\"\\bfake_dns\\x18\\x10 \\x01(\\v2,.v2ray.core.app.dns.fakedns.FakeDnsPoolMultiR\\afakeDns\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x06 \\x01(\\tR\\x03tag\\x12%\\n\" +\n\t\"\\x0edomain_matcher\\x18\\x0f \\x01(\\tR\\rdomainMatcher\\x12&\\n\" +\n\t\"\\fdisableCache\\x18\\b \\x01(\\bB\\x02\\x18\\x01R\\fdisableCache\\x12,\\n\" +\n\t\"\\x0fdisableFallback\\x18\\n\" +\n\t\" \\x01(\\bB\\x02\\x18\\x01R\\x0fdisableFallback\\x12:\\n\" +\n\t\"\\x16disableFallbackIfMatch\\x18\\v \\x01(\\bB\\x02\\x18\\x01R\\x16disableFallbackIfMatch\\x12H\\n\" +\n\t\"\\x0equery_strategy\\x18\\t \\x01(\\x0e2!.v2ray.core.app.dns.QueryStrategyR\\rqueryStrategy\\x12H\\n\" +\n\t\"\\x0ecache_strategy\\x18\\f \\x01(\\x0e2!.v2ray.core.app.dns.CacheStrategyR\\rcacheStrategy\\x12Q\\n\" +\n\t\"\\x11fallback_strategy\\x18\\r \\x01(\\x0e2$.v2ray.core.app.dns.FallbackStrategyR\\x10fallbackStrategy:\\x12\\x82\\xb5\\x18\\x0e\\n\" +\n\t\"\\aservice\\x12\\x03dnsJ\\x04\\b\\x01\\x10\\x02J\\x04\\b\\x02\\x10\\x03J\\x04\\b\\a\\x10\\b\\\"\\xa2\\x01\\n\" +\n\t\"\\x15SimplifiedHostMapping\\x12:\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2&.v2ray.core.app.dns.DomainMatchingTypeR\\x04type\\x12\\x16\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tR\\x06domain\\x12\\x0e\\n\" +\n\t\"\\x02ip\\x18\\x03 \\x03(\\tR\\x02ip\\x12%\\n\" +\n\t\"\\x0eproxied_domain\\x18\\x04 \\x01(\\tR\\rproxiedDomain\\\"\\x96\\b\\n\" +\n\t\"\\x14SimplifiedNameServer\\x129\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2\\x1f.v2ray.core.common.net.EndpointR\\aaddress\\x12\\x1b\\n\" +\n\t\"\\tclient_ip\\x18\\x05 \\x01(\\tR\\bclientIp\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\a \\x01(\\tR\\x03tag\\x12f\\n\" +\n\t\"\\x12prioritized_domain\\x18\\x02 \\x03(\\v27.v2ray.core.app.dns.SimplifiedNameServer.PriorityDomainR\\x11prioritizedDomain\\x12?\\n\" +\n\t\"\\x05geoip\\x18\\x03 \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\x05geoip\\x12\\\\\\n\" +\n\t\"\\x0eoriginal_rules\\x18\\x04 \\x03(\\v25.v2ray.core.app.dns.SimplifiedNameServer.OriginalRuleR\\roriginalRules\\x12G\\n\" +\n\t\"\\bfake_dns\\x18\\v \\x01(\\v2,.v2ray.core.app.dns.fakedns.FakeDnsPoolMultiR\\afakeDns\\x12&\\n\" +\n\t\"\\fskipFallback\\x18\\x06 \\x01(\\bB\\x02\\x18\\x01R\\fskipFallback\\x12M\\n\" +\n\t\"\\x0equery_strategy\\x18\\b \\x01(\\x0e2!.v2ray.core.app.dns.QueryStrategyH\\x00R\\rqueryStrategy\\x88\\x01\\x01\\x12M\\n\" +\n\t\"\\x0ecache_strategy\\x18\\t \\x01(\\x0e2!.v2ray.core.app.dns.CacheStrategyH\\x01R\\rcacheStrategy\\x88\\x01\\x01\\x12V\\n\" +\n\t\"\\x11fallback_strategy\\x18\\n\" +\n\t\" \\x01(\\x0e2$.v2ray.core.app.dns.FallbackStrategyH\\x02R\\x10fallbackStrategy\\x88\\x01\\x01\\x12L\\n\" +\n\t\"\\n\" +\n\t\"geo_domain\\x18\\xa1\\x93\\x04 \\x03(\\v2+.v2ray.core.app.router.routercommon.GeoSiteR\\tgeoDomain\\x1ad\\n\" +\n\t\"\\x0ePriorityDomain\\x12:\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2&.v2ray.core.app.dns.DomainMatchingTypeR\\x04type\\x12\\x16\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tR\\x06domain\\x1a6\\n\" +\n\t\"\\fOriginalRule\\x12\\x12\\n\" +\n\t\"\\x04rule\\x18\\x01 \\x01(\\tR\\x04rule\\x12\\x12\\n\" +\n\t\"\\x04size\\x18\\x02 \\x01(\\rR\\x04sizeB\\x11\\n\" +\n\t\"\\x0f_query_strategyB\\x11\\n\" +\n\t\"\\x0f_cache_strategyB\\x14\\n\" +\n\t\"\\x12_fallback_strategy*E\\n\" +\n\t\"\\x12DomainMatchingType\\x12\\b\\n\" +\n\t\"\\x04Full\\x10\\x00\\x12\\r\\n\" +\n\t\"\\tSubdomain\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aKeyword\\x10\\x02\\x12\\t\\n\" +\n\t\"\\x05Regex\\x10\\x03*5\\n\" +\n\t\"\\rQueryStrategy\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06USE_IP\\x10\\x00\\x12\\v\\n\" +\n\t\"\\aUSE_IP4\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aUSE_IP6\\x10\\x02*4\\n\" +\n\t\"\\rCacheStrategy\\x12\\x10\\n\" +\n\t\"\\fCacheEnabled\\x10\\x00\\x12\\x11\\n\" +\n\t\"\\rCacheDisabled\\x10\\x01*E\\n\" +\n\t\"\\x10FallbackStrategy\\x12\\v\\n\" +\n\t\"\\aEnabled\\x10\\x00\\x12\\f\\n\" +\n\t\"\\bDisabled\\x10\\x01\\x12\\x16\\n\" +\n\t\"\\x12DisabledIfAnyMatch\\x10\\x02BW\\n\" +\n\t\"\\x16com.v2ray.core.app.dnsP\\x01Z&github.com/v2fly/v2ray-core/v5/app/dns\\xaa\\x02\\x12V2Ray.Core.App.Dnsb\\x06proto3\"\n\nvar (\n\tfile_app_dns_config_proto_rawDescOnce sync.Once\n\tfile_app_dns_config_proto_rawDescData []byte\n)\n\nfunc file_app_dns_config_proto_rawDescGZIP() []byte {\n\tfile_app_dns_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_dns_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_dns_config_proto_rawDesc), len(file_app_dns_config_proto_rawDesc)))\n\t})\n\treturn file_app_dns_config_proto_rawDescData\n}\n\nvar file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 4)\nvar file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 11)\nvar file_app_dns_config_proto_goTypes = []any{\n\t(DomainMatchingType)(0),                     // 0: v2ray.core.app.dns.DomainMatchingType\n\t(QueryStrategy)(0),                          // 1: v2ray.core.app.dns.QueryStrategy\n\t(CacheStrategy)(0),                          // 2: v2ray.core.app.dns.CacheStrategy\n\t(FallbackStrategy)(0),                       // 3: v2ray.core.app.dns.FallbackStrategy\n\t(*NameServer)(nil),                          // 4: v2ray.core.app.dns.NameServer\n\t(*HostMapping)(nil),                         // 5: v2ray.core.app.dns.HostMapping\n\t(*Config)(nil),                              // 6: v2ray.core.app.dns.Config\n\t(*SimplifiedConfig)(nil),                    // 7: v2ray.core.app.dns.SimplifiedConfig\n\t(*SimplifiedHostMapping)(nil),               // 8: v2ray.core.app.dns.SimplifiedHostMapping\n\t(*SimplifiedNameServer)(nil),                // 9: v2ray.core.app.dns.SimplifiedNameServer\n\t(*NameServer_PriorityDomain)(nil),           // 10: v2ray.core.app.dns.NameServer.PriorityDomain\n\t(*NameServer_OriginalRule)(nil),             // 11: v2ray.core.app.dns.NameServer.OriginalRule\n\tnil,                                         // 12: v2ray.core.app.dns.Config.HostsEntry\n\t(*SimplifiedNameServer_PriorityDomain)(nil), // 13: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain\n\t(*SimplifiedNameServer_OriginalRule)(nil),   // 14: v2ray.core.app.dns.SimplifiedNameServer.OriginalRule\n\t(*net.Endpoint)(nil),                        // 15: v2ray.core.common.net.Endpoint\n\t(*routercommon.GeoIP)(nil),                  // 16: v2ray.core.app.router.routercommon.GeoIP\n\t(*fakedns.FakeDnsPoolMulti)(nil),            // 17: v2ray.core.app.dns.fakedns.FakeDnsPoolMulti\n\t(*routercommon.GeoSite)(nil),                // 18: v2ray.core.app.router.routercommon.GeoSite\n\t(*net.IPOrDomain)(nil),                      // 19: v2ray.core.common.net.IPOrDomain\n}\nvar file_app_dns_config_proto_depIdxs = []int32{\n\t15, // 0: v2ray.core.app.dns.NameServer.address:type_name -> v2ray.core.common.net.Endpoint\n\t10, // 1: v2ray.core.app.dns.NameServer.prioritized_domain:type_name -> v2ray.core.app.dns.NameServer.PriorityDomain\n\t16, // 2: v2ray.core.app.dns.NameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t11, // 3: v2ray.core.app.dns.NameServer.original_rules:type_name -> v2ray.core.app.dns.NameServer.OriginalRule\n\t17, // 4: v2ray.core.app.dns.NameServer.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti\n\t1,  // 5: v2ray.core.app.dns.NameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy\n\t2,  // 6: v2ray.core.app.dns.NameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy\n\t3,  // 7: v2ray.core.app.dns.NameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy\n\t0,  // 8: v2ray.core.app.dns.HostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType\n\t15, // 9: v2ray.core.app.dns.Config.NameServers:type_name -> v2ray.core.common.net.Endpoint\n\t4,  // 10: v2ray.core.app.dns.Config.name_server:type_name -> v2ray.core.app.dns.NameServer\n\t12, // 11: v2ray.core.app.dns.Config.Hosts:type_name -> v2ray.core.app.dns.Config.HostsEntry\n\t5,  // 12: v2ray.core.app.dns.Config.static_hosts:type_name -> v2ray.core.app.dns.HostMapping\n\t17, // 13: v2ray.core.app.dns.Config.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti\n\t1,  // 14: v2ray.core.app.dns.Config.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy\n\t2,  // 15: v2ray.core.app.dns.Config.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy\n\t3,  // 16: v2ray.core.app.dns.Config.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy\n\t9,  // 17: v2ray.core.app.dns.SimplifiedConfig.name_server:type_name -> v2ray.core.app.dns.SimplifiedNameServer\n\t8,  // 18: v2ray.core.app.dns.SimplifiedConfig.static_hosts:type_name -> v2ray.core.app.dns.SimplifiedHostMapping\n\t17, // 19: v2ray.core.app.dns.SimplifiedConfig.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti\n\t1,  // 20: v2ray.core.app.dns.SimplifiedConfig.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy\n\t2,  // 21: v2ray.core.app.dns.SimplifiedConfig.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy\n\t3,  // 22: v2ray.core.app.dns.SimplifiedConfig.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy\n\t0,  // 23: v2ray.core.app.dns.SimplifiedHostMapping.type:type_name -> v2ray.core.app.dns.DomainMatchingType\n\t15, // 24: v2ray.core.app.dns.SimplifiedNameServer.address:type_name -> v2ray.core.common.net.Endpoint\n\t13, // 25: v2ray.core.app.dns.SimplifiedNameServer.prioritized_domain:type_name -> v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain\n\t16, // 26: v2ray.core.app.dns.SimplifiedNameServer.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t14, // 27: v2ray.core.app.dns.SimplifiedNameServer.original_rules:type_name -> v2ray.core.app.dns.SimplifiedNameServer.OriginalRule\n\t17, // 28: v2ray.core.app.dns.SimplifiedNameServer.fake_dns:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPoolMulti\n\t1,  // 29: v2ray.core.app.dns.SimplifiedNameServer.query_strategy:type_name -> v2ray.core.app.dns.QueryStrategy\n\t2,  // 30: v2ray.core.app.dns.SimplifiedNameServer.cache_strategy:type_name -> v2ray.core.app.dns.CacheStrategy\n\t3,  // 31: v2ray.core.app.dns.SimplifiedNameServer.fallback_strategy:type_name -> v2ray.core.app.dns.FallbackStrategy\n\t18, // 32: v2ray.core.app.dns.SimplifiedNameServer.geo_domain:type_name -> v2ray.core.app.router.routercommon.GeoSite\n\t0,  // 33: v2ray.core.app.dns.NameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType\n\t19, // 34: v2ray.core.app.dns.Config.HostsEntry.value:type_name -> v2ray.core.common.net.IPOrDomain\n\t0,  // 35: v2ray.core.app.dns.SimplifiedNameServer.PriorityDomain.type:type_name -> v2ray.core.app.dns.DomainMatchingType\n\t36, // [36:36] is the sub-list for method output_type\n\t36, // [36:36] is the sub-list for method input_type\n\t36, // [36:36] is the sub-list for extension type_name\n\t36, // [36:36] is the sub-list for extension extendee\n\t0,  // [0:36] is the sub-list for field type_name\n}\n\nfunc init() { file_app_dns_config_proto_init() }\nfunc file_app_dns_config_proto_init() {\n\tif File_app_dns_config_proto != nil {\n\t\treturn\n\t}\n\tfile_app_dns_config_proto_msgTypes[0].OneofWrappers = []any{}\n\tfile_app_dns_config_proto_msgTypes[5].OneofWrappers = []any{}\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: unsafe.Slice(unsafe.StringData(file_app_dns_config_proto_rawDesc), len(file_app_dns_config_proto_rawDesc)),\n\t\t\tNumEnums:      4,\n\t\t\tNumMessages:   11,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_dns_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_dns_config_proto_depIdxs,\n\t\tEnumInfos:         file_app_dns_config_proto_enumTypes,\n\t\tMessageInfos:      file_app_dns_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_dns_config_proto = out.File\n\tfile_app_dns_config_proto_goTypes = nil\n\tfile_app_dns_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/dns/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.dns;\noption csharp_namespace = \"V2Ray.Core.App.Dns\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/dns\";\noption java_package = \"com.v2ray.core.app.dns\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/net/destination.proto\";\nimport \"app/router/routercommon/common.proto\";\nimport \"app/dns/fakedns/fakedns.proto\";\n\nimport \"common/protoext/extensions.proto\";\n\nmessage NameServer {\n  v2ray.core.common.net.Endpoint address = 1;\n  bytes client_ip = 5;\n  string tag = 7;\n\n  message PriorityDomain {\n    DomainMatchingType type = 1;\n    string domain = 2;\n  }\n\n  message OriginalRule {\n    string rule = 1;\n    uint32 size = 2;\n  }\n\n  repeated PriorityDomain prioritized_domain = 2;\n  repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3;\n  repeated OriginalRule original_rules = 4;\n\n  v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 11;\n\n  // Deprecated. Use fallback_strategy.\n  bool skipFallback = 6 [deprecated = true];\n\n  optional QueryStrategy query_strategy = 8;\n  optional CacheStrategy cache_strategy = 9;\n  optional FallbackStrategy fallback_strategy = 10;\n}\n\nenum DomainMatchingType {\n  Full = 0;\n  Subdomain = 1;\n  Keyword = 2;\n  Regex = 3;\n}\n\nenum QueryStrategy {\n  USE_IP = 0;\n  USE_IP4 = 1;\n  USE_IP6 = 2;\n}\n\nenum CacheStrategy {\n  CacheEnabled = 0;\n  CacheDisabled = 1;\n}\n\nenum FallbackStrategy {\n  Enabled = 0;\n  Disabled = 1;\n  DisabledIfAnyMatch = 2;\n}\n\nmessage HostMapping {\n  DomainMatchingType type = 1;\n  string domain = 2;\n\n  repeated bytes ip = 3;\n\n  // ProxiedDomain indicates the mapped domain has the same IP address on this\n  // domain. V2Ray will use this domain for IP queries.\n  string proxied_domain = 4;\n}\n\nmessage Config {\n  // Nameservers used by this DNS. Only traditional UDP servers are support at\n  // the moment. A special value 'localhost' as a domain address can be set to\n  // use DNS on local system.\n  repeated v2ray.core.common.net.Endpoint NameServers = 1 [deprecated = true];\n\n  // NameServer list used by this DNS client.\n  repeated NameServer name_server = 5;\n\n  // Static hosts. Domain to IP.\n  // Deprecated. Use static_hosts.\n  map<string, v2ray.core.common.net.IPOrDomain> Hosts = 2 [deprecated = true];\n\n  // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes\n  // (IPv6).\n  bytes client_ip = 3;\n\n  // Static domain-ip mapping in DNS server.\n  repeated HostMapping static_hosts = 4;\n\n  // Global fakedns object.\n  v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 16;\n\n  // Tag is the inbound tag of DNS client.\n  string tag = 6;\n\n  reserved 7;\n\n  // Domain matcher to use\n  string domain_matcher = 15;\n\n  // DisableCache disables DNS cache\n  // Deprecated. Use cache_strategy.\n  bool disableCache = 8 [deprecated = true];\n\n  // Deprecated. Use fallback_strategy.\n  bool disableFallback = 10 [deprecated = true];\n\n  // Deprecated. Use fallback_strategy.\n  bool disableFallbackIfMatch = 11 [deprecated = true];\n\n  // Default query strategy (IPv4, IPv6, or both) for each name server.\n  QueryStrategy query_strategy = 9;\n\n  // Default cache strategy for each name server.\n  CacheStrategy cache_strategy = 12;\n\n  // Default fallback strategy for each name server.\n  FallbackStrategy fallback_strategy = 13;\n}\n\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"dns\";\n\n\n  // Nameservers used by this DNS. Only traditional UDP servers are support at\n  // the moment. A special value 'localhost' as a domain address can be set to\n  // use DNS on local system.\n  reserved 1;\n\n  // NameServer list used by this DNS client.\n  repeated SimplifiedNameServer name_server = 5;\n\n  // Static hosts. Domain to IP.\n  // Deprecated. Use static_hosts.\n  reserved 2;\n\n  // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes\n  // (IPv6).\n  string client_ip = 3;\n\n  // Static domain-ip mapping in DNS server.\n  repeated SimplifiedHostMapping static_hosts = 4;\n\n  // Global fakedns object.\n  v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 16;\n\n  // Tag is the inbound tag of DNS client.\n  string tag = 6;\n\n  reserved 7;\n\n  // Domain matcher to use\n  string domain_matcher = 15;\n\n  // DisableCache disables DNS cache\n  // Deprecated. Use cache_strategy.\n  bool disableCache = 8 [deprecated = true];\n\n  // Deprecated. Use fallback_strategy.\n  bool disableFallback = 10 [deprecated = true];\n\n  // Deprecated. Use fallback_strategy.\n  bool disableFallbackIfMatch = 11 [deprecated = true];\n\n  // Default query strategy (IPv4, IPv6, or both) for each name server.\n  QueryStrategy query_strategy = 9;\n\n  // Default cache strategy for each name server.\n  CacheStrategy cache_strategy = 12;\n\n  // Default fallback strategy for each name server.\n  FallbackStrategy fallback_strategy = 13;\n}\n\n\nmessage SimplifiedHostMapping {\n  DomainMatchingType type = 1;\n  string domain = 2;\n\n  repeated string ip = 3;\n\n  // ProxiedDomain indicates the mapped domain has the same IP address on this\n  // domain. V2Ray will use this domain for IP queries.\n  string proxied_domain = 4;\n}\n\nmessage SimplifiedNameServer {\n  v2ray.core.common.net.Endpoint address = 1;\n  string client_ip = 5;\n  string tag = 7;\n\n  message PriorityDomain {\n    DomainMatchingType type = 1;\n    string domain = 2;\n  }\n\n  message OriginalRule {\n    string rule = 1;\n    uint32 size = 2;\n  }\n\n  repeated PriorityDomain prioritized_domain = 2;\n  repeated v2ray.core.app.router.routercommon.GeoIP geoip = 3;\n  repeated OriginalRule original_rules = 4;\n\n  v2ray.core.app.dns.fakedns.FakeDnsPoolMulti fake_dns = 11;\n\n  // Deprecated. Use fallback_strategy.\n  bool skipFallback = 6 [deprecated = true];\n\n  optional QueryStrategy query_strategy = 8;\n  optional CacheStrategy cache_strategy = 9;\n  optional FallbackStrategy fallback_strategy = 10;\n  repeated v2ray.core.app.router.routercommon.GeoSite geo_domain = 68001;\n}\n"
  },
  {
    "path": "app/dns/dns.go",
    "content": "//go:build !confonly\n// +build !confonly\n\n// Package dns is an implementation of core.DNS feature.\npackage dns\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n)\n\n// DNS is a DNS rely server.\ntype DNS struct {\n\tsync.Mutex\n\thosts         *StaticHosts\n\tclients       []*Client\n\tctx           context.Context\n\tclientTags    map[string]bool\n\tfakeDNSEngine *FakeDNSEngine\n\tdomainMatcher strmatcher.IndexMatcher\n\tmatcherInfos  []DomainMatcherInfo\n}\n\n// DomainMatcherInfo contains information attached to index returned by Server.domainMatcher\ntype DomainMatcherInfo struct {\n\tclientIdx     uint16\n\tdomainRuleIdx uint16\n}\n\n// New creates a new DNS server with given configuration.\nfunc New(ctx context.Context, config *Config) (*DNS, error) {\n\t// Create static hosts\n\thosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create hosts\").Base(err)\n\t}\n\n\t// Create name servers from legacy configs\n\tclients := []*Client{}\n\tfor _, endpoint := range config.NameServers {\n\t\tfeatures.PrintDeprecatedFeatureWarning(\"simple DNS server\")\n\t\tclient, err := NewClient(ctx, &NameServer{Address: endpoint}, config)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create client\").Base(err)\n\t\t}\n\t\tclients = append(clients, client)\n\t}\n\n\t// Create name servers\n\tnsClientMap := map[int]int{}\n\tfor nsIdx, ns := range config.NameServer {\n\t\tclient, err := NewClient(ctx, ns, config)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create client\").Base(err)\n\t\t}\n\t\tnsClientMap[nsIdx] = len(clients)\n\t\tclients = append(clients, client)\n\t}\n\n\t// If there is no DNS client in config, add a `localhost` DNS client\n\tif len(clients) == 0 {\n\t\tclients = append(clients, NewLocalDNSClient())\n\t}\n\n\ts := &DNS{\n\t\thosts:   hosts,\n\t\tclients: clients,\n\t\tctx:     ctx,\n\t}\n\n\t// Establish members related to global DNS state\n\ts.clientTags = make(map[string]bool)\n\tfor _, client := range clients {\n\t\ts.clientTags[client.tag] = true\n\t}\n\tif err := establishDomainRules(s, config, nsClientMap); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := establishExpectedIPs(s, config, nsClientMap); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := establishFakeDNS(s, config, nsClientMap); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn s, nil\n}\n\nfunc establishDomainRules(s *DNS, config *Config, nsClientMap map[int]int) error {\n\tdomainRuleCount := 0\n\tfor _, ns := range config.NameServer {\n\t\tdomainRuleCount += len(ns.PrioritizedDomain)\n\t}\n\t// MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1\n\tmatcherInfos := make([]DomainMatcherInfo, domainRuleCount+1)\n\tvar domainMatcher strmatcher.IndexMatcher\n\tswitch config.DomainMatcher {\n\tcase \"mph\", \"hybrid\":\n\t\tnewError(\"using mph domain matcher\").AtDebug().WriteToLog()\n\t\tdomainMatcher = strmatcher.NewMphIndexMatcher()\n\tcase \"linear\":\n\t\tfallthrough\n\tdefault:\n\t\tnewError(\"using default domain matcher\").AtDebug().WriteToLog()\n\t\tdomainMatcher = strmatcher.NewLinearIndexMatcher()\n\t}\n\tfor nsIdx, ns := range config.NameServer {\n\t\tclientIdx := nsClientMap[nsIdx]\n\t\tvar rules []string\n\t\truleCurr := 0\n\t\truleIter := 0\n\t\tfor _, domain := range ns.PrioritizedDomain {\n\t\t\tdomainRule, err := toStrMatcher(domain.Type, domain.Domain)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to create prioritized domain\").Base(err).AtWarning()\n\t\t\t}\n\t\t\toriginalRuleIdx := ruleCurr\n\t\t\tif ruleCurr < len(ns.OriginalRules) {\n\t\t\t\trule := ns.OriginalRules[ruleCurr]\n\t\t\t\tif ruleCurr >= len(rules) {\n\t\t\t\t\trules = append(rules, rule.Rule)\n\t\t\t\t}\n\t\t\t\truleIter++\n\t\t\t\tif ruleIter >= int(rule.Size) {\n\t\t\t\t\truleIter = 0\n\t\t\t\t\truleCurr++\n\t\t\t\t}\n\t\t\t} else { // No original rule, generate one according to current domain matcher (majorly for compatibility with tests)\n\t\t\t\trules = append(rules, domainRule.String())\n\t\t\t\truleCurr++\n\t\t\t}\n\t\t\tmidx := domainMatcher.Add(domainRule)\n\t\t\tmatcherInfos[midx] = DomainMatcherInfo{\n\t\t\t\tclientIdx:     uint16(clientIdx),\n\t\t\t\tdomainRuleIdx: uint16(originalRuleIdx),\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to create prioritized domain\").Base(err).AtWarning()\n\t\t\t}\n\t\t}\n\t\ts.clients[clientIdx].domains = rules\n\t}\n\tif err := domainMatcher.Build(); err != nil {\n\t\treturn err\n\t}\n\ts.domainMatcher = domainMatcher\n\ts.matcherInfos = matcherInfos\n\treturn nil\n}\n\nfunc establishExpectedIPs(s *DNS, config *Config, nsClientMap map[int]int) error {\n\tgeoipContainer := router.GeoIPMatcherContainer{}\n\tfor nsIdx, ns := range config.NameServer {\n\t\tclientIdx := nsClientMap[nsIdx]\n\t\tvar matchers []*router.GeoIPMatcher\n\t\tfor _, geoip := range ns.Geoip {\n\t\t\tmatcher, err := geoipContainer.Add(geoip)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to create ip matcher\").Base(err).AtWarning()\n\t\t\t}\n\t\t\tmatchers = append(matchers, matcher)\n\t\t}\n\t\ts.clients[clientIdx].expectIPs = matchers\n\t}\n\treturn nil\n}\n\nfunc establishFakeDNS(s *DNS, config *Config, nsClientMap map[int]int) error {\n\tfakeHolders := &fakedns.HolderMulti{}\n\tfakeDefault := (*fakedns.HolderMulti)(nil)\n\tif config.FakeDns != nil {\n\t\tdefaultEngine, err := fakeHolders.AddPoolMulti(config.FakeDns)\n\t\tif err != nil {\n\t\t\treturn newError(\"fail to create fake dns\").Base(err).AtWarning()\n\t\t}\n\t\tfakeDefault = defaultEngine\n\t}\n\tfor nsIdx, ns := range config.NameServer {\n\t\tclientIdx := nsClientMap[nsIdx]\n\t\tif ns.FakeDns == nil {\n\t\t\tcontinue\n\t\t}\n\t\tengine, err := fakeHolders.AddPoolMulti(ns.FakeDns)\n\t\tif err != nil {\n\t\t\treturn newError(\"fail to create fake dns\").Base(err).AtWarning()\n\t\t}\n\t\ts.clients[clientIdx].fakeDNS = NewFakeDNSServer(engine)\n\t\ts.clients[clientIdx].queryStrategy.FakeEnable = true\n\t}\n\t// Do not create FakeDNSEngine feature if no FakeDNS server is configured\n\tif fakeHolders.IsEmpty() {\n\t\treturn nil\n\t}\n\t// Add FakeDNSEngine feature when DNS feature is added for the first time\n\ts.fakeDNSEngine = &FakeDNSEngine{dns: s, fakeHolders: fakeHolders, fakeDefault: fakeDefault}\n\treturn core.RequireFeatures(s.ctx, func(client dns.Client) error {\n\t\tv := core.MustFromContext(s.ctx)\n\t\tif v.GetFeature(dns.FakeDNSEngineType()) != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif client, ok := client.(dns.ClientWithFakeDNS); ok {\n\t\t\treturn v.AddFeature(client.AsFakeDNSEngine())\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Type implements common.HasType.\nfunc (*DNS) Type() interface{} {\n\treturn dns.ClientType()\n}\n\n// Start implements common.Runnable.\nfunc (s *DNS) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (s *DNS) Close() error {\n\treturn nil\n}\n\n// IsOwnLink implements proxy.dns.ownLinkVerifier\nfunc (s *DNS) IsOwnLink(ctx context.Context) bool {\n\tinbound := session.InboundFromContext(ctx)\n\treturn inbound != nil && s.clientTags[inbound.Tag]\n}\n\n// AsFakeDNSClient implements dns.ClientWithFakeDNS.\nfunc (s *DNS) AsFakeDNSClient() dns.Client {\n\treturn &FakeDNSClient{DNS: s}\n}\n\n// AsFakeDNSEngine implements dns.ClientWithFakeDNS.\nfunc (s *DNS) AsFakeDNSEngine() dns.FakeDNSEngine {\n\treturn s.fakeDNSEngine\n}\n\n// LookupIP implements dns.Client.\nfunc (s *DNS) LookupIP(domain string) ([]net.IP, error) {\n\treturn s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, IPv6Enable: true, FakeEnable: false})\n}\n\n// LookupIPv4 implements dns.IPv4Lookup.\nfunc (s *DNS) LookupIPv4(domain string) ([]net.IP, error) {\n\treturn s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, FakeEnable: false})\n}\n\n// LookupIPv6 implements dns.IPv6Lookup.\nfunc (s *DNS) LookupIPv6(domain string) ([]net.IP, error) {\n\treturn s.lookupIPInternal(domain, dns.IPOption{IPv6Enable: true, FakeEnable: false})\n}\n\nfunc (s *DNS) lookupIPInternal(domain string, option dns.IPOption) ([]net.IP, error) {\n\tif domain == \"\" {\n\t\treturn nil, newError(\"empty domain name\")\n\t}\n\n\t// Normalize the FQDN form query\n\tdomain = strings.TrimSuffix(domain, \".\")\n\n\t// Static host lookup\n\tswitch addrs := s.hosts.Lookup(domain, option); {\n\tcase addrs == nil: // Domain not recorded in static host\n\t\tbreak\n\tcase len(addrs) == 0: // Domain recorded, but no valid IP returned (e.g. IPv4 address with only IPv6 enabled)\n\t\treturn nil, dns.ErrEmptyResponse\n\tcase len(addrs) == 1 && addrs[0].Family().IsDomain(): // Domain replacement\n\t\tnewError(\"domain replaced: \", domain, \" -> \", addrs[0].Domain()).WriteToLog()\n\t\tdomain = addrs[0].Domain()\n\tdefault: // Successfully found ip records in static host\n\t\tnewError(\"returning \", len(addrs), \" IP(s) for domain \", domain, \" -> \", addrs).WriteToLog()\n\t\treturn toNetIP(addrs)\n\t}\n\n\t// Name servers lookup\n\terrs := []error{}\n\tfor _, client := range s.sortClients(domain, option) {\n\t\tips, err := client.QueryIP(s.ctx, domain, option)\n\t\tif len(ips) > 0 {\n\t\t\treturn ips, nil\n\t\t}\n\t\tif err != nil {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t\tif err != dns.ErrEmptyResponse { // ErrEmptyResponse is not seen as failure, so no failed log\n\t\t\tnewError(\"failed to lookup ip for domain \", domain, \" at server \", client.Name()).Base(err).WriteToLog()\n\t\t}\n\t\tif err != context.Canceled && err != context.DeadlineExceeded && err != errExpectedIPNonMatch {\n\t\t\treturn nil, err // Only continue lookup for certain errors\n\t\t}\n\t}\n\n\tif len(errs) == 0 {\n\t\treturn nil, dns.ErrEmptyResponse\n\t}\n\treturn nil, newError(\"returning nil for domain \", domain).Base(errors.Combine(errs...))\n}\n\nfunc (s *DNS) sortClients(domain string, option dns.IPOption) []*Client {\n\tclients := make([]*Client, 0, len(s.clients))\n\tclientUsed := make([]bool, len(s.clients))\n\tclientIdxs := make([]int, 0, len(s.clients))\n\tdomainRules := []string{}\n\n\t// Priority domain matching\n\tfor _, match := range s.domainMatcher.Match(domain) {\n\t\tinfo := s.matcherInfos[match]\n\t\tclient := s.clients[info.clientIdx]\n\t\tdomainRule := client.domains[info.domainRuleIdx]\n\t\tdomainRules = append(domainRules, fmt.Sprintf(\"%s(DNS idx:%d)\", domainRule, info.clientIdx))\n\t\tswitch {\n\t\tcase clientUsed[info.clientIdx]:\n\t\t\tcontinue\n\t\tcase !option.FakeEnable && isFakeDNS(client.server):\n\t\t\tcontinue\n\t\t}\n\t\tclientUsed[info.clientIdx] = true\n\t\tclients = append(clients, client)\n\t\tclientIdxs = append(clientIdxs, int(info.clientIdx))\n\t}\n\n\t// Default round-robin query\n\thasDomainMatch := len(clients) > 0\n\tfor idx, client := range s.clients {\n\t\tswitch {\n\t\tcase clientUsed[idx]:\n\t\t\tcontinue\n\t\tcase !option.FakeEnable && isFakeDNS(client.server):\n\t\t\tcontinue\n\t\tcase client.fallbackStrategy == FallbackStrategy_Disabled:\n\t\t\tcontinue\n\t\tcase client.fallbackStrategy == FallbackStrategy_DisabledIfAnyMatch && hasDomainMatch:\n\t\t\tcontinue\n\t\t}\n\t\tclientUsed[idx] = true\n\t\tclients = append(clients, client)\n\t\tclientIdxs = append(clientIdxs, idx)\n\t}\n\n\tif len(domainRules) > 0 {\n\t\tnewError(\"domain \", domain, \" matches following rules: \", domainRules).AtDebug().WriteToLog()\n\t}\n\tif len(clientIdxs) > 0 {\n\t\tnewError(\"domain \", domain, \" will use DNS in order: \", s.formatClientNames(clientIdxs, option), \" \", toReqTypes(option)).AtDebug().WriteToLog()\n\t}\n\n\treturn clients\n}\n\nfunc (s *DNS) formatClientNames(clientIdxs []int, option dns.IPOption) []string {\n\tclientNames := make([]string, 0, len(clientIdxs))\n\tcounter := make(map[string]uint, len(clientIdxs))\n\tfor _, clientIdx := range clientIdxs {\n\t\tclient := s.clients[clientIdx]\n\t\tvar name string\n\t\tif option.With(client.queryStrategy).FakeEnable {\n\t\t\tname = fmt.Sprintf(\"%s(DNS idx:%d)\", client.fakeDNS.Name(), clientIdx)\n\t\t} else {\n\t\t\tname = client.Name()\n\t\t}\n\t\tcounter[name]++\n\t\tclientNames = append(clientNames, name)\n\t}\n\tfor idx, clientIdx := range clientIdxs {\n\t\tname := clientNames[idx]\n\t\tif counter[name] > 1 {\n\t\t\tclientNames[idx] = fmt.Sprintf(\"%s(DNS idx:%d)\", name, clientIdx)\n\t\t}\n\t}\n\treturn clientNames\n}\n\nvar matcherTypeMap = map[routercommon.Domain_Type]DomainMatchingType{\n\troutercommon.Domain_Plain:      DomainMatchingType_Keyword,\n\troutercommon.Domain_Regex:      DomainMatchingType_Regex,\n\troutercommon.Domain_RootDomain: DomainMatchingType_Subdomain,\n\troutercommon.Domain_Full:       DomainMatchingType_Full,\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tctx = cfgcommon.NewConfigureLoadingContext(ctx)\n\n\t\tgeoloadername := platform.NewEnvFlag(\"v2ray.conf.geoloader\").GetValue(func() string {\n\t\t\treturn \"standard\"\n\t\t})\n\n\t\tif loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {\n\t\t\tcfgcommon.SetGeoDataLoader(ctx, loader)\n\t\t} else {\n\t\t\treturn nil, newError(\"unable to create geo data loader \").Base(err)\n\t\t}\n\n\t\tcfgEnv := cfgcommon.GetConfigureLoadingEnvironment(ctx)\n\t\tgeoLoader := cfgEnv.GetGeoLoader()\n\n\t\tsimplifiedConfig := config.(*SimplifiedConfig)\n\t\tfor _, v := range simplifiedConfig.NameServer {\n\t\t\tfor _, geo := range v.Geoip {\n\t\t\t\tif geo.Code != \"\" {\n\t\t\t\t\tfilepath := \"geoip.dat\"\n\t\t\t\t\tif geo.FilePath != \"\" {\n\t\t\t\t\t\tfilepath = geo.FilePath\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgeo.CountryCode = geo.Code\n\t\t\t\t\t}\n\t\t\t\t\tvar err error\n\t\t\t\t\tgeo.Cidr, err = geoLoader.LoadIP(filepath, geo.Code)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, newError(\"unable to load geoip\").Base(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor _, geo := range v.GeoDomain {\n\t\t\t\tif geo.Code != \"\" {\n\t\t\t\t\tfilepath := \"geosite.dat\"\n\t\t\t\t\tif geo.FilePath != \"\" {\n\t\t\t\t\t\tfilepath = geo.FilePath\n\t\t\t\t\t}\n\t\t\t\t\tvar err error\n\t\t\t\t\tgeo.Domain, err = geoLoader.LoadGeoSiteWithAttr(filepath, geo.Code)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, newError(\"unable to load geodomain\").Base(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor _, domain := range geo.Domain {\n\t\t\t\t\tv.PrioritizedDomain = append(v.PrioritizedDomain, &SimplifiedNameServer_PriorityDomain{\n\t\t\t\t\t\tType:   matcherTypeMap[domain.Type],\n\t\t\t\t\t\tDomain: domain.Value,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar nameservers []*NameServer\n\n\t\tfor _, v := range simplifiedConfig.NameServer {\n\t\t\tnameserver := &NameServer{\n\t\t\t\tAddress:          v.Address,\n\t\t\t\tClientIp:         net.ParseIP(v.ClientIp),\n\t\t\t\tTag:              v.Tag,\n\t\t\t\tQueryStrategy:    v.QueryStrategy,\n\t\t\t\tCacheStrategy:    v.CacheStrategy,\n\t\t\t\tFallbackStrategy: v.FallbackStrategy,\n\t\t\t\tSkipFallback:     v.SkipFallback,\n\t\t\t\tGeoip:            v.Geoip,\n\t\t\t}\n\t\t\tfor _, prioritizedDomain := range v.PrioritizedDomain {\n\t\t\t\tnameserver.PrioritizedDomain = append(nameserver.PrioritizedDomain, &NameServer_PriorityDomain{\n\t\t\t\t\tType:   prioritizedDomain.Type,\n\t\t\t\t\tDomain: prioritizedDomain.Domain,\n\t\t\t\t})\n\t\t\t}\n\t\t\tnameservers = append(nameservers, nameserver)\n\t\t}\n\n\t\tvar statichosts []*HostMapping\n\n\t\tfor _, v := range simplifiedConfig.StaticHosts {\n\t\t\tstatichost := &HostMapping{\n\t\t\t\tType:          v.Type,\n\t\t\t\tDomain:        v.Domain,\n\t\t\t\tProxiedDomain: v.ProxiedDomain,\n\t\t\t}\n\t\t\tfor _, ip := range v.Ip {\n\t\t\t\tstatichost.Ip = append(statichost.Ip, net.ParseIP(ip))\n\t\t\t}\n\t\t\tstatichosts = append(statichosts, statichost)\n\t\t}\n\n\t\tfullConfig := &Config{\n\t\t\tStaticHosts:      statichosts,\n\t\t\tNameServer:       nameservers,\n\t\t\tClientIp:         net.ParseIP(simplifiedConfig.ClientIp),\n\t\t\tTag:              simplifiedConfig.Tag,\n\t\t\tDomainMatcher:    simplifiedConfig.DomainMatcher,\n\t\t\tQueryStrategy:    simplifiedConfig.QueryStrategy,\n\t\t\tCacheStrategy:    simplifiedConfig.CacheStrategy,\n\t\t\tFallbackStrategy: simplifiedConfig.FallbackStrategy,\n\t\t\t// Deprecated flags\n\t\t\tDisableCache:           simplifiedConfig.DisableCache,\n\t\t\tDisableFallback:        simplifiedConfig.DisableFallback,\n\t\t\tDisableFallbackIfMatch: simplifiedConfig.DisableFallbackIfMatch,\n\t\t}\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n"
  },
  {
    "path": "app/dns/dns_test.go",
    "content": "package dns_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/miekg/dns\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\tfeature_dns \"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\ntype staticHandler struct{}\n\nfunc (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {\n\tans := new(dns.Msg)\n\tans.Id = r.Id\n\n\tvar clientIP net.IP\n\n\topt := r.IsEdns0()\n\tif opt != nil {\n\t\tfor _, o := range opt.Option {\n\t\t\tif o.Option() == dns.EDNS0SUBNET {\n\t\t\t\tsubnet := o.(*dns.EDNS0_SUBNET)\n\t\t\t\tclientIP = subnet.Address\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, q := range r.Question {\n\t\tswitch {\n\t\tcase q.Name == \"google.com.\" && q.Qtype == dns.TypeA:\n\t\t\tif clientIP == nil {\n\t\t\t\trr, _ := dns.NewRR(\"google.com. IN A 8.8.8.8\")\n\t\t\t\tans.Answer = append(ans.Answer, rr)\n\t\t\t} else {\n\t\t\t\trr, _ := dns.NewRR(\"google.com. IN A 8.8.4.4\")\n\t\t\t\tans.Answer = append(ans.Answer, rr)\n\t\t\t}\n\n\t\tcase q.Name == \"api.google.com.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"api.google.com. IN A 8.8.7.7\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"v2.api.google.com.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"v2.api.google.com. IN A 8.8.7.8\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"facebook.com.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"facebook.com. IN A 9.9.9.9\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"ipv6.google.com.\" && q.Qtype == dns.TypeA:\n\t\t\trr, err := dns.NewRR(\"ipv6.google.com. IN A 8.8.8.7\")\n\t\t\tcommon.Must(err)\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"ipv6.google.com.\" && q.Qtype == dns.TypeAAAA:\n\t\t\trr, err := dns.NewRR(\"ipv6.google.com. IN AAAA 2001:4860:4860::8888\")\n\t\t\tcommon.Must(err)\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"notexist.google.com.\" && q.Qtype == dns.TypeAAAA:\n\t\t\tans.MsgHdr.Rcode = dns.RcodeNameError\n\n\t\tcase q.Name == \"hostname.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"hostname. IN A 127.0.0.1\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"hostname.local.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"hostname.local. IN A 127.0.0.1\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"hostname.localdomain.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"hostname.localdomain. IN A 127.0.0.1\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"localhost.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"localhost. IN A 127.0.0.2\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"localhost-a.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"localhost-a. IN A 127.0.0.3\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"localhost-b.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"localhost-b. IN A 127.0.0.4\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"Mijia\\\\ Cloud.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"Mijia\\\\ Cloud. IN A 127.0.0.1\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"xn--vi8h.ws.\" /* 🍕.ws */ && q.Qtype == dns.TypeA:\n\t\t\trr, err := dns.NewRR(\"xn--vi8h.ws. IN A 208.100.42.200\")\n\t\t\tcommon.Must(err)\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"xn--l8jaaa.com.\" /* ああああ.com */ && q.Qtype == dns.TypeA:\n\t\t\trr, err := dns.NewRR(\"xn--l8jaaa.com. IN AAAA a:a:a:a::aaaa\")\n\t\t\tcommon.Must(err)\n\t\t\tans.Answer = append(ans.Answer, rr)\n\t\t}\n\t}\n\tw.WriteMsg(ans)\n}\n\nfunc TestUDPServerSubnet(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: uint32(port),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tClientIp: []byte{7, 8, 9, 10},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\tips, err := client.LookupIP(\"google.com\")\n\tif err != nil {\n\t\tt.Fatal(\"unexpected error: \", err)\n\t}\n\n\tif r := cmp.Diff(ips, []net.IP{{8, 8, 4, 4}}); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n\nfunc TestUDPServer(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: uint32(port),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\t{\n\t\tips, err := client.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{\n\t\tips, err := client.LookupIP(\"facebook.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{9, 9, 9, 9}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{\n\t\t_, err := client.LookupIP(\"notexist.google.com\")\n\t\tif err == nil {\n\t\t\tt.Fatal(\"nil error\")\n\t\t}\n\t\tif r := feature_dns.RCodeFromError(err); r != uint16(dns.RcodeNameError) {\n\t\t\tt.Fatal(\"expected NameError, but got \", r)\n\t\t}\n\t}\n\n\t{\n\t\tclientv6 := client.(feature_dns.IPv6Lookup)\n\t\tips, err := clientv6.LookupIPv6(\"ipv4only.google.com\")\n\t\tif err != feature_dns.ErrEmptyResponse {\n\t\t\tt.Fatal(\"error: \", err)\n\t\t}\n\t\tif len(ips) != 0 {\n\t\t\tt.Fatal(\"ips: \", ips)\n\t\t}\n\t}\n\n\t{\n\t\tips, err := client.LookupIP(common.Must2(strmatcher.ToDomain(\"🍕.ws\")).(string))\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{208, 100, 42, 200}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{\n\t\tips, err := client.LookupIP(common.Must2(strmatcher.ToDomain(\"ああああ.com\")).(string))\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{0, 0xa, 0, 0xa, 0, 0xa, 0, 0xa, 0, 0, 0, 0, 0, 0, 0xaa, 0xaa}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\tdnsServer.Shutdown()\n\n\t{\n\t\tips, err := client.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n}\n\nfunc TestPrioritizedDomain(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 9999, /* unreachable */\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNameServer: []*NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   DomainMatchingType_Full,\n\t\t\t\t\t\t\t\tDomain: \"google.com\",\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\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\tstartTime := time.Now()\n\n\t{\n\t\tips, err := client.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\tendTime := time.Now()\n\tif startTime.After(endTime.Add(time.Second * 2)) {\n\t\tt.Error(\"DNS query doesn't finish in 2 seconds.\")\n\t}\n}\n\nfunc TestUDPServerIPv6(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: uint32(port),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\tclient6 := client.(feature_dns.IPv6Lookup)\n\t{\n\t\tips, err := client6.LookupIPv6(\"ipv6.google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{32, 1, 72, 96, 72, 96, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n}\n\nfunc TestStaticHostDomain(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: uint32(port),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tStaticHosts: []*HostMapping{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:          DomainMatchingType_Full,\n\t\t\t\t\t\tDomain:        \"example.com\",\n\t\t\t\t\t\tProxiedDomain: \"google.com\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\t{\n\t\tips, err := client.LookupIP(\"example.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\tdnsServer.Shutdown()\n}\n\nfunc TestIPMatch(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServer: []*NameServer{\n\t\t\t\t\t// private dns, not match\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCountryCode: \"local\",\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// inner ip, will not match\n\t\t\t\t\t\t\t\t\t\tIp:     []byte{192, 168, 11, 1},\n\t\t\t\t\t\t\t\t\t\tPrefix: 32,\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\t// second dns, match ip\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCountryCode: \"test\",\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tIp:     []byte{8, 8, 8, 8},\n\t\t\t\t\t\t\t\t\t\tPrefix: 32,\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\t{\n\t\t\t\t\t\t\t\tCountryCode: \"test\",\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tIp:     []byte{8, 8, 8, 4},\n\t\t\t\t\t\t\t\t\t\tPrefix: 32,\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\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\tstartTime := time.Now()\n\n\t{\n\t\tips, err := client.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\tendTime := time.Now()\n\tif startTime.After(endTime.Add(time.Second * 2)) {\n\t\tt.Error(\"DNS query doesn't finish in 2 seconds.\")\n\t}\n}\n\nfunc TestLocalDomain(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 9999, /* unreachable */\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNameServer: []*NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t// Equivalent of dotless:localhost\n\t\t\t\t\t\t\t{Type: DomainMatchingType_Regex, Domain: \"^[^.]*localhost[^.]*$\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{ // Will match localhost, localhost-a and localhost-b,\n\t\t\t\t\t\t\t\tCountryCode: \"local\",\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{Ip: []byte{127, 0, 0, 2}, Prefix: 32},\n\t\t\t\t\t\t\t\t\t{Ip: []byte{127, 0, 0, 3}, Prefix: 32},\n\t\t\t\t\t\t\t\t\t{Ip: []byte{127, 0, 0, 4}, Prefix: 32},\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\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t// Equivalent of dotless: and domain:local\n\t\t\t\t\t\t\t{Type: DomainMatchingType_Regex, Domain: \"^[^.]*$\"},\n\t\t\t\t\t\t\t{Type: DomainMatchingType_Subdomain, Domain: \"local\"},\n\t\t\t\t\t\t\t{Type: DomainMatchingType_Subdomain, Domain: \"localdomain\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tStaticHosts: []*HostMapping{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"hostnamestatic\",\n\t\t\t\t\t\tIp:     [][]byte{{127, 0, 0, 53}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:          DomainMatchingType_Full,\n\t\t\t\t\t\tDomain:        \"hostnamealias\",\n\t\t\t\t\t\tProxiedDomain: \"hostname.localdomain\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\tstartTime := time.Now()\n\n\t{ // Will match dotless:\n\t\tips, err := client.LookupIP(\"hostname\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match domain:local\n\t\tips, err := client.LookupIP(\"hostname.local\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match static ip\n\t\tips, err := client.LookupIP(\"hostnamestatic\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 53}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match domain replacing\n\t\tips, err := client.LookupIP(\"hostnamealias\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match dotless:localhost, but not expectIPs: 127.0.0.2, 127.0.0.3, then matches at dotless:\n\t\tips, err := client.LookupIP(\"localhost\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 2}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3\n\t\tips, err := client.LookupIP(\"localhost-a\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 3}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match dotless:localhost, and expectIPs: 127.0.0.2, 127.0.0.3\n\t\tips, err := client.LookupIP(\"localhost-b\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 4}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match dotless:\n\t\tips, err := client.LookupIP(\"Mijia Cloud\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{127, 0, 0, 1}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\tendTime := time.Now()\n\tif startTime.After(endTime.Add(time.Second * 2)) {\n\t\tt.Error(\"DNS query doesn't finish in 2 seconds.\")\n\t}\n}\n\nfunc TestMultiMatchPrioritizedDomain(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 9999, /* unreachable */\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNameServer: []*NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   DomainMatchingType_Subdomain,\n\t\t\t\t\t\t\t\tDomain: \"google.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{ // Will only match 8.8.8.8 and 8.8.4.4\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{Ip: []byte{8, 8, 8, 8}, Prefix: 32},\n\t\t\t\t\t\t\t\t\t{Ip: []byte{8, 8, 4, 4}, Prefix: 32},\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\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   DomainMatchingType_Subdomain,\n\t\t\t\t\t\t\t\tDomain: \"google.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{ // Will match 8.8.8.8 and 8.8.8.7, etc\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{Ip: []byte{8, 8, 8, 7}, Prefix: 24},\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\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   DomainMatchingType_Subdomain,\n\t\t\t\t\t\t\t\tDomain: \"api.google.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{ // Will only match 8.8.7.7 (api.google.com)\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{Ip: []byte{8, 8, 7, 7}, Prefix: 32},\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\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   DomainMatchingType_Full,\n\t\t\t\t\t\t\t\tDomain: \"v2.api.google.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{ // Will only match 8.8.7.8 (v2.api.google.com)\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{Ip: []byte{8, 8, 7, 8}, Prefix: 32},\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\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\n\tclient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\n\tstartTime := time.Now()\n\n\t{ // Will match server 1,2 and server 1 returns expected ip\n\t\tips, err := client.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match server 1,2 and server 1 returns unexpected ip, then server 2 returns expected one\n\t\tclientv4 := client.(feature_dns.IPv4Lookup)\n\t\tips, err := clientv4.LookupIPv4(\"ipv6.google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 7}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match server 3,1,2 and server 3 returns expected one\n\t\tips, err := client.LookupIP(\"api.google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 7, 7}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\t{ // Will match server 4,3,1,2 and server 4 returns expected one\n\t\tips, err := client.LookupIP(\"v2.api.google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 7, 8}}); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n\n\tendTime := time.Now()\n\tif startTime.After(endTime.Add(time.Second * 2)) {\n\t\tt.Error(\"DNS query doesn't finish in 2 seconds.\")\n\t}\n}\n"
  },
  {
    "path": "app/dns/dnscommon.go",
    "content": "package dns\n\nimport (\n\t\"encoding/binary\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\n// Fqdn normalizes domain make sure it ends with '.'\nfunc Fqdn(domain string) string {\n\tif len(domain) > 0 && strings.HasSuffix(domain, \".\") {\n\t\treturn domain\n\t}\n\treturn domain + \".\"\n}\n\ntype record struct {\n\tA    *IPRecord\n\tAAAA *IPRecord\n}\n\n// IPRecord is a cacheable item for a resolved domain\ntype IPRecord struct {\n\tReqID  uint16\n\tIP     []net.Address\n\tExpire time.Time\n\tRCode  dnsmessage.RCode\n}\n\nfunc (r *IPRecord) getIPs() ([]net.Address, error) {\n\tif r == nil || r.Expire.Before(time.Now()) {\n\t\treturn nil, errRecordNotFound\n\t}\n\tif r.RCode != dnsmessage.RCodeSuccess {\n\t\treturn nil, dns_feature.RCodeError(r.RCode)\n\t}\n\treturn r.IP, nil\n}\n\nfunc isNewer(baseRec *IPRecord, newRec *IPRecord) bool {\n\tif newRec == nil {\n\t\treturn false\n\t}\n\tif baseRec == nil {\n\t\treturn true\n\t}\n\treturn baseRec.Expire.Before(newRec.Expire)\n}\n\nvar errRecordNotFound = errors.New(\"record not found\")\n\ntype dnsRequest struct {\n\treqType dnsmessage.Type\n\tdomain  string\n\tstart   time.Time\n\texpire  time.Time\n\tmsg     *dnsmessage.Message\n}\n\nfunc genEDNS0Options(clientIP net.IP) *dnsmessage.Resource {\n\tif len(clientIP) == 0 {\n\t\treturn nil\n\t}\n\n\tvar netmask int\n\tvar family uint16\n\n\tif len(clientIP) == 4 {\n\t\tfamily = 1\n\t\tnetmask = 24 // 24 for IPV4, 96 for IPv6\n\t} else {\n\t\tfamily = 2\n\t\tnetmask = 96\n\t}\n\n\tb := make([]byte, 4)\n\tbinary.BigEndian.PutUint16(b[0:], family)\n\tb[2] = byte(netmask)\n\tb[3] = 0\n\tswitch family {\n\tcase 1:\n\t\tip := clientIP.To4().Mask(net.CIDRMask(netmask, net.IPv4len*8))\n\t\tneedLength := (netmask + 8 - 1) / 8 // division rounding up\n\t\tb = append(b, ip[:needLength]...)\n\tcase 2:\n\t\tip := clientIP.Mask(net.CIDRMask(netmask, net.IPv6len*8))\n\t\tneedLength := (netmask + 8 - 1) / 8 // division rounding up\n\t\tb = append(b, ip[:needLength]...)\n\t}\n\n\tconst EDNS0SUBNET = 0x08\n\n\topt := new(dnsmessage.Resource)\n\tcommon.Must(opt.Header.SetEDNS0(1350, 0xfe00, true))\n\n\topt.Body = &dnsmessage.OPTResource{\n\t\tOptions: []dnsmessage.Option{\n\t\t\t{\n\t\t\t\tCode: EDNS0SUBNET,\n\t\t\t\tData: b,\n\t\t\t},\n\t\t},\n\t}\n\n\treturn opt\n}\n\nfunc buildReqMsgs(domain string, option dns_feature.IPOption, reqIDGen func() uint16, reqOpts *dnsmessage.Resource) []*dnsRequest {\n\tqA := dnsmessage.Question{\n\t\tName:  dnsmessage.MustNewName(domain),\n\t\tType:  dnsmessage.TypeA,\n\t\tClass: dnsmessage.ClassINET,\n\t}\n\n\tqAAAA := dnsmessage.Question{\n\t\tName:  dnsmessage.MustNewName(domain),\n\t\tType:  dnsmessage.TypeAAAA,\n\t\tClass: dnsmessage.ClassINET,\n\t}\n\n\tvar reqs []*dnsRequest\n\tnow := time.Now()\n\n\tif option.IPv4Enable {\n\t\tmsg := new(dnsmessage.Message)\n\t\tmsg.Header.ID = reqIDGen()\n\t\tmsg.Header.RecursionDesired = true\n\t\tmsg.Questions = []dnsmessage.Question{qA}\n\t\tif reqOpts != nil {\n\t\t\tmsg.Additionals = append(msg.Additionals, *reqOpts)\n\t\t}\n\t\treqs = append(reqs, &dnsRequest{\n\t\t\treqType: dnsmessage.TypeA,\n\t\t\tdomain:  domain,\n\t\t\tstart:   now,\n\t\t\tmsg:     msg,\n\t\t})\n\t}\n\n\tif option.IPv6Enable {\n\t\tmsg := new(dnsmessage.Message)\n\t\tmsg.Header.ID = reqIDGen()\n\t\tmsg.Header.RecursionDesired = true\n\t\tmsg.Questions = []dnsmessage.Question{qAAAA}\n\t\tif reqOpts != nil {\n\t\t\tmsg.Additionals = append(msg.Additionals, *reqOpts)\n\t\t}\n\t\treqs = append(reqs, &dnsRequest{\n\t\t\treqType: dnsmessage.TypeAAAA,\n\t\t\tdomain:  domain,\n\t\t\tstart:   now,\n\t\t\tmsg:     msg,\n\t\t})\n\t}\n\n\treturn reqs\n}\n\n// parseResponse parses DNS answers from the returned payload\nfunc parseResponse(payload []byte) (*IPRecord, error) {\n\tvar parser dnsmessage.Parser\n\th, err := parser.Start(payload)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse DNS response\").Base(err).AtWarning()\n\t}\n\tif err := parser.SkipAllQuestions(); err != nil {\n\t\treturn nil, newError(\"failed to skip questions in DNS response\").Base(err).AtWarning()\n\t}\n\n\tnow := time.Now()\n\tipRecord := &IPRecord{\n\t\tReqID:  h.ID,\n\t\tRCode:  h.RCode,\n\t\tExpire: now.Add(time.Second * 600),\n\t}\n\nL:\n\tfor {\n\t\tah, err := parser.AnswerHeader()\n\t\tif err != nil {\n\t\t\tif err != dnsmessage.ErrSectionDone {\n\t\t\t\tnewError(\"failed to parse answer section for domain: \", ah.Name.String()).Base(err).WriteToLog()\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tttl := ah.TTL\n\t\tif ttl == 0 {\n\t\t\tttl = 600\n\t\t}\n\t\texpire := now.Add(time.Duration(ttl) * time.Second)\n\t\tif ipRecord.Expire.After(expire) {\n\t\t\tipRecord.Expire = expire\n\t\t}\n\n\t\tswitch ah.Type {\n\t\tcase dnsmessage.TypeA:\n\t\t\tans, err := parser.AResource()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to parse A record for domain: \", ah.Name).Base(err).WriteToLog()\n\t\t\t\tbreak L\n\t\t\t}\n\t\t\tipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:]))\n\t\tcase dnsmessage.TypeAAAA:\n\t\t\tans, err := parser.AAAAResource()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to parse AAAA record for domain: \", ah.Name).Base(err).WriteToLog()\n\t\t\t\tbreak L\n\t\t\t}\n\t\t\tipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:]))\n\t\tdefault:\n\t\t\tif err := parser.SkipAnswer(); err != nil {\n\t\t\t\tnewError(\"failed to skip answer\").Base(err).WriteToLog()\n\t\t\t\tbreak L\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t}\n\n\treturn ipRecord, nil\n}\n\nfunc filterIP(ips []net.Address, option dns_feature.IPOption) []net.Address {\n\tfiltered := make([]net.Address, 0, len(ips))\n\tfor _, ip := range ips {\n\t\tif (ip.Family().IsIPv4() && option.IPv4Enable) || (ip.Family().IsIPv6() && option.IPv6Enable) {\n\t\t\tfiltered = append(filtered, ip)\n\t\t}\n\t}\n\treturn filtered\n}\n"
  },
  {
    "path": "app/dns/dnscommon_test.go",
    "content": "package dns\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/miekg/dns\"\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nfunc Test_parseResponse(t *testing.T) {\n\tvar p [][]byte\n\n\tans := new(dns.Msg)\n\tans.Id = 0\n\tp = append(p, common.Must2(ans.Pack()).([]byte))\n\n\tp = append(p, []byte{})\n\n\tans = new(dns.Msg)\n\tans.Id = 1\n\tans.Answer = append(ans.Answer,\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN CNAME m.test.google.com\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN CNAME fake.google.com\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN A 8.8.8.8\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN A 8.8.4.4\")).(dns.RR),\n\t)\n\tp = append(p, common.Must2(ans.Pack()).([]byte))\n\n\tans = new(dns.Msg)\n\tans.Id = 2\n\tans.Answer = append(ans.Answer,\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN CNAME m.test.google.com\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN CNAME fake.google.com\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN CNAME m.test.google.com\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN CNAME test.google.com\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN AAAA 2001::123:8888\")).(dns.RR),\n\t\tcommon.Must2(dns.NewRR(\"google.com. IN AAAA 2001::123:8844\")).(dns.RR),\n\t)\n\tp = append(p, common.Must2(ans.Pack()).([]byte))\n\n\ttests := []struct {\n\t\tname    string\n\t\twant    *IPRecord\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\t\"empty\",\n\t\t\t&IPRecord{0, []net.Address(nil), time.Time{}, dnsmessage.RCodeSuccess},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"error\",\n\t\t\tnil,\n\t\t\ttrue,\n\t\t},\n\t\t{\n\t\t\t\"a record\",\n\t\t\t&IPRecord{\n\t\t\t\t1,\n\t\t\t\t[]net.Address{net.ParseAddress(\"8.8.8.8\"), net.ParseAddress(\"8.8.4.4\")},\n\t\t\t\ttime.Time{},\n\t\t\t\tdnsmessage.RCodeSuccess,\n\t\t\t},\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"aaaa record\",\n\t\t\t&IPRecord{2, []net.Address{net.ParseAddress(\"2001::123:8888\"), net.ParseAddress(\"2001::123:8844\")}, time.Time{}, dnsmessage.RCodeSuccess},\n\t\t\tfalse,\n\t\t},\n\t}\n\tfor i, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := parseResponse(p[i])\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"handleResponse() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif got != nil {\n\t\t\t\t// reset the time\n\t\t\t\tgot.Expire = time.Time{}\n\t\t\t}\n\t\t\tif cmp.Diff(got, tt.want) != \"\" {\n\t\t\t\tt.Errorf(\"%v\", cmp.Diff(got, tt.want))\n\t\t\t\t// t.Errorf(\"handleResponse() = %#v, want %#v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_buildReqMsgs(t *testing.T) {\n\tstubID := func() uint16 {\n\t\treturn uint16(rand.Uint32())\n\t}\n\ttype args struct {\n\t\tdomain  string\n\t\toption  dns_feature.IPOption\n\t\treqOpts *dnsmessage.Resource\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant int\n\t}{\n\t\t{\"dual stack\", args{\"test.com\", dns_feature.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: true,\n\t\t\tFakeEnable: false,\n\t\t}, nil}, 2},\n\t\t{\"ipv4 only\", args{\"test.com\", dns_feature.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: false,\n\t\t\tFakeEnable: false,\n\t\t}, nil}, 1},\n\t\t{\"ipv6 only\", args{\"test.com\", dns_feature.IPOption{\n\t\t\tIPv4Enable: false,\n\t\t\tIPv6Enable: true,\n\t\t\tFakeEnable: false,\n\t\t}, nil}, 1},\n\t\t{\"none/error\", args{\"test.com\", dns_feature.IPOption{\n\t\t\tIPv4Enable: false,\n\t\t\tIPv6Enable: false,\n\t\t\tFakeEnable: false,\n\t\t}, nil}, 0},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := buildReqMsgs(tt.args.domain, tt.args.option, stubID, tt.args.reqOpts); !(len(got) == tt.want) {\n\t\t\t\tt.Errorf(\"buildReqMsgs() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_genEDNS0Options(t *testing.T) {\n\ttype args struct {\n\t\tclientIP net.IP\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant *dnsmessage.Resource\n\t}{\n\t\t// TODO: Add test cases.\n\t\t{\"ipv4\", args{net.ParseIP(\"4.3.2.1\")}, nil},\n\t\t{\"ipv6\", args{net.ParseIP(\"2001::4321\")}, nil},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := genEDNS0Options(tt.args.clientIP); got == nil {\n\t\t\t\tt.Errorf(\"genEDNS0Options() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestFqdn(t *testing.T) {\n\ttype args struct {\n\t\tdomain string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\"with fqdn\", args{\"www.v2fly.org.\"}, \"www.v2fly.org.\"},\n\t\t{\"without fqdn\", args{\"www.v2fly.org\"}, \"www.v2fly.org.\"},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := Fqdn(tt.args.domain); got != tt.want {\n\t\t\t\tt.Errorf(\"Fqdn() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "app/dns/errors.generated.go",
    "content": "package dns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/dns/fakedns/errors.generated.go",
    "content": "package fakedns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/dns/fakedns/fake.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage fakedns\n\nimport (\n\t\"context\"\n\t\"math\"\n\t\"math/big\"\n\tgonet \"net\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cache\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\ntype Holder struct {\n\tdomainToIP cache.Lru\n\tnextIP     *big.Int\n\tmu         *sync.Mutex\n\n\tipRange *gonet.IPNet\n\n\tconfig *FakeDnsPool\n}\n\nfunc (fkdns *Holder) IsIPInIPPool(ip net.Address) bool {\n\tif ip.Family().IsDomain() {\n\t\treturn false\n\t}\n\treturn fkdns.ipRange.Contains(ip.IP())\n}\n\nfunc (fkdns *Holder) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.Address {\n\tisIPv6 := fkdns.ipRange.IP.To4() == nil\n\tif (isIPv6 && ipv6) || (!isIPv6 && ipv4) {\n\t\treturn fkdns.GetFakeIPForDomain(domain)\n\t}\n\treturn []net.Address{}\n}\n\nfunc (*Holder) Type() interface{} {\n\treturn dns.FakeDNSEngineType()\n}\n\nfunc (fkdns *Holder) Start() error {\n\tif fkdns.config != nil && fkdns.config.IpPool != \"\" && fkdns.config.LruSize != 0 {\n\t\treturn fkdns.initializeFromConfig()\n\t}\n\treturn newError(\"invalid fakeDNS setting\")\n}\n\nfunc (fkdns *Holder) Close() error {\n\tfkdns.domainToIP = nil\n\tfkdns.nextIP = nil\n\tfkdns.ipRange = nil\n\tfkdns.mu = nil\n\treturn nil\n}\n\nfunc NewFakeDNSHolder() (*Holder, error) {\n\tvar fkdns *Holder\n\tvar err error\n\n\tif fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil {\n\t\treturn nil, newError(\"Unable to create Fake Dns Engine\").Base(err).AtError()\n\t}\n\terr = fkdns.initialize(\"198.18.0.0/15\", 65535)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn fkdns, nil\n}\n\nfunc NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) {\n\treturn &Holder{nil, nil, nil, nil, conf}, nil\n}\n\nfunc (fkdns *Holder) initializeFromConfig() error {\n\treturn fkdns.initialize(fkdns.config.IpPool, int(fkdns.config.LruSize))\n}\n\nfunc (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {\n\tvar ipRange *gonet.IPNet\n\tvar ipaddr gonet.IP\n\tvar currentIP *big.Int\n\tvar err error\n\n\tif ipaddr, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil {\n\t\treturn newError(\"Unable to parse CIDR for Fake DNS IP assignment\").Base(err).AtError()\n\t}\n\n\tcurrentIP = big.NewInt(0).SetBytes(ipaddr)\n\tif ipaddr.To4() != nil {\n\t\tcurrentIP = big.NewInt(0).SetBytes(ipaddr.To4())\n\t}\n\n\tones, bits := ipRange.Mask.Size()\n\trooms := bits - ones\n\tif math.Log2(float64(lruSize)) >= float64(rooms) {\n\t\treturn newError(\"LRU size is bigger than subnet size\").AtError()\n\t}\n\tfkdns.domainToIP = cache.NewLru(lruSize)\n\tfkdns.ipRange = ipRange\n\tfkdns.nextIP = currentIP\n\tfkdns.mu = new(sync.Mutex)\n\treturn nil\n}\n\n// GetFakeIPForDomain checks and generate a fake IP for a domain name\nfunc (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address {\n\tfkdns.mu.Lock()\n\tdefer fkdns.mu.Unlock()\n\tif v, ok := fkdns.domainToIP.Get(domain); ok {\n\t\treturn []net.Address{v.(net.Address)}\n\t}\n\tvar ip net.Address\n\tfor {\n\t\tip = net.IPAddress(fkdns.nextIP.Bytes())\n\n\t\tfkdns.nextIP = fkdns.nextIP.Add(fkdns.nextIP, big.NewInt(1))\n\t\tif !fkdns.ipRange.Contains(fkdns.nextIP.Bytes()) {\n\t\t\tfkdns.nextIP = big.NewInt(0).SetBytes(fkdns.ipRange.IP)\n\t\t}\n\n\t\t// if we run for a long time, we may go back to beginning and start seeing the IP in use\n\t\tif _, ok := fkdns.domainToIP.GetKeyFromValue(ip); !ok {\n\t\t\tbreak\n\t\t}\n\t}\n\tfkdns.domainToIP.Put(domain, ip)\n\treturn []net.Address{ip}\n}\n\n// GetDomainFromFakeDNS checks if an IP is a fake IP and have corresponding domain name\nfunc (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string {\n\tif !ip.Family().IsIP() || !fkdns.ipRange.Contains(ip.IP()) {\n\t\treturn \"\"\n\t}\n\tif k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok {\n\t\treturn k.(string)\n\t}\n\treturn \"\"\n}\n\ntype HolderMulti struct {\n\tholders []*Holder\n}\n\nfunc (h *HolderMulti) IsIPInIPPool(ip net.Address) bool {\n\tif ip.Family().IsDomain() {\n\t\treturn false\n\t}\n\tfor _, v := range h.holders {\n\t\tif v.IsIPInIPPool(ip) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (h *HolderMulti) GetFakeIPForDomain3(domain string, ipv4, ipv6 bool) []net.Address {\n\tvar ret []net.Address\n\tfor _, v := range h.holders {\n\t\tret = append(ret, v.GetFakeIPForDomain3(domain, ipv4, ipv6)...)\n\t}\n\treturn ret\n}\n\nfunc (h *HolderMulti) GetFakeIPForDomain(domain string) []net.Address {\n\tvar ret []net.Address\n\tfor _, v := range h.holders {\n\t\tret = append(ret, v.GetFakeIPForDomain(domain)...)\n\t}\n\treturn ret\n}\n\nfunc (h *HolderMulti) GetDomainFromFakeDNS(ip net.Address) string {\n\tfor _, v := range h.holders {\n\t\tif domain := v.GetDomainFromFakeDNS(ip); domain != \"\" {\n\t\t\treturn domain\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc (h *HolderMulti) IsEmpty() bool {\n\treturn len(h.holders) == 0\n}\n\nfunc (h *HolderMulti) AddPool(poolConfig *FakeDnsPool) (*Holder, error) {\n\t_, newIPRange, err := gonet.ParseCIDR(poolConfig.IpPool)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trunning := false\n\tfor _, v := range h.holders {\n\t\tvar ipRange *gonet.IPNet\n\t\tif v.ipRange != nil {\n\t\t\tipRange = v.ipRange\n\t\t\trunning = true\n\t\t} else {\n\t\t\t_, ipRange, err = gonet.ParseCIDR(v.config.IpPool)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tif ipRange.String() == newIPRange.String() {\n\t\t\treturn v, nil\n\t\t}\n\t\tif ipRange.Contains(newIPRange.IP) || newIPRange.Contains(ipRange.IP) {\n\t\t\treturn nil, newError(\"Trying to add ip pool \", newIPRange, \" that overlaps with existing ip pool \", ipRange)\n\t\t}\n\t}\n\tholder, err := NewFakeDNSHolderConfigOnly(poolConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif running {\n\t\tif err := holder.Start(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\th.holders = append(h.holders, holder)\n\treturn holder, nil\n}\n\nfunc (h *HolderMulti) AddPoolMulti(poolMultiConfig *FakeDnsPoolMulti) (*HolderMulti, error) {\n\tholderMulti := &HolderMulti{}\n\tfor _, poolConfig := range poolMultiConfig.Pools {\n\t\tpool, err := h.AddPool(poolConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tholderMulti.holders = append(holderMulti.holders, pool)\n\t}\n\treturn holderMulti, nil // Returned holderMulti holds references to pools managed by `h`\n}\n\nfunc (h *HolderMulti) Type() interface{} {\n\treturn dns.FakeDNSEngineType()\n}\n\nfunc (h *HolderMulti) Start() error {\n\tfor _, v := range h.holders {\n\t\tif err := v.Start(); err != nil {\n\t\t\treturn newError(\"Cannot start all fake dns pools\").Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (h *HolderMulti) Close() error {\n\tfor _, v := range h.holders {\n\t\tif err := v.Close(); err != nil {\n\t\t\treturn newError(\"Cannot close all fake dns pools\").Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (h *HolderMulti) createHolderGroups(conf *FakeDnsPoolMulti) error {\n\tfor _, pool := range conf.Pools {\n\t\t_, err := h.AddPool(pool)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc NewFakeDNSHolderMulti(conf *FakeDnsPoolMulti) (*HolderMulti, error) {\n\tholderMulti := &HolderMulti{}\n\tif err := holderMulti.createHolderGroups(conf); err != nil {\n\t\treturn nil, err\n\t}\n\treturn holderMulti, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*FakeDnsPool)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tvar f *Holder\n\t\tvar err error\n\t\tif f, err = NewFakeDNSHolderConfigOnly(config.(*FakeDnsPool)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn f, nil\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*FakeDnsPoolMulti)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tvar f *HolderMulti\n\t\tvar err error\n\t\tif f, err = NewFakeDNSHolderMulti(config.(*FakeDnsPoolMulti)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn f, nil\n\t}))\n}\n"
  },
  {
    "path": "app/dns/fakedns/fakedns.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage fakedns\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/dns/fakedns/fakedns.pb.go",
    "content": "package fakedns\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 FakeDnsPool struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tIpPool        string                 `protobuf:\"bytes,1,opt,name=ip_pool,json=ipPool,proto3\" json:\"ip_pool,omitempty\"` //CIDR of IP pool used as fake DNS IP\n\tLruSize       int64                  `protobuf:\"varint,2,opt,name=lruSize,proto3\" json:\"lruSize,omitempty\"`            //Size of Pool for remembering relationship between domain name and IP address\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *FakeDnsPool) Reset() {\n\t*x = FakeDnsPool{}\n\tmi := &file_app_dns_fakedns_fakedns_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *FakeDnsPool) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FakeDnsPool) ProtoMessage() {}\n\nfunc (x *FakeDnsPool) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_fakedns_fakedns_proto_msgTypes[0]\n\tif 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 FakeDnsPool.ProtoReflect.Descriptor instead.\nfunc (*FakeDnsPool) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_fakedns_fakedns_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *FakeDnsPool) GetIpPool() string {\n\tif x != nil {\n\t\treturn x.IpPool\n\t}\n\treturn \"\"\n}\n\nfunc (x *FakeDnsPool) GetLruSize() int64 {\n\tif x != nil {\n\t\treturn x.LruSize\n\t}\n\treturn 0\n}\n\ntype FakeDnsPoolMulti struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tPools         []*FakeDnsPool         `protobuf:\"bytes,1,rep,name=pools,proto3\" json:\"pools,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *FakeDnsPoolMulti) Reset() {\n\t*x = FakeDnsPoolMulti{}\n\tmi := &file_app_dns_fakedns_fakedns_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *FakeDnsPoolMulti) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FakeDnsPoolMulti) ProtoMessage() {}\n\nfunc (x *FakeDnsPoolMulti) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_dns_fakedns_fakedns_proto_msgTypes[1]\n\tif 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 FakeDnsPoolMulti.ProtoReflect.Descriptor instead.\nfunc (*FakeDnsPoolMulti) Descriptor() ([]byte, []int) {\n\treturn file_app_dns_fakedns_fakedns_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *FakeDnsPoolMulti) GetPools() []*FakeDnsPool {\n\tif x != nil {\n\t\treturn x.Pools\n\t}\n\treturn nil\n}\n\nvar File_app_dns_fakedns_fakedns_proto protoreflect.FileDescriptor\n\nconst file_app_dns_fakedns_fakedns_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1dapp/dns/fakedns/fakedns.proto\\x12\\x1av2ray.core.app.dns.fakedns\\x1a common/protoext/extensions.proto\\\"X\\n\" +\n\t\"\\vFakeDnsPool\\x12\\x17\\n\" +\n\t\"\\aip_pool\\x18\\x01 \\x01(\\tR\\x06ipPool\\x12\\x18\\n\" +\n\t\"\\alruSize\\x18\\x02 \\x01(\\x03R\\alruSize:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\aservice\\x12\\afakeDns\\\"n\\n\" +\n\t\"\\x10FakeDnsPoolMulti\\x12=\\n\" +\n\t\"\\x05pools\\x18\\x01 \\x03(\\v2'.v2ray.core.app.dns.fakedns.FakeDnsPoolR\\x05pools:\\x1b\\x82\\xb5\\x18\\x17\\n\" +\n\t\"\\aservice\\x12\\ffakeDnsMultiBo\\n\" +\n\t\"\\x1ecom.v2ray.core.app.dns.fakednsP\\x01Z.github.com/v2fly/v2ray-core/v5/app/dns/fakedns\\xaa\\x02\\x1aV2Ray.Core.App.Dns.Fakednsb\\x06proto3\"\n\nvar (\n\tfile_app_dns_fakedns_fakedns_proto_rawDescOnce sync.Once\n\tfile_app_dns_fakedns_fakedns_proto_rawDescData []byte\n)\n\nfunc file_app_dns_fakedns_fakedns_proto_rawDescGZIP() []byte {\n\tfile_app_dns_fakedns_fakedns_proto_rawDescOnce.Do(func() {\n\t\tfile_app_dns_fakedns_fakedns_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_dns_fakedns_fakedns_proto_rawDesc), len(file_app_dns_fakedns_fakedns_proto_rawDesc)))\n\t})\n\treturn file_app_dns_fakedns_fakedns_proto_rawDescData\n}\n\nvar file_app_dns_fakedns_fakedns_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_app_dns_fakedns_fakedns_proto_goTypes = []any{\n\t(*FakeDnsPool)(nil),      // 0: v2ray.core.app.dns.fakedns.FakeDnsPool\n\t(*FakeDnsPoolMulti)(nil), // 1: v2ray.core.app.dns.fakedns.FakeDnsPoolMulti\n}\nvar file_app_dns_fakedns_fakedns_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.dns.fakedns.FakeDnsPoolMulti.pools:type_name -> v2ray.core.app.dns.fakedns.FakeDnsPool\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_dns_fakedns_fakedns_proto_init() }\nfunc file_app_dns_fakedns_fakedns_proto_init() {\n\tif File_app_dns_fakedns_fakedns_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: unsafe.Slice(unsafe.StringData(file_app_dns_fakedns_fakedns_proto_rawDesc), len(file_app_dns_fakedns_fakedns_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_dns_fakedns_fakedns_proto_goTypes,\n\t\tDependencyIndexes: file_app_dns_fakedns_fakedns_proto_depIdxs,\n\t\tMessageInfos:      file_app_dns_fakedns_fakedns_proto_msgTypes,\n\t}.Build()\n\tFile_app_dns_fakedns_fakedns_proto = out.File\n\tfile_app_dns_fakedns_fakedns_proto_goTypes = nil\n\tfile_app_dns_fakedns_fakedns_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/dns/fakedns/fakedns.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.dns.fakedns;\noption csharp_namespace = \"V2Ray.Core.App.Dns.Fakedns\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\";\noption java_package = \"com.v2ray.core.app.dns.fakedns\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage FakeDnsPool{\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"fakeDns\";\n\n  string ip_pool = 1; //CIDR of IP pool used as fake DNS IP\n  int64  lruSize = 2; //Size of Pool for remembering relationship between domain name and IP address\n}\n\nmessage FakeDnsPoolMulti{\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"fakeDnsMulti\";\n\n  repeated FakeDnsPool pools = 1;\n}"
  },
  {
    "path": "app/dns/fakedns/fakedns_test.go",
    "content": "package fakedns\n\nimport (\n\tgonet \"net\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\nfunc TestNewFakeDnsHolder(_ *testing.T) {\n\t_, err := NewFakeDNSHolder()\n\tcommon.Must(err)\n}\n\nfunc TestFakeDnsHolderCreateMapping(t *testing.T) {\n\tfkdns, err := NewFakeDNSHolder()\n\tcommon.Must(err)\n\n\taddr := fkdns.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\tassert.Equal(t, \"198.18.0.0\", addr[0].IP().String())\n}\n\nfunc TestFakeDnsHolderCreateMappingMany(t *testing.T) {\n\tfkdns, err := NewFakeDNSHolder()\n\tcommon.Must(err)\n\n\taddr := fkdns.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\tassert.Equal(t, \"198.18.0.0\", addr[0].IP().String())\n\n\taddr2 := fkdns.GetFakeIPForDomain(\"fakednstest2.v2fly.org\")\n\tassert.Equal(t, \"198.18.0.1\", addr2[0].IP().String())\n}\n\nfunc TestFakeDnsHolderCreateMappingManyAndResolve(t *testing.T) {\n\tfkdns, err := NewFakeDNSHolder()\n\tcommon.Must(err)\n\n\t{\n\t\taddr := fkdns.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\t\tassert.Equal(t, \"198.18.0.0\", addr[0].IP().String())\n\t}\n\n\t{\n\t\taddr2 := fkdns.GetFakeIPForDomain(\"fakednstest2.v2fly.org\")\n\t\tassert.Equal(t, \"198.18.0.1\", addr2[0].IP().String())\n\t}\n\n\t{\n\t\tresult := fkdns.GetDomainFromFakeDNS(net.ParseAddress(\"198.18.0.0\"))\n\t\tassert.Equal(t, \"fakednstest.v2fly.org\", result)\n\t}\n\n\t{\n\t\tresult := fkdns.GetDomainFromFakeDNS(net.ParseAddress(\"198.18.0.1\"))\n\t\tassert.Equal(t, \"fakednstest2.v2fly.org\", result)\n\t}\n}\n\nfunc TestFakeDnsHolderCreateMappingManySingleDomain(t *testing.T) {\n\tfkdns, err := NewFakeDNSHolder()\n\tcommon.Must(err)\n\n\taddr := fkdns.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\tassert.Equal(t, \"198.18.0.0\", addr[0].IP().String())\n\n\taddr2 := fkdns.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\tassert.Equal(t, \"198.18.0.0\", addr2[0].IP().String())\n}\n\nfunc TestGetFakeIPForDomainConcurrently(t *testing.T) {\n\tfkdns, err := NewFakeDNSHolder()\n\tcommon.Must(err)\n\n\ttotal := 200\n\taddr := make([][]net.Address, total+1)\n\tvar errg errgroup.Group\n\tfor i := 0; i < total; i++ {\n\t\terrg.Go(testGetFakeIP(i, addr, fkdns))\n\t}\n\terrg.Wait()\n\tfor i := 0; i < total; i++ {\n\t\tfor j := i + 1; j < total; j++ {\n\t\t\tassert.NotEqual(t, addr[i][0].IP().String(), addr[j][0].IP().String())\n\t\t}\n\t}\n}\n\nfunc testGetFakeIP(index int, addr [][]net.Address, fkdns *Holder) func() error {\n\treturn func() error {\n\t\taddr[index] = fkdns.GetFakeIPForDomain(\"fakednstest\" + strconv.Itoa(index) + \".example.com\")\n\t\treturn nil\n\t}\n}\n\nfunc TestFakeDnsHolderCreateMappingAndRollOver(t *testing.T) {\n\tfkdns, err := NewFakeDNSHolderConfigOnly(&FakeDnsPool{\n\t\tIpPool:  \"240.0.0.0/12\",\n\t\tLruSize: 256,\n\t})\n\tcommon.Must(err)\n\n\terr = fkdns.Start()\n\n\tcommon.Must(err)\n\n\t{\n\t\taddr := fkdns.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\t\tassert.Equal(t, \"240.0.0.0\", addr[0].IP().String())\n\t}\n\n\t{\n\t\taddr2 := fkdns.GetFakeIPForDomain(\"fakednstest2.v2fly.org\")\n\t\tassert.Equal(t, \"240.0.0.1\", addr2[0].IP().String())\n\t}\n\n\tfor i := 0; i <= 8192; i++ {\n\t\t{\n\t\t\tresult := fkdns.GetDomainFromFakeDNS(net.ParseAddress(\"240.0.0.0\"))\n\t\t\tassert.Equal(t, \"fakednstest.v2fly.org\", result)\n\t\t}\n\n\t\t{\n\t\t\tresult := fkdns.GetDomainFromFakeDNS(net.ParseAddress(\"240.0.0.1\"))\n\t\t\tassert.Equal(t, \"fakednstest2.v2fly.org\", result)\n\t\t}\n\n\t\t{\n\t\t\tuuid := uuid.New()\n\t\t\tdomain := uuid.String() + \".fakednstest.v2fly.org\"\n\t\t\taddr := fkdns.GetFakeIPForDomain(domain)\n\t\t\trsaddr := addr[0].IP().String()\n\n\t\t\tresult := fkdns.GetDomainFromFakeDNS(net.ParseAddress(rsaddr))\n\t\t\tassert.Equal(t, domain, result)\n\t\t}\n\t}\n}\n\nfunc TestFakeDNSMulti(t *testing.T) {\n\tfakeMulti, err := NewFakeDNSHolderMulti(&FakeDnsPoolMulti{\n\t\tPools: []*FakeDnsPool{{\n\t\t\tIpPool:  \"240.0.0.0/12\",\n\t\t\tLruSize: 256,\n\t\t}, {\n\t\t\tIpPool:  \"fddd:c5b4:ff5f:f4f0::/64\",\n\t\t\tLruSize: 256,\n\t\t}},\n\t},\n\t)\n\tcommon.Must(err)\n\n\terr = fakeMulti.Start()\n\n\tcommon.Must(err)\n\n\tassert.Nil(t, err, \"Should not throw error\")\n\t_ = fakeMulti\n\n\tt.Run(\"checkInRange\", func(t *testing.T) {\n\t\tt.Run(\"ipv4\", func(t *testing.T) {\n\t\t\tinPool := fakeMulti.IsIPInIPPool(net.IPAddress([]byte{240, 0, 0, 5}))\n\t\t\tassert.True(t, inPool)\n\t\t})\n\t\tt.Run(\"ipv6\", func(t *testing.T) {\n\t\t\tip, err := gonet.ResolveIPAddr(\"ip\", \"fddd:c5b4:ff5f:f4f0::5\")\n\t\t\tassert.Nil(t, err)\n\t\t\tinPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))\n\t\t\tassert.True(t, inPool)\n\t\t})\n\t\tt.Run(\"ipv4_inverse\", func(t *testing.T) {\n\t\t\tinPool := fakeMulti.IsIPInIPPool(net.IPAddress([]byte{241, 0, 0, 5}))\n\t\t\tassert.False(t, inPool)\n\t\t})\n\t\tt.Run(\"ipv6_inverse\", func(t *testing.T) {\n\t\t\tip, err := gonet.ResolveIPAddr(\"ip\", \"fcdd:c5b4:ff5f:f4f0::5\")\n\t\t\tassert.Nil(t, err)\n\t\t\tinPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))\n\t\t\tassert.False(t, inPool)\n\t\t})\n\t})\n\n\tt.Run(\"allocateTwoAddressForTwoPool\", func(t *testing.T) {\n\t\taddress := fakeMulti.GetFakeIPForDomain(\"fakednstest.v2fly.org\")\n\t\tassert.Len(t, address, 2, \"should be 2 address one for each pool\")\n\t\tt.Run(\"eachOfThemShouldResolve:0\", func(t *testing.T) {\n\t\t\tdomain := fakeMulti.GetDomainFromFakeDNS(address[0])\n\t\t\tassert.Equal(t, \"fakednstest.v2fly.org\", domain)\n\t\t})\n\t\tt.Run(\"eachOfThemShouldResolve:1\", func(t *testing.T) {\n\t\t\tdomain := fakeMulti.GetDomainFromFakeDNS(address[1])\n\t\t\tassert.Equal(t, \"fakednstest.v2fly.org\", domain)\n\t\t})\n\t})\n\n\tt.Run(\"understandIPTypeSelector\", func(t *testing.T) {\n\t\tt.Run(\"ipv4\", func(t *testing.T) {\n\t\t\taddress := fakeMulti.GetFakeIPForDomain3(\"fakednstestipv4.v2fly.org\", true, false)\n\t\t\tassert.Len(t, address, 1, \"should be 1 address\")\n\t\t\tassert.True(t, address[0].Family().IsIPv4())\n\t\t})\n\t\tt.Run(\"ipv6\", func(t *testing.T) {\n\t\t\taddress := fakeMulti.GetFakeIPForDomain3(\"fakednstestipv6.v2fly.org\", false, true)\n\t\t\tassert.Len(t, address, 1, \"should be 1 address\")\n\t\t\tassert.True(t, address[0].Family().IsIPv6())\n\t\t})\n\t\tt.Run(\"ipv46\", func(t *testing.T) {\n\t\t\taddress := fakeMulti.GetFakeIPForDomain3(\"fakednstestipv46.v2fly.org\", true, true)\n\t\t\tassert.Len(t, address, 2, \"should be 2 address\")\n\t\t\tassert.True(t, address[0].Family().IsIPv4())\n\t\t\tassert.True(t, address[1].Family().IsIPv6())\n\t\t})\n\t})\n}\n\nfunc TestFakeDNSMultiAddPool(t *testing.T) {\n\trunTest := func(runTestBeforeStart bool) {\n\t\tfakeMulti, err := NewFakeDNSHolderMulti(&FakeDnsPoolMulti{\n\t\t\tPools: []*FakeDnsPool{{\n\t\t\t\tIpPool:  \"240.0.0.0/12\",\n\t\t\t\tLruSize: 256,\n\t\t\t}, {\n\t\t\t\tIpPool:  \"fddd:c5b4:ff5f:f4f0::/64\",\n\t\t\t\tLruSize: 256,\n\t\t\t}},\n\t\t})\n\t\tcommon.Must(err)\n\t\tif !runTestBeforeStart {\n\t\t\terr = fakeMulti.Start()\n\t\t\tcommon.Must(err)\n\t\t}\n\t\tt.Run(\"ipv4_return_existing\", func(t *testing.T) {\n\t\t\tpool, err := fakeMulti.AddPool(&FakeDnsPool{\n\t\t\t\tIpPool:  \"240.0.0.1/12\",\n\t\t\t\tLruSize: 256,\n\t\t\t})\n\t\t\tcommon.Must(err)\n\t\t\tif pool != fakeMulti.holders[0] {\n\t\t\t\tt.Error(\"HolderMulti.AddPool not returning same holder for existing IPv4 pool\")\n\t\t\t}\n\t\t})\n\t\tt.Run(\"ipv6_return_existing\", func(t *testing.T) {\n\t\t\tpool, err := fakeMulti.AddPool(&FakeDnsPool{\n\t\t\t\tIpPool:  \"fddd:c5b4:ff5f:f4f0::1/64\",\n\t\t\t\tLruSize: 256,\n\t\t\t})\n\t\t\tcommon.Must(err)\n\t\t\tif pool != fakeMulti.holders[1] {\n\t\t\t\tt.Error(\"HolderMulti.AddPool not returning same holder for existing IPv6 pool\")\n\t\t\t}\n\t\t})\n\t\tt.Run(\"ipv4_reject_overlap\", func(t *testing.T) {\n\t\t\t_, err := fakeMulti.AddPool(&FakeDnsPool{\n\t\t\t\tIpPool:  \"240.8.0.0/13\",\n\t\t\t\tLruSize: 256,\n\t\t\t})\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"HolderMulti.AddPool not rejecting IPv4 pool that is subnet of existing ones\")\n\t\t\t}\n\t\t\t_, err = fakeMulti.AddPool(&FakeDnsPool{\n\t\t\t\tIpPool:  \"240.0.0.0/11\",\n\t\t\t\tLruSize: 256,\n\t\t\t})\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"HolderMulti.AddPool not rejecting IPv4 pool that contains existing ones\")\n\t\t\t}\n\t\t})\n\t\tt.Run(\"new_pool\", func(t *testing.T) {\n\t\t\tpool, err := fakeMulti.AddPool(&FakeDnsPool{\n\t\t\t\tIpPool:  \"192.168.168.0/16\",\n\t\t\t\tLruSize: 256,\n\t\t\t})\n\t\t\tcommon.Must(err)\n\t\t\tif pool != fakeMulti.holders[2] {\n\t\t\t\tt.Error(\"HolderMulti.AddPool not creating new holder for new IPv4 pool\")\n\t\t\t}\n\t\t})\n\t\tt.Run(\"add_pool_multi\", func(t *testing.T) {\n\t\t\tpools, err := fakeMulti.AddPoolMulti(&FakeDnsPoolMulti{\n\t\t\t\tPools: []*FakeDnsPool{{\n\t\t\t\t\tIpPool:  \"192.168.168.0/16\",\n\t\t\t\t\tLruSize: 256,\n\t\t\t\t}, {\n\t\t\t\t\tIpPool:  \"2001:1111::/64\",\n\t\t\t\t\tLruSize: 256,\n\t\t\t\t}},\n\t\t\t})\n\t\t\tcommon.Must(err)\n\t\t\tif len(pools.holders) != 2 {\n\t\t\t\tt.Error(\"HolderMulti.AddPoolMutli not returning holderMulti that has the same length as passed PoolMulti config\")\n\t\t\t}\n\t\t\tif pools.holders[0] != fakeMulti.holders[2] {\n\t\t\t\tt.Error(\"HolderMulti.AddPoolMulti not returning same holder for existing IPv4 pool 192.168.168.0/16\")\n\t\t\t}\n\t\t\tif pools.holders[1] != fakeMulti.holders[3] {\n\t\t\t\tt.Error(\"HolderMulti.AddPoolMulti not creating new holder for new IPv6 pool 2001:1111::/64\")\n\t\t\t}\n\t\t})\n\t\tif runTestBeforeStart {\n\t\t\terr = fakeMulti.Start()\n\t\t\tcommon.Must(err)\n\t\t}\n\t}\n\tt.Run(\"addPoolBeforeStart\", func(t *testing.T) {\n\t\trunTest(true)\n\t})\n\tt.Run(\"addPoolAfterStart\", func(t *testing.T) {\n\t\trunTest(false)\n\t})\n}\n"
  },
  {
    "path": "app/dns/fakedns.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\tfakedns \"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\n// FakeDNSClient is an implementation of dns.Client with FakeDNS enabled.\ntype FakeDNSClient struct {\n\t*DNS\n}\n\n// LookupIP implements dns.Client.\nfunc (s *FakeDNSClient) LookupIP(domain string) ([]net.IP, error) {\n\treturn s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, IPv6Enable: true, FakeEnable: true})\n}\n\n// LookupIPv4 implements dns.IPv4Lookup.\nfunc (s *FakeDNSClient) LookupIPv4(domain string) ([]net.IP, error) {\n\treturn s.lookupIPInternal(domain, dns.IPOption{IPv4Enable: true, FakeEnable: true})\n}\n\n// LookupIPv6 implements dns.IPv6Lookup.\nfunc (s *FakeDNSClient) LookupIPv6(domain string) ([]net.IP, error) {\n\treturn s.lookupIPInternal(domain, dns.IPOption{IPv6Enable: true, FakeEnable: true})\n}\n\n// FakeDNSEngine is an implementation of dns.FakeDNSEngine based on a fully functional DNS.\ntype FakeDNSEngine struct {\n\tdns         *DNS\n\tfakeHolders *fakedns.HolderMulti\n\tfakeDefault *fakedns.HolderMulti\n}\n\n// Type implements common.HasType.\nfunc (*FakeDNSEngine) Type() interface{} {\n\treturn dns.FakeDNSEngineType()\n}\n\n// Start implements common.Runnable.\nfunc (f *FakeDNSEngine) Start() error {\n\treturn f.fakeHolders.Start()\n}\n\n// Close implements common.Closable.\nfunc (f *FakeDNSEngine) Close() error {\n\treturn f.fakeHolders.Close()\n}\n\n// GetFakeIPForDomain implements dns.FakeDNSEngine.\nfunc (f *FakeDNSEngine) GetFakeIPForDomain(domain string) []net.Address {\n\treturn f.GetFakeIPForDomain3(domain, true, true)\n}\n\n// GetDomainFromFakeDNS implements dns.FakeDNSEngine.\nfunc (f *FakeDNSEngine) GetDomainFromFakeDNS(ip net.Address) string {\n\treturn f.fakeHolders.GetDomainFromFakeDNS(ip)\n}\n\n// IsIPInIPPool implements dns.FakeDNSEngineRev0.\nfunc (f *FakeDNSEngine) IsIPInIPPool(ip net.Address) bool {\n\treturn f.fakeHolders.IsIPInIPPool(ip)\n}\n\n// GetFakeIPForDomain3 implements dns.FakeDNSEngineRev0.\nfunc (f *FakeDNSEngine) GetFakeIPForDomain3(domain string, IPv4 bool, IPv6 bool) []net.Address { // nolint: gocritic\n\toption := dns.IPOption{IPv4Enable: IPv4, IPv6Enable: IPv6, FakeEnable: true}\n\tfor _, client := range f.dns.sortClients(domain, option) {\n\t\tfakeServer, ok := client.fakeDNS.(*FakeDNSServer)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tfakeEngine, ok := fakeServer.fakeDNSEngine.(dns.FakeDNSEngineRev0)\n\t\tif !ok {\n\t\t\treturn filterIP(fakeServer.fakeDNSEngine.GetFakeIPForDomain(domain), option)\n\t\t}\n\t\treturn fakeEngine.GetFakeIPForDomain3(domain, IPv4, IPv6)\n\t}\n\tif f.fakeDefault != nil {\n\t\treturn f.fakeDefault.GetFakeIPForDomain3(domain, IPv4, IPv6)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "app/dns/fakedns_test.go",
    "content": "package dns_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/miekg/dns\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\tfeature_dns \"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\nfunc TestFakeDNS(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServer: []*NameServer{\n\t\t\t\t\t{ // \"fakedns\"\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Domain{\n\t\t\t\t\t\t\t\t\tDomain: \"fakedns\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tPort: uint32(53),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{ // { \"address\": \"127.0.0.1\", \"port\": \"<port>\", \"domains\": [\"domain:google.com\"], \"fakedns\": \"198.19.0.0/16\", \"fallbackStrategy\": \"disabled\" }\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{Type: DomainMatchingType_Subdomain, Domain: \"google.com\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tFakeDns: &fakedns.FakeDnsPoolMulti{\n\t\t\t\t\t\t\tPools: []*fakedns.FakeDnsPool{\n\t\t\t\t\t\t\t\t{IpPool: \"198.19.0.0/16\", LruSize: 256},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tFallbackStrategy: FallbackStrategy_Disabled.Enum(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tFakeDns: &fakedns.FakeDnsPoolMulti{ // \"fakedns\": \"198.18.0.0/16\"\n\t\t\t\t\tPools: []*fakedns.FakeDnsPool{\n\t\t\t\t\t\t{IpPool: \"198.18.0.0/16\", LruSize: 256},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\tcommon.Must(v.Start())\n\n\tdnsClient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\tfakeClient := dnsClient.(feature_dns.ClientWithFakeDNS).AsFakeDNSClient()\n\n\tvar fakeIPForFacebook net.IP\n\tvar fakeIPForGoogle net.IP\n\n\t{ // Lookup facebook.com with Fake Client will return 198.18.0.0/16 (global fake pool)\n\t\tips, err := fakeClient.LookupIP(\"facebook.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\t\tfor _, ip := range ips {\n\t\t\tif !(&net.IPNet{IP: net.IP{198, 18, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip) {\n\t\t\t\tt.Fatal(\"Lookup facebook.com with fake client not in global pool 198.18.0.0/16\")\n\t\t\t}\n\t\t}\n\t\tfakeIPForFacebook = ips[0]\n\t}\n\t{ // Lookup facebook.com with Normal Client with return empty record (because UDP server matching \"domain:google.com\" are configured with fallback disabled)\n\t\t_, err := dnsClient.LookupIP(\"facebook.com\")\n\t\tif err != feature_dns.ErrEmptyResponse {\n\t\t\tt.Fatal(\"Lookup facebook.com with normal client not returning empty response\")\n\t\t}\n\t}\n\t{ // Lookup google.com with Fake Client will return 198.19.0.0/16 (local fake pool)\n\t\tips, err := fakeClient.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\t\tfor _, ip := range ips {\n\t\t\tif !(&net.IPNet{IP: net.IP{198, 19, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip) {\n\t\t\t\tt.Fatal(\"Lookup google.com with fake client not in global pool 198.19.0.0/16\")\n\t\t\t}\n\t\t}\n\t\tfakeIPForGoogle = ips[0]\n\t}\n\t{ // Lookup google.com with Normal Client will return 8.8.8.8\n\t\tips, err := dnsClient.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\t\tif r := cmp.Diff(ips, []net.IP{{8, 8, 8, 8}}); r != \"\" {\n\t\t\tt.Fatal(\"Lookup google.com with normal client not returning 8.8.8.8\")\n\t\t}\n\t}\n\n\tfakeEngine := dnsClient.(feature_dns.ClientWithFakeDNS).AsFakeDNSEngine().(feature_dns.FakeDNSEngineRev0)\n\t{\n\t\tif !fakeEngine.IsIPInIPPool(net.IPAddress(fakeIPForFacebook)) {\n\t\t\tt.Fatal(\"Fake IP of domain facebook.com not in FakeDNSEngine's pool.\")\n\t\t}\n\t\tif !fakeEngine.IsIPInIPPool(net.IPAddress(fakeIPForGoogle)) {\n\t\t\tt.Fatal(\"Fake IP of domain google.com not in FakeDNSEngine's pool.\")\n\t\t}\n\t}\n\t{\n\t\tif domain := fakeEngine.GetDomainFromFakeDNS(net.IPAddress(fakeIPForFacebook)); domain != \"facebook.com\" {\n\t\t\tt.Fatal(\"Recover fake IP to get domain facebook.com failed.\")\n\t\t}\n\t\tif domain := fakeEngine.GetDomainFromFakeDNS(net.IPAddress(fakeIPForGoogle)); domain != \"google.com\" {\n\t\t\tt.Fatal(\"Recover fake IP to get domain google.com failed.\")\n\t\t}\n\t}\n\t{\n\t\tips := fakeEngine.GetFakeIPForDomain(\"api.google.com\")\n\t\tfor _, ip := range ips {\n\t\t\tif !(&net.IPNet{IP: net.IP{198, 19, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip.IP()) {\n\t\t\t\tt.Fatal(\"Fake IP for api.google.com not in local pool 198.19.0.0/16\")\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tips := fakeEngine.GetFakeIPForDomain3(\"v2fly.org\", true, false)\n\t\tfor _, ip := range ips {\n\t\t\tif !(&net.IPNet{IP: net.IP{198, 18, 0, 0}, Mask: net.CIDRMask(16, 8*net.IPv4len)}).Contains(ip.IP()) {\n\t\t\t\tt.Fatal(\"Fake IP for v2fly.org not in global pool 198.18.0.0/16\")\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestFakeDNSEmptyGlobalConfig(t *testing.T) {\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&Config{\n\t\t\t\tNameServer: []*NameServer{\n\t\t\t\t\t{ // \"fakedns\"\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Domain{\n\t\t\t\t\t\t\t\t\tDomain: \"fakedns\",\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\tQueryStrategy: QueryStrategy_USE_IP4.Enum(),\n\t\t\t\t\t},\n\t\t\t\t\t{ // \"localhost\"\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Domain{\n\t\t\t\t\t\t\t\t\tDomain: \"localhost\",\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\tQueryStrategy: QueryStrategy_USE_IP6.Enum(),\n\t\t\t\t\t\tPrioritizedDomain: []*NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{Type: DomainMatchingType_Subdomain, Domain: \"google.com\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tFakeDns: &fakedns.FakeDnsPoolMulti{Pools: []*fakedns.FakeDnsPool{}}, // \"fakedns\": true\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\tcommon.Must(v.Start())\n\n\tdnsClient := v.GetFeature(feature_dns.ClientType()).(feature_dns.Client)\n\tfakeClient := dnsClient.(feature_dns.ClientWithFakeDNS).AsFakeDNSClient()\n\n\t{ // Lookup facebook.com will return 198.18.0.0/15 (default IPv4 pool)\n\t\tips, err := fakeClient.LookupIP(\"facebook.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\t\tfor _, ip := range ips {\n\t\t\tif !(&net.IPNet{IP: net.IP{198, 18, 0, 0}, Mask: net.CIDRMask(15, 8*net.IPv4len)}).Contains(ip) {\n\t\t\t\tt.Fatal(\"Lookup facebook.com with fake client not in default IPv4 pool 198.18.0.0/15\")\n\t\t\t}\n\t\t}\n\t}\n\t{ // Lookup google.com will return fc00::/18 (default IPv6 pool)\n\t\tips, err := fakeClient.LookupIP(\"google.com\")\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\t\tfor _, ip := range ips {\n\t\t\tif !(&net.IPNet{IP: net.IP{0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Mask: net.CIDRMask(18, 8*net.IPv6len)}).Contains(ip) {\n\t\t\t\tt.Fatal(\"Lookup google.com with fake client not in default IPv6 pool fc00::/18\")\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/dns/hosts.go",
    "content": "package dns\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\n// StaticHosts represents static domain-ip mapping in DNS server.\ntype StaticHosts struct {\n\tips      [][]net.Address\n\tmatchers *strmatcher.LinearIndexMatcher\n}\n\n// NewStaticHosts creates a new StaticHosts instance.\nfunc NewStaticHosts(hosts []*HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) {\n\tg := new(strmatcher.LinearIndexMatcher)\n\tsh := &StaticHosts{\n\t\tips:      make([][]net.Address, len(hosts)+len(legacy)+16),\n\t\tmatchers: g,\n\t}\n\n\tif legacy != nil {\n\t\tfeatures.PrintDeprecatedFeatureWarning(\"simple host mapping\")\n\n\t\tfor domain, ip := range legacy {\n\t\t\tmatcher, err := strmatcher.Full.New(domain)\n\t\t\tcommon.Must(err)\n\t\t\tid := g.Add(matcher)\n\n\t\t\taddress := ip.AsAddress()\n\t\t\tif address.Family().IsDomain() {\n\t\t\t\treturn nil, newError(\"invalid domain address in static hosts: \", address.Domain()).AtWarning()\n\t\t\t}\n\n\t\t\tsh.ips[id] = []net.Address{address}\n\t\t}\n\t}\n\n\tfor _, mapping := range hosts {\n\t\tmatcher, err := toStrMatcher(mapping.Type, mapping.Domain)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create domain matcher\").Base(err)\n\t\t}\n\t\tid := g.Add(matcher)\n\t\tips := make([]net.Address, 0, len(mapping.Ip)+1)\n\t\tswitch {\n\t\tcase len(mapping.ProxiedDomain) > 0:\n\t\t\tips = append(ips, net.DomainAddress(mapping.ProxiedDomain))\n\t\tcase len(mapping.Ip) > 0:\n\t\t\tfor _, ip := range mapping.Ip {\n\t\t\t\taddr := net.IPAddress(ip)\n\t\t\t\tif addr == nil {\n\t\t\t\t\treturn nil, newError(\"invalid IP address in static hosts: \", ip).AtWarning()\n\t\t\t\t}\n\t\t\t\tips = append(ips, addr)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, newError(\"neither IP address nor proxied domain specified for domain: \", mapping.Domain).AtWarning()\n\t\t}\n\n\t\tsh.ips[id] = ips\n\t}\n\n\treturn sh, nil\n}\n\nfunc (h *StaticHosts) lookupInternal(domain string) []net.Address {\n\tvar ips []net.Address\n\tfor _, id := range h.matchers.Match(domain) {\n\t\tips = append(ips, h.ips[id]...)\n\t}\n\treturn ips\n}\n\nfunc (h *StaticHosts) lookup(domain string, option dns.IPOption, maxDepth int) []net.Address {\n\tswitch addrs := h.lookupInternal(domain); {\n\tcase len(addrs) == 0: // Not recorded in static hosts, return nil\n\t\treturn nil\n\tcase len(addrs) == 1 && addrs[0].Family().IsDomain(): // Try to unwrap domain\n\t\tnewError(\"found replaced domain: \", domain, \" -> \", addrs[0].Domain(), \". Try to unwrap it\").AtDebug().WriteToLog()\n\t\tif maxDepth > 0 {\n\t\t\tunwrapped := h.lookup(addrs[0].Domain(), option, maxDepth-1)\n\t\t\tif unwrapped != nil {\n\t\t\t\treturn unwrapped\n\t\t\t}\n\t\t}\n\t\treturn addrs\n\tdefault: // IP record found, return a non-nil IP array\n\t\treturn filterIP(addrs, option)\n\t}\n}\n\n// Lookup returns IP addresses or proxied domain for the given domain, if exists in this StaticHosts.\nfunc (h *StaticHosts) Lookup(domain string, option dns.IPOption) []net.Address {\n\treturn h.lookup(domain, option, 5)\n}\n"
  },
  {
    "path": "app/dns/hosts_test.go",
    "content": "package dns_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nfunc TestStaticHosts(t *testing.T) {\n\tpb := []*HostMapping{\n\t\t{\n\t\t\tType:   DomainMatchingType_Full,\n\t\t\tDomain: \"v2fly.org\",\n\t\t\tIp: [][]byte{\n\t\t\t\t{1, 1, 1, 1},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tType:   DomainMatchingType_Full,\n\t\t\tDomain: \"proxy.v2fly.org\",\n\t\t\tIp: [][]byte{\n\t\t\t\t{1, 2, 3, 4},\n\t\t\t\t{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\t},\n\t\t\tProxiedDomain: \"another-proxy.v2fly.org\",\n\t\t},\n\t\t{\n\t\t\tType:          DomainMatchingType_Full,\n\t\t\tDomain:        \"proxy2.v2fly.org\",\n\t\t\tProxiedDomain: \"proxy.v2fly.org\",\n\t\t},\n\t\t{\n\t\t\tType:   DomainMatchingType_Subdomain,\n\t\t\tDomain: \"v2ray.cn\",\n\t\t\tIp: [][]byte{\n\t\t\t\t{2, 2, 2, 2},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tType:   DomainMatchingType_Subdomain,\n\t\t\tDomain: \"baidu.com\",\n\t\t\tIp: [][]byte{\n\t\t\t\t{127, 0, 0, 1},\n\t\t\t\t{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\t},\n\t\t},\n\t}\n\n\thosts, err := NewStaticHosts(pb, nil)\n\tcommon.Must(err)\n\n\t{\n\t\tips := hosts.Lookup(\"v2fly.org\", dns.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: true,\n\t\t})\n\t\tif len(ips) != 1 {\n\t\t\tt.Error(\"expect 1 IP, but got \", len(ips))\n\t\t}\n\t\tif diff := cmp.Diff([]byte(ips[0].IP()), []byte{1, 1, 1, 1}); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n\n\t{\n\t\tdomain := hosts.Lookup(\"proxy.v2fly.org\", dns.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: false,\n\t\t})\n\t\tif len(domain) != 1 {\n\t\t\tt.Error(\"expect 1 domain, but got \", len(domain))\n\t\t}\n\t\tif diff := cmp.Diff(domain[0].Domain(), \"another-proxy.v2fly.org\"); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n\n\t{\n\t\tdomain := hosts.Lookup(\"proxy2.v2fly.org\", dns.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: false,\n\t\t})\n\t\tif len(domain) != 1 {\n\t\t\tt.Error(\"expect 1 domain, but got \", len(domain))\n\t\t}\n\t\tif diff := cmp.Diff(domain[0].Domain(), \"another-proxy.v2fly.org\"); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n\n\t{\n\t\tips := hosts.Lookup(\"www.v2ray.cn\", dns.IPOption{\n\t\t\tIPv4Enable: true,\n\t\t\tIPv6Enable: true,\n\t\t})\n\t\tif len(ips) != 1 {\n\t\t\tt.Error(\"expect 1 IP, but got \", len(ips))\n\t\t}\n\t\tif diff := cmp.Diff([]byte(ips[0].IP()), []byte{2, 2, 2, 2}); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n\n\t{\n\t\tips := hosts.Lookup(\"baidu.com\", dns.IPOption{\n\t\t\tIPv4Enable: false,\n\t\t\tIPv6Enable: true,\n\t\t})\n\t\tif len(ips) != 1 {\n\t\t\tt.Error(\"expect 1 IP, but got \", len(ips))\n\t\t}\n\t\tif diff := cmp.Diff([]byte(ips[0].IP()), []byte(net.LocalHostIPv6.IP())); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver.go",
    "content": "package dns\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\n// Server is the interface for Name Server.\ntype Server interface {\n\t// Name of the Client.\n\tName() string\n\t// QueryIP sends IP queries to its configured server.\n\tQueryIP(ctx context.Context, domain string, clientIP net.IP, option dns.IPOption, disableCache bool) ([]net.IP, error)\n}\n\n// Client is the interface for DNS client.\ntype Client struct {\n\tserver   Server\n\tclientIP net.IP\n\ttag      string\n\n\tqueryStrategy    dns.IPOption\n\tcacheStrategy    CacheStrategy\n\tfallbackStrategy FallbackStrategy\n\n\tdomains   []string\n\texpectIPs []*router.GeoIPMatcher\n\tfakeDNS   Server\n}\n\nvar errExpectedIPNonMatch = errors.New(\"expectIPs not match\")\n\n// NewServer creates a name server object according to the network destination url.\nfunc NewServer(ctx context.Context, dest net.Destination, onCreated func(Server) error) error {\n\tonCreatedWithError := func(server Server, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn onCreated(server)\n\t}\n\tif address := dest.Address; address.Family().IsDomain() {\n\t\tu, err := url.Parse(address.Domain())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tswitch {\n\t\tcase strings.EqualFold(u.String(), \"localhost\"):\n\t\t\treturn onCreated(NewLocalNameServer())\n\t\tcase strings.EqualFold(u.String(), \"fakedns\"):\n\t\t\treturn core.RequireFeatures(ctx, func(fakedns dns.FakeDNSEngine) error { return onCreated(NewFakeDNSServer(fakedns)) })\n\t\tcase strings.EqualFold(u.Scheme, \"https\"): // DOH Remote mode\n\t\t\treturn core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { return onCreatedWithError(NewDoHNameServer(u, dispatcher)) })\n\t\tcase strings.EqualFold(u.Scheme, \"https+local\"): // DOH Local mode\n\t\t\treturn onCreated(NewDoHLocalNameServer(u))\n\t\tcase strings.EqualFold(u.Scheme, \"tcp\"): // DNS-over-TCP Remote mode\n\t\t\treturn core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { return onCreatedWithError(NewTCPNameServer(u, dispatcher)) })\n\t\tcase strings.EqualFold(u.Scheme, \"tcp+local\"): // DNS-over-TCP Local mode\n\t\t\treturn onCreatedWithError(NewTCPLocalNameServer(u))\n\t\tcase strings.EqualFold(u.Scheme, \"quic+local\"): // DNS-over-QUIC Local mode\n\t\t\treturn onCreatedWithError(NewQUICNameServer(u))\n\t\t}\n\t}\n\tif dest.Network == net.Network_Unknown {\n\t\tdest.Network = net.Network_UDP\n\t}\n\tif dest.Network == net.Network_UDP { // UDP classic DNS mode\n\t\treturn core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error { return onCreated(NewClassicNameServer(dest, dispatcher)) })\n\t}\n\treturn newError(\"No available name server could be created from \", dest).AtWarning()\n}\n\n// NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.\nfunc NewClient(ctx context.Context, ns *NameServer, dns *Config) (*Client, error) {\n\tclient := &Client{}\n\n\t// Create DNS server instance\n\terr := NewServer(ctx, ns.Address.AsDestination(), func(server Server) error {\n\t\tclient.server = server\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Initialize fields with default values\n\tif len(ns.Tag) == 0 {\n\t\tns.Tag = dns.Tag\n\t\tif len(ns.Tag) == 0 {\n\t\t\tns.Tag = generateRandomTag()\n\t\t}\n\t}\n\tif len(ns.ClientIp) == 0 {\n\t\tns.ClientIp = dns.ClientIp\n\t}\n\tif ns.QueryStrategy == nil {\n\t\tns.QueryStrategy = &dns.QueryStrategy\n\t}\n\tif ns.CacheStrategy == nil {\n\t\tns.CacheStrategy = new(CacheStrategy)\n\t\tswitch {\n\t\tcase dns.CacheStrategy != CacheStrategy_CacheEnabled:\n\t\t\t*ns.CacheStrategy = dns.CacheStrategy\n\t\tcase dns.DisableCache:\n\t\t\tfeatures.PrintDeprecatedFeatureWarning(\"DNS disableCache settings\")\n\t\t\t*ns.CacheStrategy = CacheStrategy_CacheDisabled\n\t\t}\n\t}\n\tif ns.FallbackStrategy == nil {\n\t\tns.FallbackStrategy = new(FallbackStrategy)\n\t\tswitch {\n\t\tcase ns.SkipFallback:\n\t\t\tfeatures.PrintDeprecatedFeatureWarning(\"DNS server skipFallback settings\")\n\t\t\t*ns.FallbackStrategy = FallbackStrategy_Disabled\n\t\tcase dns.FallbackStrategy != FallbackStrategy_Enabled:\n\t\t\t*ns.FallbackStrategy = dns.FallbackStrategy\n\t\tcase dns.DisableFallback:\n\t\t\tfeatures.PrintDeprecatedFeatureWarning(\"DNS disableFallback settings\")\n\t\t\t*ns.FallbackStrategy = FallbackStrategy_Disabled\n\t\tcase dns.DisableFallbackIfMatch:\n\t\t\tfeatures.PrintDeprecatedFeatureWarning(\"DNS disableFallbackIfMatch settings\")\n\t\t\t*ns.FallbackStrategy = FallbackStrategy_DisabledIfAnyMatch\n\t\t}\n\t}\n\tif (ns.FakeDns != nil && len(ns.FakeDns.Pools) == 0) || // Use globally configured fake ip pool if: 1. `fakedns` config is set, but empty(represents { \"fakedns\": true } in JSON settings);\n\t\tns.FakeDns == nil && strings.EqualFold(ns.Address.Address.GetDomain(), \"fakedns\") { // 2. `fakedns` config not set, but server address is `fakedns`(represents { \"address\": \"fakedns\" } in JSON settings).\n\t\tif dns.FakeDns != nil {\n\t\t\tns.FakeDns = dns.FakeDns\n\t\t} else {\n\t\t\tns.FakeDns = &fakedns.FakeDnsPoolMulti{}\n\t\t\tqueryStrategy := toIPOption(*ns.QueryStrategy)\n\t\t\tif queryStrategy.IPv4Enable {\n\t\t\t\tns.FakeDns.Pools = append(ns.FakeDns.Pools, &fakedns.FakeDnsPool{\n\t\t\t\t\tIpPool:  \"198.18.0.0/15\",\n\t\t\t\t\tLruSize: 65535,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif queryStrategy.IPv6Enable {\n\t\t\t\tns.FakeDns.Pools = append(ns.FakeDns.Pools, &fakedns.FakeDnsPool{\n\t\t\t\t\tIpPool:  \"fc00::/18\",\n\t\t\t\t\tLruSize: 65535,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t// Priotize local domains with specific TLDs or without any dot to local DNS\n\tif strings.EqualFold(ns.Address.Address.GetDomain(), \"localhost\") {\n\t\tns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...)\n\t\tns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule)\n\t}\n\n\tif len(ns.ClientIp) > 0 {\n\t\tnewError(\"DNS: client \", ns.Address.Address.AsAddress(), \" uses clientIP \", net.IP(ns.ClientIp).String()).AtInfo().WriteToLog()\n\t}\n\n\tclient.clientIP = ns.ClientIp\n\tclient.tag = ns.Tag\n\tclient.queryStrategy = toIPOption(*ns.QueryStrategy)\n\tclient.cacheStrategy = *ns.CacheStrategy\n\tclient.fallbackStrategy = *ns.FallbackStrategy\n\treturn client, nil\n}\n\n// Name returns the server name the client manages.\nfunc (c *Client) Name() string {\n\treturn c.server.Name()\n}\n\n// QueryIP send DNS query to the name server with the client's IP and IP options.\nfunc (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption) ([]net.IP, error) {\n\tqueryOption := option.With(c.queryStrategy)\n\tif !queryOption.IsValid() {\n\t\tnewError(c.server.Name(), \" returns empty answer: \", domain, \". \", toReqTypes(option)).AtInfo().WriteToLog()\n\t\treturn nil, dns.ErrEmptyResponse\n\t}\n\tserver := c.server\n\tif queryOption.FakeEnable && c.fakeDNS != nil {\n\t\tserver = c.fakeDNS\n\t}\n\tdisableCache := c.cacheStrategy == CacheStrategy_CacheDisabled\n\n\tctx = session.ContextWithInbound(ctx, &session.Inbound{Tag: c.tag})\n\tctx, cancel := context.WithTimeout(ctx, 4*time.Second)\n\tips, err := server.QueryIP(ctx, domain, c.clientIP, queryOption, disableCache)\n\tcancel()\n\n\tif err != nil || queryOption.FakeEnable {\n\t\treturn ips, err\n\t}\n\treturn c.MatchExpectedIPs(domain, ips)\n}\n\n// MatchExpectedIPs matches queried domain IPs with expected IPs and returns matched ones.\nfunc (c *Client) MatchExpectedIPs(domain string, ips []net.IP) ([]net.IP, error) {\n\tif len(c.expectIPs) == 0 {\n\t\treturn ips, nil\n\t}\n\tnewIps := []net.IP{}\n\tfor _, ip := range ips {\n\t\tfor _, matcher := range c.expectIPs {\n\t\t\tif matcher.Match(ip) {\n\t\t\t\tnewIps = append(newIps, ip)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif len(newIps) == 0 {\n\t\treturn nil, errExpectedIPNonMatch\n\t}\n\tnewError(\"domain \", domain, \" expectIPs \", newIps, \" matched at server \", c.Name()).AtDebug().WriteToLog()\n\treturn newIps, nil\n}\n"
  },
  {
    "path": "app/dns/nameserver_doh.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/pubsub\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// DoHNameServer implemented DNS over HTTPS (RFC8484) Wire Format,\n// which is compatible with traditional dns over udp(RFC1035),\n// thus most of the DOH implementation is copied from udpns.go\ntype DoHNameServer struct {\n\tsync.RWMutex\n\tips        map[string]record\n\tpub        *pubsub.Service\n\tcleanup    *task.Periodic\n\thttpClient *http.Client\n\tdohURL     string\n\tname       string\n}\n\n// NewDoHNameServer creates DOH server object for remote resolving.\nfunc NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher) (*DoHNameServer, error) {\n\tnewError(\"DNS: created Remote DOH client for \", url.String()).AtInfo().WriteToLog()\n\ts := baseDOHNameServer(url, \"DOH\")\n\n\t// Dispatched connection will be closed (interrupted) after each request\n\t// This makes DOH inefficient without a keep-alived connection\n\t// See: core/app/proxyman/outbound/handler.go:113\n\t// Using mux (https request wrapped in a stream layer) improves the situation.\n\t// Recommend to use NewDoHLocalNameServer (DOHL:) if v2ray instance is running on\n\t//  a normal network eg. the server side of v2ray\n\ttr := &http.Transport{\n\t\tMaxIdleConns:        30,\n\t\tIdleConnTimeout:     90 * time.Second,\n\t\tTLSHandshakeTimeout: 30 * time.Second,\n\t\tForceAttemptHTTP2:   true,\n\t\tDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\t\tdest, err := net.ParseDestination(network + \":\" + addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlink, err := dispatcher.Dispatch(ctx, dest)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn net.NewConnection(\n\t\t\t\tnet.ConnectionInputMulti(link.Writer),\n\t\t\t\tnet.ConnectionOutputMulti(link.Reader),\n\t\t\t), nil\n\t\t},\n\t}\n\n\tdispatchedClient := &http.Client{\n\t\tTransport: tr,\n\t\tTimeout:   60 * time.Second,\n\t}\n\n\ts.httpClient = dispatchedClient\n\treturn s, nil\n}\n\n// NewDoHLocalNameServer creates DOH client object for local resolving\nfunc NewDoHLocalNameServer(url *url.URL) *DoHNameServer {\n\turl.Scheme = \"https\"\n\ts := baseDOHNameServer(url, \"DOHL\")\n\ttr := &http.Transport{\n\t\tIdleConnTimeout:   90 * time.Second,\n\t\tForceAttemptHTTP2: true,\n\t\tDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\t\tdest, err := net.ParseDestination(network + \":\" + addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconn, err := internet.DialSystem(ctx, dest, nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn conn, nil\n\t\t},\n\t}\n\ts.httpClient = &http.Client{\n\t\tTimeout:   time.Second * 180,\n\t\tTransport: tr,\n\t}\n\tnewError(\"DNS: created Local DOH client for \", url.String()).AtInfo().WriteToLog()\n\treturn s\n}\n\nfunc baseDOHNameServer(url *url.URL, prefix string) *DoHNameServer {\n\ts := &DoHNameServer{\n\t\tips:    make(map[string]record),\n\t\tpub:    pubsub.NewService(),\n\t\tname:   prefix + \"//\" + url.Host,\n\t\tdohURL: url.String(),\n\t}\n\ts.cleanup = &task.Periodic{\n\t\tInterval: time.Minute,\n\t\tExecute:  s.Cleanup,\n\t}\n\treturn s\n}\n\n// Name implements Server.\nfunc (s *DoHNameServer) Name() string {\n\treturn s.name\n}\n\n// Cleanup clears expired items from cache\nfunc (s *DoHNameServer) Cleanup() error {\n\tnow := time.Now()\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tif len(s.ips) == 0 {\n\t\treturn newError(\"nothing to do. stopping...\")\n\t}\n\n\tfor domain, record := range s.ips {\n\t\tif record.A != nil && record.A.Expire.Before(now) {\n\t\t\trecord.A = nil\n\t\t}\n\t\tif record.AAAA != nil && record.AAAA.Expire.Before(now) {\n\t\t\trecord.AAAA = nil\n\t\t}\n\n\t\tif record.A == nil && record.AAAA == nil {\n\t\t\tnewError(s.name, \" cleanup \", domain).AtDebug().WriteToLog()\n\t\t\tdelete(s.ips, domain)\n\t\t} else {\n\t\t\ts.ips[domain] = record\n\t\t}\n\t}\n\n\tif len(s.ips) == 0 {\n\t\ts.ips = make(map[string]record)\n\t}\n\n\treturn nil\n}\n\nfunc (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {\n\telapsed := time.Since(req.start)\n\n\ts.Lock()\n\trec := s.ips[req.domain]\n\tupdated := false\n\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\tif isNewer(rec.A, ipRec) {\n\t\t\trec.A = ipRec\n\t\t\tupdated = true\n\t\t}\n\tcase dnsmessage.TypeAAAA:\n\t\taddr := make([]net.Address, 0)\n\t\tfor _, ip := range ipRec.IP {\n\t\t\tif len(ip.IP()) == net.IPv6len {\n\t\t\t\taddr = append(addr, ip)\n\t\t\t}\n\t\t}\n\t\tipRec.IP = addr\n\t\tif isNewer(rec.AAAA, ipRec) {\n\t\t\trec.AAAA = ipRec\n\t\t\tupdated = true\n\t\t}\n\t}\n\tnewError(s.name, \" got answer: \", req.domain, \" \", req.reqType, \" -> \", ipRec.IP, \" \", elapsed).AtInfo().WriteToLog()\n\n\tif updated {\n\t\ts.ips[req.domain] = rec\n\t}\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\ts.pub.Publish(req.domain+\"4\", nil)\n\tcase dnsmessage.TypeAAAA:\n\t\ts.pub.Publish(req.domain+\"6\", nil)\n\t}\n\ts.Unlock()\n\tcommon.Must(s.cleanup.Start())\n}\n\nfunc (s *DoHNameServer) newReqID() uint16 {\n\treturn 0\n}\n\nfunc (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {\n\tnewError(s.name, \" querying: \", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))\n\n\treqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))\n\n\tvar deadline time.Time\n\tif d, ok := ctx.Deadline(); ok {\n\t\tdeadline = d\n\t} else {\n\t\tdeadline = time.Now().Add(time.Second * 5)\n\t}\n\n\tfor _, req := range reqs {\n\t\tgo func(r *dnsRequest) {\n\t\t\t// generate new context for each req, using same context\n\t\t\t// may cause reqs all aborted if any one encounter an error\n\t\t\tdnsCtx := ctx\n\n\t\t\t// reserve internal dns server requested Inbound\n\t\t\tif inbound := session.InboundFromContext(ctx); inbound != nil {\n\t\t\t\tdnsCtx = session.ContextWithInbound(dnsCtx, inbound)\n\t\t\t}\n\n\t\t\tdnsCtx = session.ContextWithContent(dnsCtx, &session.Content{\n\t\t\t\tProtocol:       \"tls\",\n\t\t\t\tSkipDNSResolve: true,\n\t\t\t})\n\n\t\t\t// forced to use mux for DOH\n\t\t\tdnsCtx = session.ContextWithMuxPrefered(dnsCtx, true)\n\n\t\t\tvar cancel context.CancelFunc\n\t\t\tdnsCtx, cancel = context.WithDeadline(dnsCtx, deadline)\n\t\t\tdefer cancel()\n\n\t\t\tb, err := dns.PackMessage(r.msg)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to pack dns query\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresp, err := s.dohHTTPSContext(dnsCtx, b.Bytes())\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to retrieve response\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\trec, err := parseResponse(resp)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to handle DOH response\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\ts.updateIP(r, rec)\n\t\t}(req)\n\t}\n}\n\nfunc (s *DoHNameServer) dohHTTPSContext(ctx context.Context, b []byte) ([]byte, error) {\n\tbody := bytes.NewBuffer(b)\n\treq, err := http.NewRequest(\"POST\", s.dohURL, body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Header.Add(\"Accept\", \"application/dns-message\")\n\treq.Header.Add(\"Content-Type\", \"application/dns-message\")\n\n\tresp, err := s.httpClient.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\tio.Copy(io.Discard, resp.Body) // flush resp.Body so that the conn is reusable\n\t\treturn nil, fmt.Errorf(\"DOH server returned code %d\", resp.StatusCode)\n\t}\n\n\treturn io.ReadAll(resp.Body)\n}\n\nfunc (s *DoHNameServer) findIPsForDomain(domain string, option dns_feature.IPOption) ([]net.IP, error) {\n\ts.RLock()\n\trecord, found := s.ips[domain]\n\ts.RUnlock()\n\n\tif !found {\n\t\treturn nil, errRecordNotFound\n\t}\n\n\tvar ips []net.Address\n\tvar lastErr error\n\tif option.IPv4Enable {\n\t\ta, err := record.A.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, a...)\n\t}\n\n\tif option.IPv6Enable {\n\t\taaaa, err := record.AAAA.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, aaaa...)\n\t}\n\n\tif len(ips) > 0 {\n\t\treturn toNetIP(ips)\n\t}\n\n\tif lastErr != nil {\n\t\treturn nil, lastErr\n\t}\n\n\treturn nil, dns_feature.ErrEmptyResponse\n}\n\n// QueryIP implements Server.\nfunc (s *DoHNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) { // nolint: dupl\n\tfqdn := Fqdn(domain)\n\n\tif disableCache {\n\t\tnewError(\"DNS cache is disabled. Querying IP for \", domain, \" at \", s.name).AtDebug().WriteToLog()\n\t} else {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\tnewError(s.name, \" cache HIT \", domain, \" -> \", ips).Base(err).AtDebug().WriteToLog()\n\t\t\treturn ips, err\n\t\t}\n\t}\n\n\t// ipv4 and ipv6 belong to different subscription groups\n\tvar sub4, sub6 *pubsub.Subscriber\n\tif option.IPv4Enable {\n\t\tsub4 = s.pub.Subscribe(fqdn + \"4\")\n\t\tdefer sub4.Close()\n\t}\n\tif option.IPv6Enable {\n\t\tsub6 = s.pub.Subscribe(fqdn + \"6\")\n\t\tdefer sub6.Close()\n\t}\n\tdone := make(chan interface{})\n\tgo func() {\n\t\tif sub4 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub4.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tif sub6 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub6.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tclose(done)\n\t}()\n\ts.sendQuery(ctx, fqdn, clientIP, option)\n\n\tfor {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\treturn ips, err\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-done:\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver_doh_test.go",
    "content": "package dns_test\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nfunc TestDoHLocalNameServer(t *testing.T) {\n\turl, err := url.Parse(\"https+local://1.1.1.1/dns-query\")\n\tcommon.Must(err)\n\n\ts := NewDoHLocalNameServer(url)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n}\n\nfunc TestDoHLocalNameServerWithCache(t *testing.T) {\n\turl, err := url.Parse(\"https+local://1.1.1.1/dns-query\")\n\tcommon.Must(err)\n\n\ts := NewDoHLocalNameServer(url)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n\n\tctx2, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips2, err := s.QueryIP(ctx2, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, true)\n\tcancel()\n\tcommon.Must(err)\n\tif r := cmp.Diff(ips2, ips); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver_fakedns.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\ntype FakeDNSServer struct {\n\tfakeDNSEngine dns.FakeDNSEngine\n}\n\nfunc NewFakeDNSServer(fakeDNSEngine dns.FakeDNSEngine) *FakeDNSServer {\n\treturn &FakeDNSServer{fakeDNSEngine: fakeDNSEngine}\n}\n\nfunc (FakeDNSServer) Name() string {\n\treturn \"fakedns\"\n}\n\nfunc (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, opt dns.IPOption, _ bool) ([]net.IP, error) {\n\tif !opt.FakeEnable {\n\t\treturn nil, nil // Returning empty ip record with no error will continue DNS lookup, effectively indicating that this server is disabled.\n\t}\n\tif f.fakeDNSEngine == nil {\n\t\tif err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) {\n\t\t\tf.fakeDNSEngine = fd\n\t\t}); err != nil {\n\t\t\treturn nil, newError(\"Unable to locate a fake DNS Engine\").Base(err).AtError()\n\t\t}\n\t}\n\tvar ips []net.Address\n\tif fkr0, ok := f.fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {\n\t\tips = fkr0.GetFakeIPForDomain3(domain, opt.IPv4Enable, opt.IPv6Enable)\n\t} else {\n\t\tips = filterIP(f.fakeDNSEngine.GetFakeIPForDomain(domain), opt)\n\t}\n\n\tnetIP, err := toNetIP(ips)\n\tif err != nil {\n\t\treturn nil, newError(\"Unable to convert IP to net ip\").Base(err).AtError()\n\t}\n\n\tnewError(f.Name(), \" got answer: \", domain, \" -> \", ips).AtInfo().WriteToLog()\n\n\tif len(netIP) > 0 {\n\t\treturn netIP, nil\n\t}\n\treturn nil, dns.ErrEmptyResponse\n}\n\nfunc isFakeDNS(server Server) bool {\n\t_, ok := server.(*FakeDNSServer)\n\treturn ok\n}\n"
  },
  {
    "path": "app/dns/nameserver_local.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns/localdns\"\n)\n\n// LocalNameServer is an wrapper over local DNS feature.\ntype LocalNameServer struct {\n\tclient *localdns.Client\n}\n\n// QueryIP implements Server.\nfunc (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) ([]net.IP, error) {\n\tvar ips []net.IP\n\tvar err error\n\n\tswitch {\n\tcase option.IPv4Enable && option.IPv6Enable:\n\t\tips, err = s.client.LookupIP(domain)\n\tcase option.IPv4Enable:\n\t\tips, err = s.client.LookupIPv4(domain)\n\tcase option.IPv6Enable:\n\t\tips, err = s.client.LookupIPv6(domain)\n\t}\n\n\tif len(ips) > 0 {\n\t\tnewError(\"Localhost got answer: \", domain, \" -> \", ips).AtInfo().WriteToLog()\n\t}\n\n\treturn ips, err\n}\n\n// Name implements Server.\nfunc (s *LocalNameServer) Name() string {\n\treturn \"localhost\"\n}\n\n// NewLocalNameServer creates localdns server object for directly lookup in system DNS.\nfunc NewLocalNameServer() *LocalNameServer {\n\tnewError(\"DNS: created localhost client\").AtInfo().WriteToLog()\n\treturn &LocalNameServer{\n\t\tclient: localdns.New(),\n\t}\n}\n\n// NewLocalDNSClient creates localdns client object for directly lookup in system DNS.\nfunc NewLocalDNSClient() *Client {\n\treturn &Client{server: NewLocalNameServer()}\n}\n"
  },
  {
    "path": "app/dns/nameserver_local_test.go",
    "content": "package dns_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nfunc TestLocalNameServer(t *testing.T) {\n\ts := NewLocalNameServer()\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP{}, dns.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver_quic.go",
    "content": "package dns\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/pubsub\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n// NextProtoDQ - During connection establishment, DNS/QUIC support is indicated\n// by selecting the ALPN token \"doq\" in the crypto handshake.\nconst NextProtoDQ = \"doq\"\n\nconst handshakeIdleTimeout = time.Second * 8\n\n// QUICNameServer implemented DNS over QUIC\ntype QUICNameServer struct {\n\tsync.RWMutex\n\tips         map[string]record\n\tpub         *pubsub.Service\n\tcleanup     *task.Periodic\n\tname        string\n\tdestination net.Destination\n\tconnection  *quic.Conn\n}\n\n// NewQUICNameServer creates DNS-over-QUIC client object for local resolving\nfunc NewQUICNameServer(url *url.URL) (*QUICNameServer, error) {\n\tnewError(\"DNS: created Local DNS-over-QUIC client for \", url.String()).AtInfo().WriteToLog()\n\n\tvar err error\n\tport := net.Port(853)\n\tif url.Port() != \"\" {\n\t\tport, err = net.PortFromString(url.Port())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tdest := net.UDPDestination(net.ParseAddress(url.Hostname()), port)\n\n\ts := &QUICNameServer{\n\t\tips:         make(map[string]record),\n\t\tpub:         pubsub.NewService(),\n\t\tname:        url.String(),\n\t\tdestination: dest,\n\t}\n\ts.cleanup = &task.Periodic{\n\t\tInterval: time.Minute,\n\t\tExecute:  s.Cleanup,\n\t}\n\n\treturn s, nil\n}\n\n// Name returns client name\nfunc (s *QUICNameServer) Name() string {\n\treturn s.name\n}\n\n// Cleanup clears expired items from cache\nfunc (s *QUICNameServer) Cleanup() error {\n\tnow := time.Now()\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tif len(s.ips) == 0 {\n\t\treturn newError(\"nothing to do. stopping...\")\n\t}\n\n\tfor domain, record := range s.ips {\n\t\tif record.A != nil && record.A.Expire.Before(now) {\n\t\t\trecord.A = nil\n\t\t}\n\t\tif record.AAAA != nil && record.AAAA.Expire.Before(now) {\n\t\t\trecord.AAAA = nil\n\t\t}\n\n\t\tif record.A == nil && record.AAAA == nil {\n\t\t\tnewError(s.name, \" cleanup \", domain).AtDebug().WriteToLog()\n\t\t\tdelete(s.ips, domain)\n\t\t} else {\n\t\t\ts.ips[domain] = record\n\t\t}\n\t}\n\n\tif len(s.ips) == 0 {\n\t\ts.ips = make(map[string]record)\n\t}\n\n\treturn nil\n}\n\nfunc (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {\n\telapsed := time.Since(req.start)\n\n\ts.Lock()\n\trec := s.ips[req.domain]\n\tupdated := false\n\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\tif isNewer(rec.A, ipRec) {\n\t\t\trec.A = ipRec\n\t\t\tupdated = true\n\t\t}\n\tcase dnsmessage.TypeAAAA:\n\t\taddr := make([]net.Address, 0)\n\t\tfor _, ip := range ipRec.IP {\n\t\t\tif len(ip.IP()) == net.IPv6len {\n\t\t\t\taddr = append(addr, ip)\n\t\t\t}\n\t\t}\n\t\tipRec.IP = addr\n\t\tif isNewer(rec.AAAA, ipRec) {\n\t\t\trec.AAAA = ipRec\n\t\t\tupdated = true\n\t\t}\n\t}\n\tnewError(s.name, \" got answer: \", req.domain, \" \", req.reqType, \" -> \", ipRec.IP, \" \", elapsed).AtInfo().WriteToLog()\n\n\tif updated {\n\t\ts.ips[req.domain] = rec\n\t}\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\ts.pub.Publish(req.domain+\"4\", nil)\n\tcase dnsmessage.TypeAAAA:\n\t\ts.pub.Publish(req.domain+\"6\", nil)\n\t}\n\ts.Unlock()\n\tcommon.Must(s.cleanup.Start())\n}\n\nfunc (s *QUICNameServer) newReqID() uint16 {\n\treturn 0\n}\n\nfunc (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {\n\tnewError(s.name, \" querying: \", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))\n\n\treqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))\n\n\tvar deadline time.Time\n\tif d, ok := ctx.Deadline(); ok {\n\t\tdeadline = d\n\t} else {\n\t\tdeadline = time.Now().Add(time.Second * 5)\n\t}\n\n\tfor _, req := range reqs {\n\t\tgo func(r *dnsRequest) {\n\t\t\t// generate new context for each req, using same context\n\t\t\t// may cause reqs all aborted if any one encounter an error\n\t\t\tdnsCtx := ctx\n\n\t\t\t// reserve internal dns server requested Inbound\n\t\t\tif inbound := session.InboundFromContext(ctx); inbound != nil {\n\t\t\t\tdnsCtx = session.ContextWithInbound(dnsCtx, inbound)\n\t\t\t}\n\n\t\t\tdnsCtx = session.ContextWithContent(dnsCtx, &session.Content{\n\t\t\t\tProtocol:       \"quic\",\n\t\t\t\tSkipDNSResolve: true,\n\t\t\t})\n\n\t\t\tvar cancel context.CancelFunc\n\t\t\tdnsCtx, cancel = context.WithDeadline(dnsCtx, deadline)\n\t\t\tdefer cancel()\n\n\t\t\tb, err := dns.PackMessage(r.msg)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to pack dns query\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdnsReqBuf := buf.New()\n\t\t\tbinary.Write(dnsReqBuf, binary.BigEndian, uint16(b.Len()))\n\t\t\tdnsReqBuf.Write(b.Bytes())\n\t\t\tb.Release()\n\n\t\t\tconn, err := s.openStream(dnsCtx)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to open quic connection\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t_, err = conn.Write(dnsReqBuf.Bytes())\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to send query\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t_ = conn.Close()\n\n\t\t\trespBuf := buf.New()\n\t\t\tdefer respBuf.Release()\n\t\t\tn, err := respBuf.ReadFullFrom(conn, 2)\n\t\t\tif err != nil && n == 0 {\n\t\t\t\tnewError(\"failed to read response length\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvar length int16\n\t\t\terr = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to parse response length\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\trespBuf.Clear()\n\t\t\tn, err = respBuf.ReadFullFrom(conn, int32(length))\n\t\t\tif err != nil && n == 0 {\n\t\t\t\tnewError(\"failed to read response length\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\trec, err := parseResponse(respBuf.Bytes())\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to handle response\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\ts.updateIP(r, rec)\n\t\t}(req)\n\t}\n}\n\nfunc (s *QUICNameServer) findIPsForDomain(domain string, option dns_feature.IPOption) ([]net.IP, error) {\n\ts.RLock()\n\trecord, found := s.ips[domain]\n\ts.RUnlock()\n\n\tif !found {\n\t\treturn nil, errRecordNotFound\n\t}\n\n\tvar ips []net.Address\n\tvar lastErr error\n\tif option.IPv4Enable {\n\t\ta, err := record.A.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, a...)\n\t}\n\n\tif option.IPv6Enable {\n\t\taaaa, err := record.AAAA.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, aaaa...)\n\t}\n\n\tif len(ips) > 0 {\n\t\treturn toNetIP(ips)\n\t}\n\n\tif lastErr != nil {\n\t\treturn nil, lastErr\n\t}\n\n\treturn nil, dns_feature.ErrEmptyResponse\n}\n\n// QueryIP is called from dns.Server->queryIPTimeout\nfunc (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) {\n\tfqdn := Fqdn(domain)\n\n\tif disableCache {\n\t\tnewError(\"DNS cache is disabled. Querying IP for \", domain, \" at \", s.name).AtDebug().WriteToLog()\n\t} else {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\tnewError(s.name, \" cache HIT \", domain, \" -> \", ips).Base(err).AtDebug().WriteToLog()\n\t\t\treturn ips, err\n\t\t}\n\t}\n\n\t// ipv4 and ipv6 belong to different subscription groups\n\tvar sub4, sub6 *pubsub.Subscriber\n\tif option.IPv4Enable {\n\t\tsub4 = s.pub.Subscribe(fqdn + \"4\")\n\t\tdefer sub4.Close()\n\t}\n\tif option.IPv6Enable {\n\t\tsub6 = s.pub.Subscribe(fqdn + \"6\")\n\t\tdefer sub6.Close()\n\t}\n\tdone := make(chan interface{})\n\tgo func() {\n\t\tif sub4 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub4.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tif sub6 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub6.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tclose(done)\n\t}()\n\ts.sendQuery(ctx, fqdn, clientIP, option)\n\n\tfor {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\treturn ips, err\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-done:\n\t\t}\n\t}\n}\n\nfunc isActive(s *quic.Conn) bool {\n\tselect {\n\tcase <-s.Context().Done():\n\t\treturn false\n\tdefault:\n\t\treturn true\n\t}\n}\n\nfunc (s *QUICNameServer) getConnection(ctx context.Context) (*quic.Conn, error) {\n\tvar conn *quic.Conn\n\ts.RLock()\n\tconn = s.connection\n\tif conn != nil && isActive(conn) {\n\t\ts.RUnlock()\n\t\treturn conn, nil\n\t}\n\tif conn != nil {\n\t\t// we're recreating the connection, let's create a new one\n\t\t_ = conn.CloseWithError(0, \"\")\n\t}\n\ts.RUnlock()\n\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tvar err error\n\tconn, err = s.openConnection(ctx)\n\tif err != nil {\n\t\t// This does not look too nice, but QUIC (or maybe quic-go)\n\t\t// doesn't seem stable enough.\n\t\t// Maybe retransmissions aren't fully implemented in quic-go?\n\t\t// Anyways, the simple solution is to make a second try when\n\t\t// it fails to open the QUIC connection.\n\t\tconn, err = s.openConnection(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\ts.connection = conn\n\treturn conn, nil\n}\n\nfunc (s *QUICNameServer) openConnection(ctx context.Context) (*quic.Conn, error) {\n\ttlsConfig := tls.Config{\n\t\tServerName: func() string {\n\t\t\tswitch s.destination.Address.Family() {\n\t\t\tcase net.AddressFamilyIPv4, net.AddressFamilyIPv6:\n\t\t\t\treturn s.destination.Address.IP().String()\n\t\t\tcase net.AddressFamilyDomain:\n\t\t\t\treturn s.destination.Address.Domain()\n\t\t\tdefault:\n\t\t\t\tpanic(\"unknown address family\")\n\t\t\t}\n\t\t}(),\n\t}\n\tquicConfig := &quic.Config{\n\t\tHandshakeIdleTimeout: handshakeIdleTimeout,\n\t}\n\n\tconn, err := quic.DialAddr(ctx, s.destination.NetAddr(), tlsConfig.GetTLSConfig(tls.WithNextProto(NextProtoDQ)), quicConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn conn, nil\n}\n\nfunc (s *QUICNameServer) openStream(ctx context.Context) (*quic.Stream, error) {\n\tconn, err := s.getConnection(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// open a new stream\n\treturn conn.OpenStreamSync(ctx)\n}\n"
  },
  {
    "path": "app/dns/nameserver_quic_test.go",
    "content": "package dns_test\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nfunc TestQUICNameServer(t *testing.T) {\n\turl, err := url.Parse(\"quic://dns.adguard.com\")\n\tcommon.Must(err)\n\ts, err := NewQUICNameServer(url)\n\tcommon.Must(err)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n}\n\nfunc TestQUICNameServerWithCache(t *testing.T) {\n\turl, err := url.Parse(\"quic://dns.adguard.com\")\n\tcommon.Must(err)\n\ts, err := NewQUICNameServer(url)\n\tcommon.Must(err)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n\n\tctx2, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips2, err := s.QueryIP(ctx2, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, true)\n\tcancel()\n\tcommon.Must(err)\n\tif r := cmp.Diff(ips2, ips); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver_tcp.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"net/url\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/pubsub\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// TCPNameServer implemented DNS over TCP (RFC7766).\ntype TCPNameServer struct {\n\tsync.RWMutex\n\tname        string\n\tdestination net.Destination\n\tips         map[string]record\n\tpub         *pubsub.Service\n\tcleanup     *task.Periodic\n\treqID       uint32\n\tdial        func(context.Context) (net.Conn, error)\n}\n\n// NewTCPNameServer creates DNS over TCP server object for remote resolving.\nfunc NewTCPNameServer(url *url.URL, dispatcher routing.Dispatcher) (*TCPNameServer, error) {\n\ts, err := baseTCPNameServer(url, \"TCP\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ts.dial = func(ctx context.Context) (net.Conn, error) {\n\t\tlink, err := dispatcher.Dispatch(ctx, s.destination)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn net.NewConnection(\n\t\t\tnet.ConnectionInputMulti(link.Writer),\n\t\t\tnet.ConnectionOutputMulti(link.Reader),\n\t\t), nil\n\t}\n\n\treturn s, nil\n}\n\n// NewTCPLocalNameServer creates DNS over TCP client object for local resolving\nfunc NewTCPLocalNameServer(url *url.URL) (*TCPNameServer, error) {\n\ts, err := baseTCPNameServer(url, \"TCPL\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ts.dial = func(ctx context.Context) (net.Conn, error) {\n\t\treturn internet.DialSystem(ctx, s.destination, nil)\n\t}\n\n\treturn s, nil\n}\n\nfunc baseTCPNameServer(url *url.URL, prefix string) (*TCPNameServer, error) {\n\tvar err error\n\tport := net.Port(53)\n\tif url.Port() != \"\" {\n\t\tport, err = net.PortFromString(url.Port())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tdest := net.TCPDestination(net.ParseAddress(url.Hostname()), port)\n\n\ts := &TCPNameServer{\n\t\tdestination: dest,\n\t\tips:         make(map[string]record),\n\t\tpub:         pubsub.NewService(),\n\t\tname:        prefix + \"//\" + dest.NetAddr(),\n\t}\n\ts.cleanup = &task.Periodic{\n\t\tInterval: time.Minute,\n\t\tExecute:  s.Cleanup,\n\t}\n\n\treturn s, nil\n}\n\n// Name implements Server.\nfunc (s *TCPNameServer) Name() string {\n\treturn s.name\n}\n\n// Cleanup clears expired items from cache\nfunc (s *TCPNameServer) Cleanup() error {\n\tnow := time.Now()\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tif len(s.ips) == 0 {\n\t\treturn newError(\"nothing to do. stopping...\")\n\t}\n\n\tfor domain, record := range s.ips {\n\t\tif record.A != nil && record.A.Expire.Before(now) {\n\t\t\trecord.A = nil\n\t\t}\n\t\tif record.AAAA != nil && record.AAAA.Expire.Before(now) {\n\t\t\trecord.AAAA = nil\n\t\t}\n\n\t\tif record.A == nil && record.AAAA == nil {\n\t\t\tnewError(s.name, \" cleanup \", domain).AtDebug().WriteToLog()\n\t\t\tdelete(s.ips, domain)\n\t\t} else {\n\t\t\ts.ips[domain] = record\n\t\t}\n\t}\n\n\tif len(s.ips) == 0 {\n\t\ts.ips = make(map[string]record)\n\t}\n\n\treturn nil\n}\n\nfunc (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {\n\telapsed := time.Since(req.start)\n\n\ts.Lock()\n\trec := s.ips[req.domain]\n\tupdated := false\n\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\tif isNewer(rec.A, ipRec) {\n\t\t\trec.A = ipRec\n\t\t\tupdated = true\n\t\t}\n\tcase dnsmessage.TypeAAAA:\n\t\taddr := make([]net.Address, 0)\n\t\tfor _, ip := range ipRec.IP {\n\t\t\tif len(ip.IP()) == net.IPv6len {\n\t\t\t\taddr = append(addr, ip)\n\t\t\t}\n\t\t}\n\t\tipRec.IP = addr\n\t\tif isNewer(rec.AAAA, ipRec) {\n\t\t\trec.AAAA = ipRec\n\t\t\tupdated = true\n\t\t}\n\t}\n\tnewError(s.name, \" got answer: \", req.domain, \" \", req.reqType, \" -> \", ipRec.IP, \" \", elapsed).AtInfo().WriteToLog()\n\n\tif updated {\n\t\ts.ips[req.domain] = rec\n\t}\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\ts.pub.Publish(req.domain+\"4\", nil)\n\tcase dnsmessage.TypeAAAA:\n\t\ts.pub.Publish(req.domain+\"6\", nil)\n\t}\n\ts.Unlock()\n\tcommon.Must(s.cleanup.Start())\n}\n\nfunc (s *TCPNameServer) newReqID() uint16 {\n\treturn uint16(atomic.AddUint32(&s.reqID, 1))\n}\n\nfunc (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {\n\tnewError(s.name, \" querying DNS for: \", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\n\treqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))\n\n\tvar deadline time.Time\n\tif d, ok := ctx.Deadline(); ok {\n\t\tdeadline = d\n\t} else {\n\t\tdeadline = time.Now().Add(time.Second * 5)\n\t}\n\n\tfor _, req := range reqs {\n\t\tgo func(r *dnsRequest) {\n\t\t\tdnsCtx := ctx\n\n\t\t\tif inbound := session.InboundFromContext(ctx); inbound != nil {\n\t\t\t\tdnsCtx = session.ContextWithInbound(dnsCtx, inbound)\n\t\t\t}\n\n\t\t\tdnsCtx = session.ContextWithContent(dnsCtx, &session.Content{\n\t\t\t\tProtocol:       \"dns\",\n\t\t\t\tSkipDNSResolve: true,\n\t\t\t})\n\n\t\t\tvar cancel context.CancelFunc\n\t\t\tdnsCtx, cancel = context.WithDeadline(dnsCtx, deadline)\n\t\t\tdefer cancel()\n\n\t\t\tb, err := dns.PackMessage(r.msg)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to pack dns query\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconn, err := s.dial(dnsCtx)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to dial namesever\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer conn.Close()\n\t\t\tdnsReqBuf := buf.New()\n\t\t\tbinary.Write(dnsReqBuf, binary.BigEndian, uint16(b.Len()))\n\t\t\tdnsReqBuf.Write(b.Bytes())\n\t\t\tb.Release()\n\n\t\t\t_, err = conn.Write(dnsReqBuf.Bytes())\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to send query\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdnsReqBuf.Release()\n\n\t\t\trespBuf := buf.New()\n\t\t\tdefer respBuf.Release()\n\t\t\tn, err := respBuf.ReadFullFrom(conn, 2)\n\t\t\tif err != nil && n == 0 {\n\t\t\t\tnewError(\"failed to read response length\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvar length int16\n\t\t\terr = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to parse response length\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\trespBuf.Clear()\n\t\t\tn, err = respBuf.ReadFullFrom(conn, int32(length))\n\t\t\tif err != nil && n == 0 {\n\t\t\t\tnewError(\"failed to read response length\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\trec, err := parseResponse(respBuf.Bytes())\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to parse DNS over TCP response\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ts.updateIP(r, rec)\n\t\t}(req)\n\t}\n}\n\nfunc (s *TCPNameServer) findIPsForDomain(domain string, option dns_feature.IPOption) ([]net.IP, error) {\n\ts.RLock()\n\trecord, found := s.ips[domain]\n\ts.RUnlock()\n\n\tif !found {\n\t\treturn nil, errRecordNotFound\n\t}\n\n\tvar ips []net.Address\n\tvar lastErr error\n\tif option.IPv4Enable {\n\t\ta, err := record.A.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, a...)\n\t}\n\n\tif option.IPv6Enable {\n\t\taaaa, err := record.AAAA.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, aaaa...)\n\t}\n\n\tif len(ips) > 0 {\n\t\treturn toNetIP(ips)\n\t}\n\n\tif lastErr != nil {\n\t\treturn nil, lastErr\n\t}\n\n\treturn nil, dns_feature.ErrEmptyResponse\n}\n\n// QueryIP implements Server.\nfunc (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) {\n\tfqdn := Fqdn(domain)\n\n\tif disableCache {\n\t\tnewError(\"DNS cache is disabled. Querying IP for \", domain, \" at \", s.name).AtDebug().WriteToLog()\n\t} else {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\tnewError(s.name, \" cache HIT \", domain, \" -> \", ips).Base(err).AtDebug().WriteToLog()\n\t\t\treturn ips, err\n\t\t}\n\t}\n\n\t// ipv4 and ipv6 belong to different subscription groups\n\tvar sub4, sub6 *pubsub.Subscriber\n\tif option.IPv4Enable {\n\t\tsub4 = s.pub.Subscribe(fqdn + \"4\")\n\t\tdefer sub4.Close()\n\t}\n\tif option.IPv6Enable {\n\t\tsub6 = s.pub.Subscribe(fqdn + \"6\")\n\t\tdefer sub6.Close()\n\t}\n\tdone := make(chan interface{})\n\tgo func() {\n\t\tif sub4 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub4.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tif sub6 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub6.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tclose(done)\n\t}()\n\ts.sendQuery(ctx, fqdn, clientIP, option)\n\n\tfor {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\treturn ips, err\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-done:\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver_tcp_test.go",
    "content": "package dns_test\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\nfunc TestTCPLocalNameServer(t *testing.T) {\n\turl, err := url.Parse(\"tcp+local://8.8.8.8\")\n\tcommon.Must(err)\n\ts, err := NewTCPLocalNameServer(url)\n\tcommon.Must(err)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n}\n\nfunc TestTCPLocalNameServerWithCache(t *testing.T) {\n\turl, err := url.Parse(\"tcp+local://8.8.8.8\")\n\tcommon.Must(err)\n\ts, err := NewTCPLocalNameServer(url)\n\tcommon.Must(err)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips, err := s.QueryIP(ctx, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, false)\n\tcancel()\n\tcommon.Must(err)\n\tif len(ips) == 0 {\n\t\tt.Error(\"expect some ips, but got 0\")\n\t}\n\n\tctx2, cancel := context.WithTimeout(context.Background(), time.Second*5)\n\tips2, err := s.QueryIP(ctx2, \"google.com\", net.IP(nil), dns_feature.IPOption{\n\t\tIPv4Enable: true,\n\t\tIPv6Enable: true,\n\t}, true)\n\tcancel()\n\tcommon.Must(err)\n\tif r := cmp.Diff(ips2, ips); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n"
  },
  {
    "path": "app/dns/nameserver_udp.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage dns\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/dns\"\n\tudp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/pubsub\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\tdns_feature \"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// ClassicNameServer implemented traditional UDP DNS.\ntype ClassicNameServer struct {\n\tsync.RWMutex\n\tname      string\n\taddress   net.Destination\n\tips       map[string]record\n\trequests  map[uint16]dnsRequest\n\tpub       *pubsub.Service\n\tudpServer udp.DispatcherI\n\tcleanup   *task.Periodic\n\treqID     uint32\n}\n\n// NewClassicNameServer creates udp server object for remote resolving.\nfunc NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher) *ClassicNameServer {\n\t// default to 53 if unspecific\n\tif address.Port == 0 {\n\t\taddress.Port = net.Port(53)\n\t}\n\n\ts := &ClassicNameServer{\n\t\taddress:  address,\n\t\tips:      make(map[string]record),\n\t\trequests: make(map[uint16]dnsRequest),\n\t\tpub:      pubsub.NewService(),\n\t\tname:     strings.ToUpper(address.String()),\n\t}\n\ts.cleanup = &task.Periodic{\n\t\tInterval: time.Minute,\n\t\tExecute:  s.Cleanup,\n\t}\n\ts.udpServer = udp.NewSplitDispatcher(dispatcher, s.HandleResponse)\n\tnewError(\"DNS: created UDP client initialized for \", address.NetAddr()).AtInfo().WriteToLog()\n\treturn s\n}\n\n// Name implements Server.\nfunc (s *ClassicNameServer) Name() string {\n\treturn s.name\n}\n\n// Cleanup clears expired items from cache\nfunc (s *ClassicNameServer) Cleanup() error {\n\tnow := time.Now()\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tif len(s.ips) == 0 && len(s.requests) == 0 {\n\t\treturn newError(s.name, \" nothing to do. stopping...\")\n\t}\n\n\tfor domain, record := range s.ips {\n\t\tif record.A != nil && record.A.Expire.Before(now) {\n\t\t\trecord.A = nil\n\t\t}\n\t\tif record.AAAA != nil && record.AAAA.Expire.Before(now) {\n\t\t\trecord.AAAA = nil\n\t\t}\n\n\t\tif record.A == nil && record.AAAA == nil {\n\t\t\tdelete(s.ips, domain)\n\t\t} else {\n\t\t\ts.ips[domain] = record\n\t\t}\n\t}\n\n\tif len(s.ips) == 0 {\n\t\ts.ips = make(map[string]record)\n\t}\n\n\tfor id, req := range s.requests {\n\t\tif req.expire.Before(now) {\n\t\t\tdelete(s.requests, id)\n\t\t}\n\t}\n\n\tif len(s.requests) == 0 {\n\t\ts.requests = make(map[uint16]dnsRequest)\n\t}\n\n\treturn nil\n}\n\n// HandleResponse handles udp response packet from remote DNS server.\nfunc (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) {\n\tipRec, err := parseResponse(packet.Payload.Bytes())\n\tif err != nil {\n\t\tnewError(s.name, \" fail to parse responded DNS udp\").AtError().WriteToLog()\n\t\treturn\n\t}\n\n\ts.Lock()\n\tid := ipRec.ReqID\n\treq, ok := s.requests[id]\n\tif ok {\n\t\t// remove the pending request\n\t\tdelete(s.requests, id)\n\t}\n\ts.Unlock()\n\tif !ok {\n\t\tnewError(s.name, \" cannot find the pending request\").AtError().WriteToLog()\n\t\treturn\n\t}\n\n\tvar rec record\n\tswitch req.reqType {\n\tcase dnsmessage.TypeA:\n\t\trec.A = ipRec\n\tcase dnsmessage.TypeAAAA:\n\t\trec.AAAA = ipRec\n\t}\n\n\telapsed := time.Since(req.start)\n\tnewError(s.name, \" got answer: \", req.domain, \" \", req.reqType, \" -> \", ipRec.IP, \" \", elapsed).AtInfo().WriteToLog()\n\tif len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) {\n\t\ts.updateIP(req.domain, rec)\n\t}\n}\n\nfunc (s *ClassicNameServer) updateIP(domain string, newRec record) {\n\ts.Lock()\n\n\tnewError(s.name, \" updating IP records for domain:\", domain).AtDebug().WriteToLog()\n\trec := s.ips[domain]\n\n\tupdated := false\n\tif isNewer(rec.A, newRec.A) {\n\t\trec.A = newRec.A\n\t\tupdated = true\n\t}\n\tif isNewer(rec.AAAA, newRec.AAAA) {\n\t\trec.AAAA = newRec.AAAA\n\t\tupdated = true\n\t}\n\n\tif updated {\n\t\ts.ips[domain] = rec\n\t}\n\tif newRec.A != nil {\n\t\ts.pub.Publish(domain+\"4\", nil)\n\t}\n\tif newRec.AAAA != nil {\n\t\ts.pub.Publish(domain+\"6\", nil)\n\t}\n\ts.Unlock()\n\tcommon.Must(s.cleanup.Start())\n}\n\nfunc (s *ClassicNameServer) newReqID() uint16 {\n\treturn uint16(atomic.AddUint32(&s.reqID, 1))\n}\n\nfunc (s *ClassicNameServer) addPendingRequest(req *dnsRequest) {\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tid := req.msg.ID\n\treq.expire = time.Now().Add(time.Second * 8)\n\ts.requests[id] = *req\n}\n\nfunc (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {\n\tnewError(s.name, \" querying DNS for: \", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\n\treqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))\n\n\tfor _, req := range reqs {\n\t\ts.addPendingRequest(req)\n\t\tb, _ := dns.PackMessage(req.msg)\n\t\tudpCtx := core.ToBackgroundDetachedContext(ctx)\n\t\tif inbound := session.InboundFromContext(ctx); inbound != nil {\n\t\t\tudpCtx = session.ContextWithInbound(udpCtx, inbound)\n\t\t}\n\t\tudpCtx = session.ContextWithContent(udpCtx, &session.Content{\n\t\t\tProtocol: \"dns\",\n\t\t})\n\t\ts.udpServer.Dispatch(udpCtx, s.address, b)\n\t}\n}\n\nfunc (s *ClassicNameServer) findIPsForDomain(domain string, option dns_feature.IPOption) ([]net.IP, error) {\n\ts.RLock()\n\trecord, found := s.ips[domain]\n\ts.RUnlock()\n\n\tif !found {\n\t\treturn nil, errRecordNotFound\n\t}\n\n\tvar ips []net.Address\n\tvar lastErr error\n\tif option.IPv4Enable {\n\t\ta, err := record.A.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, a...)\n\t}\n\n\tif option.IPv6Enable {\n\t\taaaa, err := record.AAAA.getIPs()\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t\tips = append(ips, aaaa...)\n\t}\n\n\tif len(ips) > 0 {\n\t\treturn toNetIP(ips)\n\t}\n\n\tif lastErr != nil {\n\t\treturn nil, lastErr\n\t}\n\n\treturn nil, dns_feature.ErrEmptyResponse\n}\n\n// QueryIP implements Server.\nfunc (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) {\n\tfqdn := Fqdn(domain)\n\n\tif disableCache {\n\t\tnewError(\"DNS cache is disabled. Querying IP for \", domain, \" at \", s.name).AtDebug().WriteToLog()\n\t} else {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\tnewError(s.name, \" cache HIT \", domain, \" -> \", ips).Base(err).AtDebug().WriteToLog()\n\t\t\treturn ips, err\n\t\t}\n\t}\n\n\t// ipv4 and ipv6 belong to different subscription groups\n\tvar sub4, sub6 *pubsub.Subscriber\n\tif option.IPv4Enable {\n\t\tsub4 = s.pub.Subscribe(fqdn + \"4\")\n\t\tdefer sub4.Close()\n\t}\n\tif option.IPv6Enable {\n\t\tsub6 = s.pub.Subscribe(fqdn + \"6\")\n\t\tdefer sub6.Close()\n\t}\n\tdone := make(chan interface{})\n\tgo func() {\n\t\tif sub4 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub4.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tif sub6 != nil {\n\t\t\tselect {\n\t\t\tcase <-sub6.Wait():\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t}\n\t\tclose(done)\n\t}()\n\ts.sendQuery(ctx, fqdn, clientIP, option)\n\n\tfor {\n\t\tips, err := s.findIPsForDomain(fqdn, option)\n\t\tif err != errRecordNotFound {\n\t\t\treturn ips, err\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-done:\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/instman/command/command.go",
    "content": "package command\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\n\t\"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\ntype service struct {\n\tUnimplementedInstanceManagementServiceServer\n\n\tinstman extension.InstanceManagement\n}\n\nfunc (s service) ListInstance(ctx context.Context, req *ListInstanceReq) (*ListInstanceResp, error) {\n\tinstanceNames, err := s.instman.ListInstance(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ListInstanceResp{Name: instanceNames}, nil\n}\n\nfunc (s service) AddInstance(ctx context.Context, req *AddInstanceReq) (*AddInstanceResp, error) {\n\tconfigContent, err := base64.StdEncoding.DecodeString(req.ConfigContentB64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = s.instman.AddInstance(ctx, req.Name, configContent, req.ConfigType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &AddInstanceResp{}, nil\n}\n\nfunc (s service) StartInstance(ctx context.Context, req *StartInstanceReq) (*StartInstanceResp, error) {\n\terr := s.instman.StartInstance(ctx, req.Name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &StartInstanceResp{}, nil\n}\n\nfunc (s service) Register(server *grpc.Server) {\n\tRegisterInstanceManagementServiceServer(server, s)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\ts := core.MustFromContext(ctx)\n\t\tsv := &service{}\n\t\terr := s.RequireFeatures(func(instman extension.InstanceManagement) {\n\t\t\tsv.instman = instman\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn sv, nil\n\t}))\n}\n"
  },
  {
    "path": "app/instman/command/command.pb.go",
    "content": "package command\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ListInstanceReq struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ListInstanceReq) Reset() {\n\t*x = ListInstanceReq{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ListInstanceReq) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListInstanceReq) ProtoMessage() {}\n\nfunc (x *ListInstanceReq) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[0]\n\tif 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 ListInstanceReq.ProtoReflect.Descriptor instead.\nfunc (*ListInstanceReq) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{0}\n}\n\ntype ListInstanceResp struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          []string               `protobuf:\"bytes,1,rep,name=name,proto3\" json:\"name,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ListInstanceResp) Reset() {\n\t*x = ListInstanceResp{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ListInstanceResp) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListInstanceResp) ProtoMessage() {}\n\nfunc (x *ListInstanceResp) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[1]\n\tif 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 ListInstanceResp.ProtoReflect.Descriptor instead.\nfunc (*ListInstanceResp) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ListInstanceResp) GetName() []string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn nil\n}\n\ntype AddInstanceReq struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tName             string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tConfigType       string                 `protobuf:\"bytes,2,opt,name=configType,proto3\" json:\"configType,omitempty\"`\n\tConfigContentB64 string                 `protobuf:\"bytes,3,opt,name=configContentB64,proto3\" json:\"configContentB64,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *AddInstanceReq) Reset() {\n\t*x = AddInstanceReq{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddInstanceReq) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddInstanceReq) ProtoMessage() {}\n\nfunc (x *AddInstanceReq) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[2]\n\tif 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 AddInstanceReq.ProtoReflect.Descriptor instead.\nfunc (*AddInstanceReq) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *AddInstanceReq) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *AddInstanceReq) GetConfigType() string {\n\tif x != nil {\n\t\treturn x.ConfigType\n\t}\n\treturn \"\"\n}\n\nfunc (x *AddInstanceReq) GetConfigContentB64() string {\n\tif x != nil {\n\t\treturn x.ConfigContentB64\n\t}\n\treturn \"\"\n}\n\ntype AddInstanceResp struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddInstanceResp) Reset() {\n\t*x = AddInstanceResp{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddInstanceResp) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddInstanceResp) ProtoMessage() {}\n\nfunc (x *AddInstanceResp) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[3]\n\tif 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 AddInstanceResp.ProtoReflect.Descriptor instead.\nfunc (*AddInstanceResp) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{3}\n}\n\ntype StartInstanceReq struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *StartInstanceReq) Reset() {\n\t*x = StartInstanceReq{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StartInstanceReq) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StartInstanceReq) ProtoMessage() {}\n\nfunc (x *StartInstanceReq) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[4]\n\tif 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 StartInstanceReq.ProtoReflect.Descriptor instead.\nfunc (*StartInstanceReq) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *StartInstanceReq) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype StartInstanceResp struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *StartInstanceResp) Reset() {\n\t*x = StartInstanceResp{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StartInstanceResp) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StartInstanceResp) ProtoMessage() {}\n\nfunc (x *StartInstanceResp) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[5]\n\tif 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 StartInstanceResp.ProtoReflect.Descriptor instead.\nfunc (*StartInstanceResp) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{5}\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_instman_command_command_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_command_command_proto_msgTypes[6]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_command_command_proto_rawDescGZIP(), []int{6}\n}\n\nvar File_app_instman_command_command_proto protoreflect.FileDescriptor\n\nconst file_app_instman_command_command_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!app/instman/command/command.proto\\x12\\x1ev2ray.core.app.instman.command\\x1a common/protoext/extensions.proto\\\"\\x11\\n\" +\n\t\"\\x0fListInstanceReq\\\"&\\n\" +\n\t\"\\x10ListInstanceResp\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x03(\\tR\\x04name\\\"p\\n\" +\n\t\"\\x0eAddInstanceReq\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"configType\\x18\\x02 \\x01(\\tR\\n\" +\n\t\"configType\\x12*\\n\" +\n\t\"\\x10configContentB64\\x18\\x03 \\x01(\\tR\\x10configContentB64\\\"\\x11\\n\" +\n\t\"\\x0fAddInstanceResp\\\"&\\n\" +\n\t\"\\x10StartInstanceReq\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\\"\\x13\\n\" +\n\t\"\\x11StartInstanceResp\\\"$\\n\" +\n\t\"\\x06Config:\\x1a\\x82\\xb5\\x18\\x16\\n\" +\n\t\"\\vgrpcservice\\x12\\ainstman2\\xf4\\x02\\n\" +\n\t\"\\x19InstanceManagementService\\x12q\\n\" +\n\t\"\\fListInstance\\x12/.v2ray.core.app.instman.command.ListInstanceReq\\x1a0.v2ray.core.app.instman.command.ListInstanceResp\\x12n\\n\" +\n\t\"\\vAddInstance\\x12..v2ray.core.app.instman.command.AddInstanceReq\\x1a/.v2ray.core.app.instman.command.AddInstanceResp\\x12t\\n\" +\n\t\"\\rStartInstance\\x120.v2ray.core.app.instman.command.StartInstanceReq\\x1a1.v2ray.core.app.instman.command.StartInstanceRespB\\x7f\\n\" +\n\t\"&com.v2ray.core.app.observatory.instmanP\\x01Z2github.com/v2fly/v2ray-core/v5/app/instman/command\\xaa\\x02\\x1eV2Ray.Core.App.Instman.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_instman_command_command_proto_rawDescOnce sync.Once\n\tfile_app_instman_command_command_proto_rawDescData []byte\n)\n\nfunc file_app_instman_command_command_proto_rawDescGZIP() []byte {\n\tfile_app_instman_command_command_proto_rawDescOnce.Do(func() {\n\t\tfile_app_instman_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_instman_command_command_proto_rawDesc), len(file_app_instman_command_command_proto_rawDesc)))\n\t})\n\treturn file_app_instman_command_command_proto_rawDescData\n}\n\nvar file_app_instman_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 7)\nvar file_app_instman_command_command_proto_goTypes = []any{\n\t(*ListInstanceReq)(nil),   // 0: v2ray.core.app.instman.command.ListInstanceReq\n\t(*ListInstanceResp)(nil),  // 1: v2ray.core.app.instman.command.ListInstanceResp\n\t(*AddInstanceReq)(nil),    // 2: v2ray.core.app.instman.command.AddInstanceReq\n\t(*AddInstanceResp)(nil),   // 3: v2ray.core.app.instman.command.AddInstanceResp\n\t(*StartInstanceReq)(nil),  // 4: v2ray.core.app.instman.command.StartInstanceReq\n\t(*StartInstanceResp)(nil), // 5: v2ray.core.app.instman.command.StartInstanceResp\n\t(*Config)(nil),            // 6: v2ray.core.app.instman.command.Config\n}\nvar file_app_instman_command_command_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.instman.command.InstanceManagementService.ListInstance:input_type -> v2ray.core.app.instman.command.ListInstanceReq\n\t2, // 1: v2ray.core.app.instman.command.InstanceManagementService.AddInstance:input_type -> v2ray.core.app.instman.command.AddInstanceReq\n\t4, // 2: v2ray.core.app.instman.command.InstanceManagementService.StartInstance:input_type -> v2ray.core.app.instman.command.StartInstanceReq\n\t1, // 3: v2ray.core.app.instman.command.InstanceManagementService.ListInstance:output_type -> v2ray.core.app.instman.command.ListInstanceResp\n\t3, // 4: v2ray.core.app.instman.command.InstanceManagementService.AddInstance:output_type -> v2ray.core.app.instman.command.AddInstanceResp\n\t5, // 5: v2ray.core.app.instman.command.InstanceManagementService.StartInstance:output_type -> v2ray.core.app.instman.command.StartInstanceResp\n\t3, // [3:6] is the sub-list for method output_type\n\t0, // [0:3] 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_app_instman_command_command_proto_init() }\nfunc file_app_instman_command_command_proto_init() {\n\tif File_app_instman_command_command_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: unsafe.Slice(unsafe.StringData(file_app_instman_command_command_proto_rawDesc), len(file_app_instman_command_command_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   7,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_instman_command_command_proto_goTypes,\n\t\tDependencyIndexes: file_app_instman_command_command_proto_depIdxs,\n\t\tMessageInfos:      file_app_instman_command_command_proto_msgTypes,\n\t}.Build()\n\tFile_app_instman_command_command_proto = out.File\n\tfile_app_instman_command_command_proto_goTypes = nil\n\tfile_app_instman_command_command_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/instman/command/command.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.instman.command;\noption csharp_namespace = \"V2Ray.Core.App.Instman.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/instman/command\";\noption java_package = \"com.v2ray.core.app.observatory.instman\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage ListInstanceReq{}\nmessage ListInstanceResp{\n  repeated string name = 1;\n}\n\nmessage AddInstanceReq{\n  string name = 1;\n  string configType = 2;\n  string configContentB64 = 3;\n}\n\nmessage AddInstanceResp{}\n\nmessage StartInstanceReq{\n  string name = 1;\n}\n\nmessage StartInstanceResp{\n}\n\nservice InstanceManagementService {\n  rpc ListInstance(ListInstanceReq) returns (ListInstanceResp);\n  rpc AddInstance(AddInstanceReq) returns (AddInstanceResp);\n  rpc StartInstance(StartInstanceReq) returns (StartInstanceResp);\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"instman\";\n}"
  },
  {
    "path": "app/instman/command/command_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tInstanceManagementService_ListInstance_FullMethodName  = \"/v2ray.core.app.instman.command.InstanceManagementService/ListInstance\"\n\tInstanceManagementService_AddInstance_FullMethodName   = \"/v2ray.core.app.instman.command.InstanceManagementService/AddInstance\"\n\tInstanceManagementService_StartInstance_FullMethodName = \"/v2ray.core.app.instman.command.InstanceManagementService/StartInstance\"\n)\n\n// InstanceManagementServiceClient is the client API for InstanceManagementService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype InstanceManagementServiceClient interface {\n\tListInstance(ctx context.Context, in *ListInstanceReq, opts ...grpc.CallOption) (*ListInstanceResp, error)\n\tAddInstance(ctx context.Context, in *AddInstanceReq, opts ...grpc.CallOption) (*AddInstanceResp, error)\n\tStartInstance(ctx context.Context, in *StartInstanceReq, opts ...grpc.CallOption) (*StartInstanceResp, error)\n}\n\ntype instanceManagementServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewInstanceManagementServiceClient(cc grpc.ClientConnInterface) InstanceManagementServiceClient {\n\treturn &instanceManagementServiceClient{cc}\n}\n\nfunc (c *instanceManagementServiceClient) ListInstance(ctx context.Context, in *ListInstanceReq, opts ...grpc.CallOption) (*ListInstanceResp, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(ListInstanceResp)\n\terr := c.cc.Invoke(ctx, InstanceManagementService_ListInstance_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *instanceManagementServiceClient) AddInstance(ctx context.Context, in *AddInstanceReq, opts ...grpc.CallOption) (*AddInstanceResp, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(AddInstanceResp)\n\terr := c.cc.Invoke(ctx, InstanceManagementService_AddInstance_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *instanceManagementServiceClient) StartInstance(ctx context.Context, in *StartInstanceReq, opts ...grpc.CallOption) (*StartInstanceResp, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(StartInstanceResp)\n\terr := c.cc.Invoke(ctx, InstanceManagementService_StartInstance_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// InstanceManagementServiceServer is the server API for InstanceManagementService service.\n// All implementations must embed UnimplementedInstanceManagementServiceServer\n// for forward compatibility.\ntype InstanceManagementServiceServer interface {\n\tListInstance(context.Context, *ListInstanceReq) (*ListInstanceResp, error)\n\tAddInstance(context.Context, *AddInstanceReq) (*AddInstanceResp, error)\n\tStartInstance(context.Context, *StartInstanceReq) (*StartInstanceResp, error)\n\tmustEmbedUnimplementedInstanceManagementServiceServer()\n}\n\n// UnimplementedInstanceManagementServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedInstanceManagementServiceServer struct{}\n\nfunc (UnimplementedInstanceManagementServiceServer) ListInstance(context.Context, *ListInstanceReq) (*ListInstanceResp, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method ListInstance not implemented\")\n}\nfunc (UnimplementedInstanceManagementServiceServer) AddInstance(context.Context, *AddInstanceReq) (*AddInstanceResp, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method AddInstance not implemented\")\n}\nfunc (UnimplementedInstanceManagementServiceServer) StartInstance(context.Context, *StartInstanceReq) (*StartInstanceResp, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method StartInstance not implemented\")\n}\nfunc (UnimplementedInstanceManagementServiceServer) mustEmbedUnimplementedInstanceManagementServiceServer() {\n}\nfunc (UnimplementedInstanceManagementServiceServer) testEmbeddedByValue() {}\n\n// UnsafeInstanceManagementServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to InstanceManagementServiceServer will\n// result in compilation errors.\ntype UnsafeInstanceManagementServiceServer interface {\n\tmustEmbedUnimplementedInstanceManagementServiceServer()\n}\n\nfunc RegisterInstanceManagementServiceServer(s grpc.ServiceRegistrar, srv InstanceManagementServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedInstanceManagementServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&InstanceManagementService_ServiceDesc, srv)\n}\n\nfunc _InstanceManagementService_ListInstance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListInstanceReq)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(InstanceManagementServiceServer).ListInstance(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: InstanceManagementService_ListInstance_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(InstanceManagementServiceServer).ListInstance(ctx, req.(*ListInstanceReq))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _InstanceManagementService_AddInstance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddInstanceReq)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(InstanceManagementServiceServer).AddInstance(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: InstanceManagementService_AddInstance_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(InstanceManagementServiceServer).AddInstance(ctx, req.(*AddInstanceReq))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _InstanceManagementService_StartInstance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(StartInstanceReq)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(InstanceManagementServiceServer).StartInstance(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: InstanceManagementService_StartInstance_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(InstanceManagementServiceServer).StartInstance(ctx, req.(*StartInstanceReq))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// InstanceManagementService_ServiceDesc is the grpc.ServiceDesc for InstanceManagementService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar InstanceManagementService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.instman.command.InstanceManagementService\",\n\tHandlerType: (*InstanceManagementServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListInstance\",\n\t\t\tHandler:    _InstanceManagementService_ListInstance_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"AddInstance\",\n\t\t\tHandler:    _InstanceManagementService_AddInstance_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"StartInstance\",\n\t\t\tHandler:    _InstanceManagementService_StartInstance_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"app/instman/command/command.proto\",\n}\n"
  },
  {
    "path": "app/instman/config.pb.go",
    "content": "package instman\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_instman_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_instman_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_instman_config_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_app_instman_config_proto protoreflect.FileDescriptor\n\nconst file_app_instman_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x18app/instman/config.proto\\x12\\x16v2ray.core.app.instman\\x1a common/protoext/extensions.proto\\\" \\n\" +\n\t\"\\x06Config:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\aservice\\x12\\ainstmanBc\\n\" +\n\t\"\\x1acom.v2ray.core.app.instmanP\\x01Z*github.com/v2fly/v2ray-core/v5/app/instman\\xaa\\x02\\x16V2Ray.Core.App.Instmanb\\x06proto3\"\n\nvar (\n\tfile_app_instman_config_proto_rawDescOnce sync.Once\n\tfile_app_instman_config_proto_rawDescData []byte\n)\n\nfunc file_app_instman_config_proto_rawDescGZIP() []byte {\n\tfile_app_instman_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_instman_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_instman_config_proto_rawDesc), len(file_app_instman_config_proto_rawDesc)))\n\t})\n\treturn file_app_instman_config_proto_rawDescData\n}\n\nvar file_app_instman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_instman_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.app.instman.Config\n}\nvar file_app_instman_config_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_app_instman_config_proto_init() }\nfunc file_app_instman_config_proto_init() {\n\tif File_app_instman_config_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: unsafe.Slice(unsafe.StringData(file_app_instman_config_proto_rawDesc), len(file_app_instman_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_instman_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_instman_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_instman_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_instman_config_proto = out.File\n\tfile_app_instman_config_proto_goTypes = nil\n\tfile_app_instman_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/instman/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.instman;\noption csharp_namespace = \"V2Ray.Core.App.Instman\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/instman\";\noption java_package = \"com.v2ray.core.app.instman\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"instman\";\n}"
  },
  {
    "path": "app/instman/errors.generated.go",
    "content": "package instman\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/instman/instman.go",
    "content": "package instman\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype InstanceMgr struct {\n\tconfig    *Config // nolint: structcheck\n\tinstances map[string]*core.Instance\n}\n\nfunc (i InstanceMgr) Type() interface{} {\n\treturn extension.InstanceManagementType()\n}\n\nfunc (i InstanceMgr) Start() error {\n\treturn nil\n}\n\nfunc (i InstanceMgr) Close() error {\n\treturn nil\n}\n\nfunc (i InstanceMgr) ListInstance(ctx context.Context) ([]string, error) {\n\tvar instanceNames []string\n\tfor k := range i.instances {\n\t\tinstanceNames = append(instanceNames, k)\n\t}\n\treturn instanceNames, nil\n}\n\nfunc (i InstanceMgr) AddInstance(ctx context.Context, name string, config []byte, configType string) error {\n\tcoreConfig, err := core.LoadConfig(configType, config)\n\tif err != nil {\n\t\treturn newError(\"unable to load config\").Base(err)\n\t}\n\tinstance, err := core.New(coreConfig)\n\tif err != nil {\n\t\treturn newError(\"unable to create instance\").Base(err)\n\t}\n\ti.instances[name] = instance\n\treturn nil\n}\n\nfunc (i InstanceMgr) StartInstance(ctx context.Context, name string) error {\n\terr := i.instances[name].Start()\n\tif err != nil {\n\t\treturn newError(\"failed to start instance\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc (i InstanceMgr) StopInstance(ctx context.Context, name string) error {\n\terr := i.instances[name].Close()\n\tif err != nil {\n\t\treturn newError(\"failed to stop instance\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc (i InstanceMgr) UntrackInstance(ctx context.Context, name string) error {\n\tdelete(i.instances, name)\n\treturn nil\n}\n\nfunc NewInstanceMgr(ctx context.Context, config *Config) (extension.InstanceManagement, error) {\n\treturn InstanceMgr{instances: map[string]*core.Instance{}}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tvar f extension.InstanceManagement\n\t\tvar err error\n\t\tif f, err = NewInstanceMgr(ctx, config.(*Config)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn f, nil\n\t}))\n}\n"
  },
  {
    "path": "app/log/command/command.go",
    "content": "package command\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\tgrpc \"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tcmlog \"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\n// LoggerServer is the implemention of LoggerService\ntype LoggerServer struct {\n\tV *core.Instance\n}\n\n// RestartLogger implements LoggerService.\nfunc (s *LoggerServer) RestartLogger(ctx context.Context, request *RestartLoggerRequest) (*RestartLoggerResponse, error) {\n\tlogger := s.V.GetFeature((*log.Instance)(nil))\n\tif logger == nil {\n\t\treturn nil, newError(\"unable to get logger instance\")\n\t}\n\tif err := logger.Close(); err != nil {\n\t\treturn nil, newError(\"failed to close logger\").Base(err)\n\t}\n\tif err := logger.Start(); err != nil {\n\t\treturn nil, newError(\"failed to start logger\").Base(err)\n\t}\n\treturn &RestartLoggerResponse{}, nil\n}\n\n// FollowLog implements LoggerService.\nfunc (s *LoggerServer) FollowLog(_ *FollowLogRequest, stream LoggerService_FollowLogServer) error {\n\tlogger := s.V.GetFeature((*log.Instance)(nil))\n\tif logger == nil {\n\t\treturn newError(\"unable to get logger instance\")\n\t}\n\tfollower, ok := logger.(cmlog.Follower)\n\tif !ok {\n\t\treturn newError(\"logger not support following\")\n\t}\n\tctx, cancel := context.WithCancel(stream.Context())\n\tdefer cancel()\n\tf := func(msg cmlog.Message) {\n\t\terr := stream.Send(&FollowLogResponse{\n\t\t\tMessage: msg.String(),\n\t\t})\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t}\n\t}\n\tfollower.AddFollower(f)\n\tdefer follower.RemoveFollower(f)\n\t<-ctx.Done()\n\treturn nil\n}\n\nfunc (s *LoggerServer) mustEmbedUnimplementedLoggerServiceServer() {}\n\ntype service struct {\n\tv *core.Instance\n}\n\nfunc (s *service) Register(server *grpc.Server) {\n\tRegisterLoggerServiceServer(server, &LoggerServer{\n\t\tV: s.v,\n\t})\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\ts := core.MustFromContext(ctx)\n\t\treturn &service{v: s}, nil\n\t}))\n}\n"
  },
  {
    "path": "app/log/command/command_test.go",
    "content": "package command_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t. \"github.com/v2fly/v2ray-core/v5/app/log/command\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc TestLoggerRestart(t *testing.T) {\n\tv, err := core.New(&core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t})\n\tcommon.Must(err)\n\tcommon.Must(v.Start())\n\n\tserver := &LoggerServer{\n\t\tV: v,\n\t}\n\tcommon.Must2(server.RestartLogger(context.Background(), &RestartLoggerRequest{}))\n}\n"
  },
  {
    "path": "app/log/command/config.pb.go",
    "content": "package command\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_log_command_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_command_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_log_command_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype RestartLoggerRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RestartLoggerRequest) Reset() {\n\t*x = RestartLoggerRequest{}\n\tmi := &file_app_log_command_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RestartLoggerRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RestartLoggerRequest) ProtoMessage() {}\n\nfunc (x *RestartLoggerRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_command_config_proto_msgTypes[1]\n\tif 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 RestartLoggerRequest.ProtoReflect.Descriptor instead.\nfunc (*RestartLoggerRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_log_command_config_proto_rawDescGZIP(), []int{1}\n}\n\ntype RestartLoggerResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RestartLoggerResponse) Reset() {\n\t*x = RestartLoggerResponse{}\n\tmi := &file_app_log_command_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RestartLoggerResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RestartLoggerResponse) ProtoMessage() {}\n\nfunc (x *RestartLoggerResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_command_config_proto_msgTypes[2]\n\tif 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 RestartLoggerResponse.ProtoReflect.Descriptor instead.\nfunc (*RestartLoggerResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_log_command_config_proto_rawDescGZIP(), []int{2}\n}\n\ntype FollowLogRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *FollowLogRequest) Reset() {\n\t*x = FollowLogRequest{}\n\tmi := &file_app_log_command_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *FollowLogRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FollowLogRequest) ProtoMessage() {}\n\nfunc (x *FollowLogRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_command_config_proto_msgTypes[3]\n\tif 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 FollowLogRequest.ProtoReflect.Descriptor instead.\nfunc (*FollowLogRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_log_command_config_proto_rawDescGZIP(), []int{3}\n}\n\ntype FollowLogResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tMessage       string                 `protobuf:\"bytes,1,opt,name=message,proto3\" json:\"message,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *FollowLogResponse) Reset() {\n\t*x = FollowLogResponse{}\n\tmi := &file_app_log_command_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *FollowLogResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FollowLogResponse) ProtoMessage() {}\n\nfunc (x *FollowLogResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_command_config_proto_msgTypes[4]\n\tif 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 FollowLogResponse.ProtoReflect.Descriptor instead.\nfunc (*FollowLogResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_log_command_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *FollowLogResponse) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\nvar File_app_log_command_config_proto protoreflect.FileDescriptor\n\nconst file_app_log_command_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1capp/log/command/config.proto\\x12\\x1av2ray.core.app.log.command\\\"\\b\\n\" +\n\t\"\\x06Config\\\"\\x16\\n\" +\n\t\"\\x14RestartLoggerRequest\\\"\\x17\\n\" +\n\t\"\\x15RestartLoggerResponse\\\"\\x12\\n\" +\n\t\"\\x10FollowLogRequest\\\"-\\n\" +\n\t\"\\x11FollowLogResponse\\x12\\x18\\n\" +\n\t\"\\amessage\\x18\\x01 \\x01(\\tR\\amessage2\\xf5\\x01\\n\" +\n\t\"\\rLoggerService\\x12v\\n\" +\n\t\"\\rRestartLogger\\x120.v2ray.core.app.log.command.RestartLoggerRequest\\x1a1.v2ray.core.app.log.command.RestartLoggerResponse\\\"\\x00\\x12l\\n\" +\n\t\"\\tFollowLog\\x12,.v2ray.core.app.log.command.FollowLogRequest\\x1a-.v2ray.core.app.log.command.FollowLogResponse\\\"\\x000\\x01Bo\\n\" +\n\t\"\\x1ecom.v2ray.core.app.log.commandP\\x01Z.github.com/v2fly/v2ray-core/v5/app/log/command\\xaa\\x02\\x1aV2Ray.Core.App.Log.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_log_command_config_proto_rawDescOnce sync.Once\n\tfile_app_log_command_config_proto_rawDescData []byte\n)\n\nfunc file_app_log_command_config_proto_rawDescGZIP() []byte {\n\tfile_app_log_command_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_log_command_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_log_command_config_proto_rawDesc), len(file_app_log_command_config_proto_rawDesc)))\n\t})\n\treturn file_app_log_command_config_proto_rawDescData\n}\n\nvar file_app_log_command_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)\nvar file_app_log_command_config_proto_goTypes = []any{\n\t(*Config)(nil),                // 0: v2ray.core.app.log.command.Config\n\t(*RestartLoggerRequest)(nil),  // 1: v2ray.core.app.log.command.RestartLoggerRequest\n\t(*RestartLoggerResponse)(nil), // 2: v2ray.core.app.log.command.RestartLoggerResponse\n\t(*FollowLogRequest)(nil),      // 3: v2ray.core.app.log.command.FollowLogRequest\n\t(*FollowLogResponse)(nil),     // 4: v2ray.core.app.log.command.FollowLogResponse\n}\nvar file_app_log_command_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.app.log.command.LoggerService.RestartLogger:input_type -> v2ray.core.app.log.command.RestartLoggerRequest\n\t3, // 1: v2ray.core.app.log.command.LoggerService.FollowLog:input_type -> v2ray.core.app.log.command.FollowLogRequest\n\t2, // 2: v2ray.core.app.log.command.LoggerService.RestartLogger:output_type -> v2ray.core.app.log.command.RestartLoggerResponse\n\t4, // 3: v2ray.core.app.log.command.LoggerService.FollowLog:output_type -> v2ray.core.app.log.command.FollowLogResponse\n\t2, // [2:4] is the sub-list for method output_type\n\t0, // [0:2] 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_app_log_command_config_proto_init() }\nfunc file_app_log_command_config_proto_init() {\n\tif File_app_log_command_config_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: unsafe.Slice(unsafe.StringData(file_app_log_command_config_proto_rawDesc), len(file_app_log_command_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   5,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_log_command_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_log_command_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_log_command_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_log_command_config_proto = out.File\n\tfile_app_log_command_config_proto_goTypes = nil\n\tfile_app_log_command_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/log/command/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.log.command;\noption csharp_namespace = \"V2Ray.Core.App.Log.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/log/command\";\noption java_package = \"com.v2ray.core.app.log.command\";\noption java_multiple_files = true;\n\nmessage Config {}\n\nmessage RestartLoggerRequest {}\n\nmessage RestartLoggerResponse {}\n\nmessage FollowLogRequest {}\n\nmessage FollowLogResponse {\n  string message = 1;\n}\n\nservice LoggerService {\n  rpc RestartLogger(RestartLoggerRequest) returns (RestartLoggerResponse) {}\n\n  //Unstable interface\n  rpc FollowLog(FollowLogRequest) returns (stream FollowLogResponse) {};\n}\n"
  },
  {
    "path": "app/log/command/config_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tLoggerService_RestartLogger_FullMethodName = \"/v2ray.core.app.log.command.LoggerService/RestartLogger\"\n\tLoggerService_FollowLog_FullMethodName     = \"/v2ray.core.app.log.command.LoggerService/FollowLog\"\n)\n\n// LoggerServiceClient is the client API for LoggerService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype LoggerServiceClient interface {\n\tRestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error)\n\t// Unstable interface\n\tFollowLog(ctx context.Context, in *FollowLogRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[FollowLogResponse], error)\n}\n\ntype loggerServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewLoggerServiceClient(cc grpc.ClientConnInterface) LoggerServiceClient {\n\treturn &loggerServiceClient{cc}\n}\n\nfunc (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(RestartLoggerResponse)\n\terr := c.cc.Invoke(ctx, LoggerService_RestartLogger_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *loggerServiceClient) FollowLog(ctx context.Context, in *FollowLogRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[FollowLogResponse], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &LoggerService_ServiceDesc.Streams[0], LoggerService_FollowLog_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[FollowLogRequest, FollowLogResponse]{ClientStream: stream}\n\tif err := x.ClientStream.SendMsg(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := x.ClientStream.CloseSend(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype LoggerService_FollowLogClient = grpc.ServerStreamingClient[FollowLogResponse]\n\n// LoggerServiceServer is the server API for LoggerService service.\n// All implementations must embed UnimplementedLoggerServiceServer\n// for forward compatibility.\ntype LoggerServiceServer interface {\n\tRestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error)\n\t// Unstable interface\n\tFollowLog(*FollowLogRequest, grpc.ServerStreamingServer[FollowLogResponse]) error\n\tmustEmbedUnimplementedLoggerServiceServer()\n}\n\n// UnimplementedLoggerServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedLoggerServiceServer struct{}\n\nfunc (UnimplementedLoggerServiceServer) RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error) {\n\treturn nil, status.Error(codes.Unimplemented, \"method RestartLogger not implemented\")\n}\nfunc (UnimplementedLoggerServiceServer) FollowLog(*FollowLogRequest, grpc.ServerStreamingServer[FollowLogResponse]) error {\n\treturn status.Error(codes.Unimplemented, \"method FollowLog not implemented\")\n}\nfunc (UnimplementedLoggerServiceServer) mustEmbedUnimplementedLoggerServiceServer() {}\nfunc (UnimplementedLoggerServiceServer) testEmbeddedByValue()                       {}\n\n// UnsafeLoggerServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to LoggerServiceServer will\n// result in compilation errors.\ntype UnsafeLoggerServiceServer interface {\n\tmustEmbedUnimplementedLoggerServiceServer()\n}\n\nfunc RegisterLoggerServiceServer(s grpc.ServiceRegistrar, srv LoggerServiceServer) {\n\t// If the following call panics, it indicates UnimplementedLoggerServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&LoggerService_ServiceDesc, srv)\n}\n\nfunc _LoggerService_RestartLogger_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(RestartLoggerRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(LoggerServiceServer).RestartLogger(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: LoggerService_RestartLogger_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(LoggerServiceServer).RestartLogger(ctx, req.(*RestartLoggerRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _LoggerService_FollowLog_Handler(srv interface{}, stream grpc.ServerStream) error {\n\tm := new(FollowLogRequest)\n\tif err := stream.RecvMsg(m); err != nil {\n\t\treturn err\n\t}\n\treturn srv.(LoggerServiceServer).FollowLog(m, &grpc.GenericServerStream[FollowLogRequest, FollowLogResponse]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype LoggerService_FollowLogServer = grpc.ServerStreamingServer[FollowLogResponse]\n\n// LoggerService_ServiceDesc is the grpc.ServiceDesc for LoggerService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar LoggerService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.log.command.LoggerService\",\n\tHandlerType: (*LoggerServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"RestartLogger\",\n\t\t\tHandler:    _LoggerService_RestartLogger_Handler,\n\t\t},\n\t},\n\tStreams: []grpc.StreamDesc{\n\t\t{\n\t\t\tStreamName:    \"FollowLog\",\n\t\t\tHandler:       _LoggerService_FollowLog_Handler,\n\t\t\tServerStreams: true,\n\t\t},\n\t},\n\tMetadata: \"app/log/command/config.proto\",\n}\n"
  },
  {
    "path": "app/log/command/errors.generated.go",
    "content": "package command\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/log/config.pb.go",
    "content": "package log\n\nimport (\n\tlog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 LogType int32\n\nconst (\n\tLogType_None    LogType = 0\n\tLogType_Console LogType = 1\n\tLogType_File    LogType = 2\n\tLogType_Event   LogType = 3\n)\n\n// Enum value maps for LogType.\nvar (\n\tLogType_name = map[int32]string{\n\t\t0: \"None\",\n\t\t1: \"Console\",\n\t\t2: \"File\",\n\t\t3: \"Event\",\n\t}\n\tLogType_value = map[string]int32{\n\t\t\"None\":    0,\n\t\t\"Console\": 1,\n\t\t\"File\":    2,\n\t\t\"Event\":   3,\n\t}\n)\n\nfunc (x LogType) Enum() *LogType {\n\tp := new(LogType)\n\t*p = x\n\treturn p\n}\n\nfunc (x LogType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (LogType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_log_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (LogType) Type() protoreflect.EnumType {\n\treturn &file_app_log_config_proto_enumTypes[0]\n}\n\nfunc (x LogType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use LogType.Descriptor instead.\nfunc (LogType) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_log_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype LogSpecification struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tType          LogType                `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.log.LogType\" json:\"type,omitempty\"`\n\tLevel         log.Severity           `protobuf:\"varint,2,opt,name=level,proto3,enum=v2ray.core.common.log.Severity\" json:\"level,omitempty\"`\n\tPath          string                 `protobuf:\"bytes,3,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *LogSpecification) Reset() {\n\t*x = LogSpecification{}\n\tmi := &file_app_log_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *LogSpecification) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*LogSpecification) ProtoMessage() {}\n\nfunc (x *LogSpecification) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_config_proto_msgTypes[0]\n\tif 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 LogSpecification.ProtoReflect.Descriptor instead.\nfunc (*LogSpecification) Descriptor() ([]byte, []int) {\n\treturn file_app_log_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *LogSpecification) GetType() LogType {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn LogType_None\n}\n\nfunc (x *LogSpecification) GetLevel() log.Severity {\n\tif x != nil {\n\t\treturn x.Level\n\t}\n\treturn log.Severity(0)\n}\n\nfunc (x *LogSpecification) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tError         *LogSpecification      `protobuf:\"bytes,6,opt,name=error,proto3\" json:\"error,omitempty\"`\n\tAccess        *LogSpecification      `protobuf:\"bytes,7,opt,name=access,proto3\" json:\"access,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_log_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_log_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_log_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetError() *LogSpecification {\n\tif x != nil {\n\t\treturn x.Error\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetAccess() *LogSpecification {\n\tif x != nil {\n\t\treturn x.Access\n\t}\n\treturn nil\n}\n\nvar File_app_log_config_proto protoreflect.FileDescriptor\n\nconst file_app_log_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x14app/log/config.proto\\x12\\x12v2ray.core.app.log\\x1a\\x14common/log/log.proto\\x1a common/protoext/extensions.proto\\\"\\x8e\\x01\\n\" +\n\t\"\\x10LogSpecification\\x12/\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2\\x1b.v2ray.core.app.log.LogTypeR\\x04type\\x125\\n\" +\n\t\"\\x05level\\x18\\x02 \\x01(\\x0e2\\x1f.v2ray.core.common.log.SeverityR\\x05level\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x03 \\x01(\\tR\\x04path\\\"\\xb4\\x01\\n\" +\n\t\"\\x06Config\\x12:\\n\" +\n\t\"\\x05error\\x18\\x06 \\x01(\\v2$.v2ray.core.app.log.LogSpecificationR\\x05error\\x12<\\n\" +\n\t\"\\x06access\\x18\\a \\x01(\\v2$.v2ray.core.app.log.LogSpecificationR\\x06access:\\x12\\x82\\xb5\\x18\\x0e\\n\" +\n\t\"\\aservice\\x12\\x03logJ\\x04\\b\\x01\\x10\\x02J\\x04\\b\\x02\\x10\\x03J\\x04\\b\\x03\\x10\\x04J\\x04\\b\\x04\\x10\\x05J\\x04\\b\\x05\\x10\\x06*5\\n\" +\n\t\"\\aLogType\\x12\\b\\n\" +\n\t\"\\x04None\\x10\\x00\\x12\\v\\n\" +\n\t\"\\aConsole\\x10\\x01\\x12\\b\\n\" +\n\t\"\\x04File\\x10\\x02\\x12\\t\\n\" +\n\t\"\\x05Event\\x10\\x03BW\\n\" +\n\t\"\\x16com.v2ray.core.app.logP\\x01Z&github.com/v2fly/v2ray-core/v5/app/log\\xaa\\x02\\x12V2Ray.Core.App.Logb\\x06proto3\"\n\nvar (\n\tfile_app_log_config_proto_rawDescOnce sync.Once\n\tfile_app_log_config_proto_rawDescData []byte\n)\n\nfunc file_app_log_config_proto_rawDescGZIP() []byte {\n\tfile_app_log_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_log_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_log_config_proto_rawDesc), len(file_app_log_config_proto_rawDesc)))\n\t})\n\treturn file_app_log_config_proto_rawDescData\n}\n\nvar file_app_log_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_app_log_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_app_log_config_proto_goTypes = []any{\n\t(LogType)(0),             // 0: v2ray.core.app.log.LogType\n\t(*LogSpecification)(nil), // 1: v2ray.core.app.log.LogSpecification\n\t(*Config)(nil),           // 2: v2ray.core.app.log.Config\n\t(log.Severity)(0),        // 3: v2ray.core.common.log.Severity\n}\nvar file_app_log_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.log.LogSpecification.type:type_name -> v2ray.core.app.log.LogType\n\t3, // 1: v2ray.core.app.log.LogSpecification.level:type_name -> v2ray.core.common.log.Severity\n\t1, // 2: v2ray.core.app.log.Config.error:type_name -> v2ray.core.app.log.LogSpecification\n\t1, // 3: v2ray.core.app.log.Config.access:type_name -> v2ray.core.app.log.LogSpecification\n\t4, // [4:4] is the sub-list for method output_type\n\t4, // [4:4] is the sub-list for method input_type\n\t4, // [4:4] is the sub-list for extension type_name\n\t4, // [4:4] is the sub-list for extension extendee\n\t0, // [0:4] is the sub-list for field type_name\n}\n\nfunc init() { file_app_log_config_proto_init() }\nfunc file_app_log_config_proto_init() {\n\tif File_app_log_config_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: unsafe.Slice(unsafe.StringData(file_app_log_config_proto_rawDesc), len(file_app_log_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_log_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_log_config_proto_depIdxs,\n\t\tEnumInfos:         file_app_log_config_proto_enumTypes,\n\t\tMessageInfos:      file_app_log_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_log_config_proto = out.File\n\tfile_app_log_config_proto_goTypes = nil\n\tfile_app_log_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/log/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.log;\noption csharp_namespace = \"V2Ray.Core.App.Log\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/log\";\noption java_package = \"com.v2ray.core.app.log\";\noption java_multiple_files = true;\n\nimport \"common/log/log.proto\";\nimport \"common/protoext/extensions.proto\";\n\nenum LogType {\n  None = 0;\n  Console = 1;\n  File = 2;\n  Event = 3;\n}\n\nmessage LogSpecification {\n  LogType type = 1;\n  v2ray.core.common.log.Severity level = 2;\n  string path = 3;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"log\";\n\n  reserved 1,2,3,4,5;\n\n  LogSpecification error = 6;\n  LogSpecification access = 7;\n}\n"
  },
  {
    "path": "app/log/errors.generated.go",
    "content": "package log\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/log/log.go",
    "content": "package log\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\n// Instance is a log.Handler that handles logs.\ntype Instance struct {\n\tsync.RWMutex\n\tconfig       *Config\n\taccessLogger log.Handler\n\terrorLogger  log.Handler\n\tfollowers    map[reflect.Value]func(msg log.Message)\n\tactive       bool\n}\n\n// New creates a new log.Instance based on the given config.\nfunc New(ctx context.Context, config *Config) (*Instance, error) {\n\tif config.Error == nil {\n\t\tconfig.Error = &LogSpecification{Type: LogType_Console, Level: log.Severity_Warning}\n\t}\n\n\tif config.Access == nil {\n\t\tconfig.Access = &LogSpecification{Type: LogType_None}\n\t}\n\n\tg := &Instance{\n\t\tconfig: config,\n\t\tactive: false,\n\t}\n\tlog.RegisterHandler(g)\n\n\t// start logger instantly on inited\n\t// other modules would log during init\n\tif err := g.startInternal(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tnewError(\"Logger started\").AtDebug().WriteToLog()\n\treturn g, nil\n}\n\nfunc (g *Instance) initAccessLogger() error {\n\thandler, err := createHandler(g.config.Access.Type, HandlerCreatorOptions{\n\t\tPath: g.config.Access.Path,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tg.accessLogger = handler\n\treturn nil\n}\n\nfunc (g *Instance) initErrorLogger() error {\n\thandler, err := createHandler(g.config.Error.Type, HandlerCreatorOptions{\n\t\tPath: g.config.Error.Path,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tg.errorLogger = handler\n\treturn nil\n}\n\n// Type implements common.HasType.\nfunc (*Instance) Type() interface{} {\n\treturn (*Instance)(nil)\n}\n\nfunc (g *Instance) startInternal() error {\n\tg.Lock()\n\tdefer g.Unlock()\n\n\tif g.active {\n\t\treturn nil\n\t}\n\n\tg.active = true\n\n\tif err := g.initAccessLogger(); err != nil {\n\t\treturn newError(\"failed to initialize access logger\").Base(err).AtWarning()\n\t}\n\tif err := g.initErrorLogger(); err != nil {\n\t\treturn newError(\"failed to initialize error logger\").Base(err).AtWarning()\n\t}\n\n\treturn nil\n}\n\n// Start implements common.Runnable.Start().\nfunc (g *Instance) Start() error {\n\treturn g.startInternal()\n}\n\n// AddFollower implements log.Follower.\nfunc (g *Instance) AddFollower(f func(msg log.Message)) {\n\tg.Lock()\n\tdefer g.Unlock()\n\tif g.followers == nil {\n\t\tg.followers = make(map[reflect.Value]func(msg log.Message))\n\t}\n\tg.followers[reflect.ValueOf(f)] = f\n}\n\n// RemoveFollower implements log.Follower.\nfunc (g *Instance) RemoveFollower(f func(msg log.Message)) {\n\tg.Lock()\n\tdefer g.Unlock()\n\tdelete(g.followers, reflect.ValueOf(f))\n}\n\n// Handle implements log.Handler.\nfunc (g *Instance) Handle(msg log.Message) {\n\tg.RLock()\n\tdefer g.RUnlock()\n\n\tif !g.active {\n\t\treturn\n\t}\n\n\tfor _, f := range g.followers {\n\t\tf(msg)\n\t}\n\n\tswitch msg := msg.(type) {\n\tcase *log.AccessMessage:\n\t\tif g.accessLogger != nil {\n\t\t\tg.accessLogger.Handle(msg)\n\t\t}\n\tcase *log.GeneralMessage:\n\t\tif g.errorLogger != nil && msg.Severity <= g.config.Error.Level {\n\t\t\tg.errorLogger.Handle(msg)\n\t\t}\n\tdefault:\n\t\t// Swallow\n\t}\n}\n\n// Close implements common.Closable.Close().\nfunc (g *Instance) Close() error {\n\tnewError(\"Logger closing\").AtDebug().WriteToLog()\n\n\tg.Lock()\n\tdefer g.Unlock()\n\n\tif !g.active {\n\t\treturn nil\n\t}\n\n\tg.active = false\n\n\tcommon.Close(g.accessLogger)\n\tg.accessLogger = nil\n\n\tcommon.Close(g.errorLogger)\n\tg.errorLogger = nil\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/log/log_creator.go",
    "content": "package log\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\ntype HandlerCreatorOptions struct {\n\tPath string\n}\n\ntype HandlerCreator func(LogType, HandlerCreatorOptions) (log.Handler, error)\n\nvar handlerCreatorMap = make(map[LogType]HandlerCreator)\n\nfunc RegisterHandlerCreator(logType LogType, f HandlerCreator) error {\n\tif f == nil {\n\t\treturn newError(\"nil HandlerCreator\")\n\t}\n\n\thandlerCreatorMap[logType] = f\n\treturn nil\n}\n\nfunc createHandler(logType LogType, options HandlerCreatorOptions) (log.Handler, error) {\n\tcreator, found := handlerCreatorMap[logType]\n\tif !found {\n\t\treturn nil, newError(\"unable to create log handler for \", logType)\n\t}\n\treturn creator(logType, options)\n}\n\nfunc init() {\n\tcommon.Must(RegisterHandlerCreator(LogType_Console, func(lt LogType, options HandlerCreatorOptions) (log.Handler, error) {\n\t\treturn log.NewLogger(log.CreateStdoutLogWriter()), nil\n\t}))\n\n\tcommon.Must(RegisterHandlerCreator(LogType_File, func(lt LogType, options HandlerCreatorOptions) (log.Handler, error) {\n\t\tcreator, err := log.CreateFileLogWriter(options.Path)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn log.NewLogger(creator), nil\n\t}))\n\n\tcommon.Must(RegisterHandlerCreator(LogType_None, func(lt LogType, options HandlerCreatorOptions) (log.Handler, error) {\n\t\treturn nil, nil\n\t}))\n}\n"
  },
  {
    "path": "app/log/log_test.go",
    "content": "package log_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/mocks\"\n)\n\nfunc TestCustomLogHandler(t *testing.T) {\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tvar loggedValue []string\n\n\tmockHandler := mocks.NewLogHandler(mockCtl)\n\tmockHandler.EXPECT().Handle(gomock.Any()).AnyTimes().DoAndReturn(func(msg clog.Message) {\n\t\tloggedValue = append(loggedValue, msg.String())\n\t})\n\n\tlog.RegisterHandlerCreator(log.LogType_Console, func(lt log.LogType, options log.HandlerCreatorOptions) (clog.Handler, error) {\n\t\treturn mockHandler, nil\n\t})\n\n\tlogger, err := log.New(context.Background(), &log.Config{\n\t\tError:  &log.LogSpecification{Type: log.LogType_Console, Level: clog.Severity_Debug},\n\t\tAccess: &log.LogSpecification{Type: log.LogType_None},\n\t})\n\tcommon.Must(err)\n\n\tcommon.Must(logger.Start())\n\n\tclog.Record(&clog.GeneralMessage{\n\t\tSeverity: clog.Severity_Debug,\n\t\tContent:  \"test\",\n\t})\n\n\tif len(loggedValue) < 2 {\n\t\tt.Fatal(\"expected 2 log messages, but actually \", loggedValue)\n\t}\n\n\tif loggedValue[1] != \"[Debug] test\" {\n\t\tt.Fatal(\"expected '[Debug] test', but actually \", loggedValue[1])\n\t}\n\n\tcommon.Must(logger.Close())\n}\n"
  },
  {
    "path": "app/observatory/burst/burst.go",
    "content": "package burst\n\nimport (\n\t\"math\"\n\t\"time\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst (\n\trttFailed      = time.Duration(math.MaxInt64 - iota)\n\trttUntested    // nolint: varcheck\n\trttUnqualified // nolint: varcheck\n)\n"
  },
  {
    "path": "app/observatory/burst/burstobserver.go",
    "content": "package burst\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n)\n\ntype Observer struct {\n\tconfig *Config\n\tctx    context.Context\n\n\tstatusLock sync.Mutex // nolint: structcheck\n\thp         *HealthPing\n\n\tfinished *done.Instance\n\n\tohm outbound.Manager\n}\n\nfunc (o *Observer) GetObservation(ctx context.Context) (proto.Message, error) {\n\treturn &observatory.ObservationResult{Status: o.createResult()}, nil\n}\n\nfunc (o *Observer) createResult() []*observatory.OutboundStatus {\n\tvar result []*observatory.OutboundStatus\n\to.hp.access.Lock()\n\tdefer o.hp.access.Unlock()\n\tfor name, value := range o.hp.Results {\n\t\tstatus := observatory.OutboundStatus{\n\t\t\tAlive:           value.getStatistics().All != value.getStatistics().Fail,\n\t\t\tDelay:           value.getStatistics().Average.Milliseconds(),\n\t\t\tLastErrorReason: \"\",\n\t\t\tOutboundTag:     name,\n\t\t\tLastSeenTime:    0,\n\t\t\tLastTryTime:     0,\n\t\t\tHealthPing: &observatory.HealthPingMeasurementResult{\n\t\t\t\tAll:       int64(value.getStatistics().All),\n\t\t\t\tFail:      int64(value.getStatistics().Fail),\n\t\t\t\tDeviation: int64(value.getStatistics().Deviation),\n\t\t\t\tAverage:   int64(value.getStatistics().Average),\n\t\t\t\tMax:       int64(value.getStatistics().Max),\n\t\t\t\tMin:       int64(value.getStatistics().Min),\n\t\t\t},\n\t\t}\n\t\tresult = append(result, &status)\n\t}\n\treturn result\n}\n\nfunc (o *Observer) Type() interface{} {\n\treturn extension.ObservatoryType()\n}\n\nfunc (o *Observer) Start() error {\n\tif o.config != nil && len(o.config.SubjectSelector) != 0 {\n\t\to.finished = done.New()\n\t\to.hp.StartScheduler(func() ([]string, error) {\n\t\t\ths, ok := o.ohm.(outbound.HandlerSelector)\n\t\t\tif !ok {\n\t\t\t\treturn nil, newError(\"outbound.Manager is not a HandlerSelector\")\n\t\t\t}\n\n\t\t\toutbounds := hs.Select(o.config.SubjectSelector)\n\t\t\treturn outbounds, nil\n\t\t})\n\t}\n\treturn nil\n}\n\nfunc (o *Observer) Close() error {\n\tif o.finished != nil {\n\t\to.hp.StopScheduler()\n\t\treturn o.finished.Close()\n\t}\n\treturn nil\n}\n\nfunc New(ctx context.Context, config *Config) (*Observer, error) {\n\tvar outboundManager outbound.Manager\n\terr := core.RequireFeatures(ctx, func(om outbound.Manager) {\n\t\toutboundManager = om\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"Cannot get depended features\").Base(err)\n\t}\n\thp := NewHealthPing(ctx, config.PingConfig)\n\treturn &Observer{\n\t\tconfig: config,\n\t\tctx:    ctx,\n\t\tohm:    outboundManager,\n\t\thp:     hp,\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/observatory/burst/config.pb.go",
    "content": "package burst\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// @Document The selectors for outbound under observation\n\tSubjectSelector []string          `protobuf:\"bytes,2,rep,name=subject_selector,json=subjectSelector,proto3\" json:\"subject_selector,omitempty\"`\n\tPingConfig      *HealthPingConfig `protobuf:\"bytes,3,opt,name=ping_config,json=pingConfig,proto3\" json:\"ping_config,omitempty\"`\n\tunknownFields   protoimpl.UnknownFields\n\tsizeCache       protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_observatory_burst_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_burst_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_burst_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetSubjectSelector() []string {\n\tif x != nil {\n\t\treturn x.SubjectSelector\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetPingConfig() *HealthPingConfig {\n\tif x != nil {\n\t\treturn x.PingConfig\n\t}\n\treturn nil\n}\n\ntype HealthPingConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// destination url, need 204 for success return\n\t// default https://connectivitycheck.gstatic.com/generate_204\n\tDestination string `protobuf:\"bytes,1,opt,name=destination,proto3\" json:\"destination,omitempty\"`\n\t// connectivity check url\n\tConnectivity string `protobuf:\"bytes,2,opt,name=connectivity,proto3\" json:\"connectivity,omitempty\"`\n\t// health check interval, int64 values of time.Duration\n\tInterval int64 `protobuf:\"varint,3,opt,name=interval,proto3\" json:\"interval,omitempty\"`\n\t// sampling count is the amount of recent ping results which are kept for calculation\n\tSamplingCount int32 `protobuf:\"varint,4,opt,name=samplingCount,proto3\" json:\"samplingCount,omitempty\"`\n\t// ping timeout, int64 values of time.Duration\n\tTimeout       int64 `protobuf:\"varint,5,opt,name=timeout,proto3\" json:\"timeout,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *HealthPingConfig) Reset() {\n\t*x = HealthPingConfig{}\n\tmi := &file_app_observatory_burst_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *HealthPingConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HealthPingConfig) ProtoMessage() {}\n\nfunc (x *HealthPingConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_burst_config_proto_msgTypes[1]\n\tif 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 HealthPingConfig.ProtoReflect.Descriptor instead.\nfunc (*HealthPingConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_burst_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HealthPingConfig) GetDestination() string {\n\tif x != nil {\n\t\treturn x.Destination\n\t}\n\treturn \"\"\n}\n\nfunc (x *HealthPingConfig) GetConnectivity() string {\n\tif x != nil {\n\t\treturn x.Connectivity\n\t}\n\treturn \"\"\n}\n\nfunc (x *HealthPingConfig) GetInterval() int64 {\n\tif x != nil {\n\t\treturn x.Interval\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingConfig) GetSamplingCount() int32 {\n\tif x != nil {\n\t\treturn x.SamplingCount\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingConfig) GetTimeout() int64 {\n\tif x != nil {\n\t\treturn x.Timeout\n\t}\n\treturn 0\n}\n\nvar File_app_observatory_burst_config_proto protoreflect.FileDescriptor\n\nconst file_app_observatory_burst_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\\"app/observatory/burst/config.proto\\x12 v2ray.core.app.observatory.burst\\x1a common/protoext/extensions.proto\\\"\\xa9\\x01\\n\" +\n\t\"\\x06Config\\x12)\\n\" +\n\t\"\\x10subject_selector\\x18\\x02 \\x03(\\tR\\x0fsubjectSelector\\x12S\\n\" +\n\t\"\\vping_config\\x18\\x03 \\x01(\\v22.v2ray.core.app.observatory.burst.HealthPingConfigR\\n\" +\n\t\"pingConfig:\\x1f\\x82\\xb5\\x18\\x1b\\n\" +\n\t\"\\aservice\\x12\\x10burstObservatory\\\"\\xb4\\x01\\n\" +\n\t\"\\x10HealthPingConfig\\x12 \\n\" +\n\t\"\\vdestination\\x18\\x01 \\x01(\\tR\\vdestination\\x12\\\"\\n\" +\n\t\"\\fconnectivity\\x18\\x02 \\x01(\\tR\\fconnectivity\\x12\\x1a\\n\" +\n\t\"\\binterval\\x18\\x03 \\x01(\\x03R\\binterval\\x12$\\n\" +\n\t\"\\rsamplingCount\\x18\\x04 \\x01(\\x05R\\rsamplingCount\\x12\\x18\\n\" +\n\t\"\\atimeout\\x18\\x05 \\x01(\\x03R\\atimeoutB\\x81\\x01\\n\" +\n\t\"$com.v2ray.core.app.observatory.burstP\\x01Z4github.com/v2fly/v2ray-core/v5/app/observatory/burst\\xaa\\x02 V2Ray.Core.App.Observatory.Burstb\\x06proto3\"\n\nvar (\n\tfile_app_observatory_burst_config_proto_rawDescOnce sync.Once\n\tfile_app_observatory_burst_config_proto_rawDescData []byte\n)\n\nfunc file_app_observatory_burst_config_proto_rawDescGZIP() []byte {\n\tfile_app_observatory_burst_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_observatory_burst_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_observatory_burst_config_proto_rawDesc), len(file_app_observatory_burst_config_proto_rawDesc)))\n\t})\n\treturn file_app_observatory_burst_config_proto_rawDescData\n}\n\nvar file_app_observatory_burst_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_app_observatory_burst_config_proto_goTypes = []any{\n\t(*Config)(nil),           // 0: v2ray.core.app.observatory.burst.Config\n\t(*HealthPingConfig)(nil), // 1: v2ray.core.app.observatory.burst.HealthPingConfig\n}\nvar file_app_observatory_burst_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.app.observatory.burst.Config.ping_config:type_name -> v2ray.core.app.observatory.burst.HealthPingConfig\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_observatory_burst_config_proto_init() }\nfunc file_app_observatory_burst_config_proto_init() {\n\tif File_app_observatory_burst_config_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: unsafe.Slice(unsafe.StringData(file_app_observatory_burst_config_proto_rawDesc), len(file_app_observatory_burst_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_observatory_burst_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_observatory_burst_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_observatory_burst_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_observatory_burst_config_proto = out.File\n\tfile_app_observatory_burst_config_proto_goTypes = nil\n\tfile_app_observatory_burst_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/observatory/burst/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.observatory.burst;\noption csharp_namespace = \"V2Ray.Core.App.Observatory.Burst\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/observatory/burst\";\noption java_package = \"com.v2ray.core.app.observatory.burst\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"burstObservatory\";\n\n  /* @Document The selectors for outbound under observation\n  */\n  repeated string subject_selector = 2;\n\n  HealthPingConfig ping_config = 3;\n}\n\nmessage HealthPingConfig {\n  // destination url, need 204 for success return\n  // default https://connectivitycheck.gstatic.com/generate_204\n  string destination = 1;\n  // connectivity check url\n  string connectivity = 2;\n  // health check interval, int64 values of time.Duration\n  int64 interval = 3;\n  // sampling count is the amount of recent ping results which are kept for calculation\n  int32 samplingCount = 4;\n  // ping timeout, int64 values of time.Duration\n  int64 timeout = 5;\n}\n"
  },
  {
    "path": "app/observatory/burst/errors.generated.go",
    "content": "package burst\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/observatory/burst/healthping.go",
    "content": "package burst\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\n// HealthPingSettings holds settings for health Checker\ntype HealthPingSettings struct {\n\tDestination   string        `json:\"destination\"`\n\tConnectivity  string        `json:\"connectivity\"`\n\tInterval      time.Duration `json:\"interval\"`\n\tSamplingCount int           `json:\"sampling\"`\n\tTimeout       time.Duration `json:\"timeout\"`\n}\n\n// HealthPing is the health checker for balancers\ntype HealthPing struct {\n\tctx         context.Context\n\taccess      sync.Mutex\n\tticker      *time.Ticker\n\ttickerClose chan struct{}\n\n\tSettings *HealthPingSettings\n\tResults  map[string]*HealthPingRTTS\n}\n\n// NewHealthPing creates a new HealthPing with settings\nfunc NewHealthPing(ctx context.Context, config *HealthPingConfig) *HealthPing {\n\tsettings := &HealthPingSettings{}\n\tif config != nil {\n\t\tsettings = &HealthPingSettings{\n\t\t\tConnectivity:  strings.TrimSpace(config.Connectivity),\n\t\t\tDestination:   strings.TrimSpace(config.Destination),\n\t\t\tInterval:      time.Duration(config.Interval),\n\t\t\tSamplingCount: int(config.SamplingCount),\n\t\t\tTimeout:       time.Duration(config.Timeout),\n\t\t}\n\t}\n\tif settings.Destination == \"\" {\n\t\t// Destination URL, need 204 for success return default to chromium\n\t\t// https://github.com/chromium/chromium/blob/main/components/safety_check/url_constants.cc#L10\n\t\t// https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/safety_check/url_constants.cc#10\n\t\tsettings.Destination = \"https://connectivitycheck.gstatic.com/generate_204\"\n\t}\n\tif settings.Interval == 0 {\n\t\tsettings.Interval = time.Duration(1) * time.Minute\n\t} else if settings.Interval < 10 {\n\t\tnewError(\"health check interval is too small, 10s is applied\").AtWarning().WriteToLog()\n\t\tsettings.Interval = time.Duration(10) * time.Second\n\t}\n\tif settings.SamplingCount <= 0 {\n\t\tsettings.SamplingCount = 10\n\t}\n\tif settings.Timeout <= 0 {\n\t\t// results are saved after all health pings finish,\n\t\t// a larger timeout could possibly makes checks run longer\n\t\tsettings.Timeout = time.Duration(5) * time.Second\n\t}\n\treturn &HealthPing{\n\t\tctx:      ctx,\n\t\tSettings: settings,\n\t\tResults:  nil,\n\t}\n}\n\n// StartScheduler implements the HealthChecker\nfunc (h *HealthPing) StartScheduler(selector func() ([]string, error)) {\n\tif h.ticker != nil {\n\t\treturn\n\t}\n\tinterval := h.Settings.Interval * time.Duration(h.Settings.SamplingCount)\n\tticker := time.NewTicker(interval)\n\ttickerClose := make(chan struct{})\n\th.ticker = ticker\n\th.tickerClose = tickerClose\n\tgo func() {\n\t\tfor {\n\t\t\tgo func() {\n\t\t\t\ttags, err := selector()\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"error select outbounds for scheduled health check: \", err).AtWarning().WriteToLog()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\th.doCheck(tags, interval, h.Settings.SamplingCount)\n\t\t\t\th.Cleanup(tags)\n\t\t\t}()\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\tcontinue\n\t\t\tcase <-tickerClose:\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\n// StopScheduler implements the HealthChecker\nfunc (h *HealthPing) StopScheduler() {\n\tif h.ticker == nil {\n\t\treturn\n\t}\n\th.ticker.Stop()\n\th.ticker = nil\n\tclose(h.tickerClose)\n\th.tickerClose = nil\n}\n\n// Check implements the HealthChecker\nfunc (h *HealthPing) Check(tags []string) error {\n\tif len(tags) == 0 {\n\t\treturn nil\n\t}\n\tnewError(\"perform one-time health check for tags \", tags).AtInfo().WriteToLog()\n\th.doCheck(tags, 0, 1)\n\treturn nil\n}\n\ntype rtt struct {\n\thandler string\n\tvalue   time.Duration\n}\n\n// doCheck performs the 'rounds' amount checks in given 'duration'. You should make\n// sure all tags are valid for current balancer\nfunc (h *HealthPing) doCheck(tags []string, duration time.Duration, rounds int) {\n\tcount := len(tags) * rounds\n\tif count == 0 {\n\t\treturn\n\t}\n\tch := make(chan *rtt, count)\n\n\tfor _, tag := range tags {\n\t\thandler := tag\n\t\tclient := newPingClient(\n\t\t\th.ctx,\n\t\t\th.Settings.Destination,\n\t\t\th.Settings.Timeout,\n\t\t\thandler,\n\t\t)\n\t\tfor i := 0; i < rounds; i++ {\n\t\t\tdelay := time.Duration(0)\n\t\t\tif duration > 0 {\n\t\t\t\tdelay = time.Duration(dice.Roll(int(duration)))\n\t\t\t}\n\t\t\ttime.AfterFunc(delay, func() {\n\t\t\t\tnewError(\"checking \", handler).AtDebug().WriteToLog()\n\t\t\t\tdelay, err := client.MeasureDelay()\n\t\t\t\tif err == nil {\n\t\t\t\t\tch <- &rtt{\n\t\t\t\t\t\thandler: handler,\n\t\t\t\t\t\tvalue:   delay,\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif !h.checkConnectivity() {\n\t\t\t\t\tnewError(\"network is down\").AtWarning().WriteToLog()\n\t\t\t\t\tch <- &rtt{\n\t\t\t\t\t\thandler: handler,\n\t\t\t\t\t\tvalue:   0,\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tnewError(fmt.Sprintf(\n\t\t\t\t\t\"error ping %s with %s: %s\",\n\t\t\t\t\th.Settings.Destination,\n\t\t\t\t\thandler,\n\t\t\t\t\terr,\n\t\t\t\t)).AtWarning().WriteToLog()\n\t\t\t\tch <- &rtt{\n\t\t\t\t\thandler: handler,\n\t\t\t\t\tvalue:   rttFailed,\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\tfor i := 0; i < count; i++ {\n\t\trtt := <-ch\n\t\tif rtt.value > 0 {\n\t\t\t// should not put results when network is down\n\t\t\th.PutResult(rtt.handler, rtt.value)\n\t\t}\n\t}\n}\n\n// PutResult puts a ping rtt to results\nfunc (h *HealthPing) PutResult(tag string, rtt time.Duration) {\n\th.access.Lock()\n\tdefer h.access.Unlock()\n\tif h.Results == nil {\n\t\th.Results = make(map[string]*HealthPingRTTS)\n\t}\n\tr, ok := h.Results[tag]\n\tif !ok {\n\t\t// validity is 2 times to sampling period, since the check are\n\t\t// distributed in the time line randomly, in extreme cases,\n\t\t// previous checks are distributed on the left, and latters\n\t\t// on the right\n\t\tvalidity := h.Settings.Interval * time.Duration(h.Settings.SamplingCount) * 2\n\t\tr = NewHealthPingResult(h.Settings.SamplingCount, validity)\n\t\th.Results[tag] = r\n\t}\n\tr.Put(rtt)\n}\n\n// Cleanup removes results of removed handlers,\n// tags should be all valid tags of the Balancer now\nfunc (h *HealthPing) Cleanup(tags []string) {\n\th.access.Lock()\n\tdefer h.access.Unlock()\n\tfor tag := range h.Results {\n\t\tfound := false\n\t\tfor _, v := range tags {\n\t\t\tif tag == v {\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\tdelete(h.Results, tag)\n\t\t}\n\t}\n}\n\n// checkConnectivity checks the network connectivity, it returns\n// true if network is good or \"connectivity check url\" not set\nfunc (h *HealthPing) checkConnectivity() bool {\n\tif h.Settings.Connectivity == \"\" {\n\t\treturn true\n\t}\n\ttester := newDirectPingClient(\n\t\th.Settings.Connectivity,\n\t\th.Settings.Timeout,\n\t)\n\tif _, err := tester.MeasureDelay(); err != nil {\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "app/observatory/burst/healthping_result.go",
    "content": "package burst\n\nimport (\n\t\"math\"\n\t\"time\"\n)\n\n// HealthPingStats is the statistics of HealthPingRTTS\ntype HealthPingStats struct {\n\tAll       int\n\tFail      int\n\tDeviation time.Duration\n\tAverage   time.Duration\n\tMax       time.Duration\n\tMin       time.Duration\n}\n\n// HealthPingRTTS holds ping rtts for health Checker\ntype HealthPingRTTS struct {\n\tidx      int\n\tcap      int\n\tvalidity time.Duration\n\trtts     []*pingRTT\n\n\tlastUpdateAt time.Time\n\tstats        *HealthPingStats\n}\n\ntype pingRTT struct {\n\ttime  time.Time\n\tvalue time.Duration\n}\n\n// NewHealthPingResult returns a *HealthPingResult with specified capacity\nfunc NewHealthPingResult(cap int, validity time.Duration) *HealthPingRTTS {\n\treturn &HealthPingRTTS{cap: cap, validity: validity}\n}\n\n// Get gets statistics of the HealthPingRTTS\nfunc (h *HealthPingRTTS) Get() *HealthPingStats {\n\treturn h.getStatistics()\n}\n\n// GetWithCache get statistics and write cache for next call\n// Make sure use Mutex.Lock() before calling it, RWMutex.RLock()\n// is not an option since it writes cache\nfunc (h *HealthPingRTTS) GetWithCache() *HealthPingStats {\n\tlastPutAt := h.rtts[h.idx].time\n\tnow := time.Now()\n\tif h.stats == nil || h.lastUpdateAt.Before(lastPutAt) || h.findOutdated(now) >= 0 {\n\t\th.stats = h.getStatistics()\n\t\th.lastUpdateAt = now\n\t}\n\treturn h.stats\n}\n\n// Put puts a new rtt to the HealthPingResult\nfunc (h *HealthPingRTTS) Put(d time.Duration) {\n\tif h.rtts == nil {\n\t\th.rtts = make([]*pingRTT, h.cap)\n\t\tfor i := 0; i < h.cap; i++ {\n\t\t\th.rtts[i] = &pingRTT{}\n\t\t}\n\t\th.idx = -1\n\t}\n\th.idx = h.calcIndex(1)\n\tnow := time.Now()\n\th.rtts[h.idx].time = now\n\th.rtts[h.idx].value = d\n}\n\nfunc (h *HealthPingRTTS) calcIndex(step int) int {\n\tidx := h.idx\n\tidx += step\n\tif idx >= h.cap {\n\t\tidx %= h.cap\n\t}\n\treturn idx\n}\n\nfunc (h *HealthPingRTTS) getStatistics() *HealthPingStats {\n\tstats := &HealthPingStats{}\n\tstats.Fail = 0\n\tstats.Max = 0\n\tstats.Min = rttFailed\n\tsum := time.Duration(0)\n\tcnt := 0\n\tvalidRTTs := make([]time.Duration, 0)\n\tfor _, rtt := range h.rtts {\n\t\tswitch {\n\t\tcase rtt.value == 0 || time.Since(rtt.time) > h.validity:\n\t\t\tcontinue\n\t\tcase rtt.value == rttFailed:\n\t\t\tstats.Fail++\n\t\t\tcontinue\n\t\t}\n\t\tcnt++\n\t\tsum += rtt.value\n\t\tvalidRTTs = append(validRTTs, rtt.value)\n\t\tif stats.Max < rtt.value {\n\t\t\tstats.Max = rtt.value\n\t\t}\n\t\tif stats.Min > rtt.value {\n\t\t\tstats.Min = rtt.value\n\t\t}\n\t}\n\tstats.All = cnt + stats.Fail\n\tif cnt == 0 {\n\t\tstats.Min = 0\n\t\treturn stats\n\t}\n\tstats.Average = time.Duration(int(sum) / cnt)\n\tvar std float64\n\tif cnt < 2 {\n\t\t// no enough data for standard deviation, we assume it's half of the average rtt\n\t\t// if we don't do this, standard deviation of 1 round tested nodes is 0, will always\n\t\t// selected before 2 or more rounds tested nodes\n\t\tstd = float64(stats.Average / 2)\n\t} else {\n\t\tvariance := float64(0)\n\t\tfor _, rtt := range validRTTs {\n\t\t\tvariance += math.Pow(float64(rtt-stats.Average), 2)\n\t\t}\n\t\tstd = math.Sqrt(variance / float64(cnt))\n\t}\n\tstats.Deviation = time.Duration(std)\n\treturn stats\n}\n\nfunc (h *HealthPingRTTS) findOutdated(now time.Time) int {\n\tfor i := h.cap - 1; i < 2*h.cap; i++ {\n\t\t// from oldest to latest\n\t\tidx := h.calcIndex(i)\n\t\tvalidity := h.rtts[idx].time.Add(h.validity)\n\t\tif h.lastUpdateAt.After(validity) {\n\t\t\treturn idx\n\t\t}\n\t\tif validity.Before(now) {\n\t\t\treturn idx\n\t\t}\n\t}\n\treturn -1\n}\n"
  },
  {
    "path": "app/observatory/burst/healthping_result_test.go",
    "content": "package burst_test\n\nimport (\n\t\"math\"\n\treflect \"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory/burst\"\n)\n\nfunc TestHealthPingResults(t *testing.T) {\n\trtts := []int64{60, 140, 60, 140, 60, 60, 140, 60, 140}\n\thr := burst.NewHealthPingResult(4, time.Hour)\n\tfor _, rtt := range rtts {\n\t\thr.Put(time.Duration(rtt))\n\t}\n\trttFailed := time.Duration(math.MaxInt64)\n\texpected := &burst.HealthPingStats{\n\t\tAll:       4,\n\t\tFail:      0,\n\t\tDeviation: 40,\n\t\tAverage:   100,\n\t\tMax:       140,\n\t\tMin:       60,\n\t}\n\tactual := hr.Get()\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, actual)\n\t}\n\thr.Put(rttFailed)\n\thr.Put(rttFailed)\n\texpected.Fail = 2\n\tactual = hr.Get()\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"failed half-failures test, expected: %v, actual: %v\", expected, actual)\n\t}\n\thr.Put(rttFailed)\n\thr.Put(rttFailed)\n\texpected = &burst.HealthPingStats{\n\t\tAll:       4,\n\t\tFail:      4,\n\t\tDeviation: 0,\n\t\tAverage:   0,\n\t\tMax:       0,\n\t\tMin:       0,\n\t}\n\tactual = hr.Get()\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"failed all-failures test, expected: %v, actual: %v\", expected, actual)\n\t}\n}\n\nfunc TestHealthPingResultsIgnoreOutdated(t *testing.T) {\n\trtts := []int64{60, 140, 60, 140}\n\thr := burst.NewHealthPingResult(4, time.Duration(10)*time.Millisecond)\n\tfor i, rtt := range rtts {\n\t\tif i == 2 {\n\t\t\t// wait for previous 2 outdated\n\t\t\ttime.Sleep(time.Duration(10) * time.Millisecond)\n\t\t}\n\t\thr.Put(time.Duration(rtt))\n\t}\n\thr.Get()\n\texpected := &burst.HealthPingStats{\n\t\tAll:       2,\n\t\tFail:      0,\n\t\tDeviation: 40,\n\t\tAverage:   100,\n\t\tMax:       140,\n\t\tMin:       60,\n\t}\n\tactual := hr.Get()\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"failed 'half-outdated' test, expected: %v, actual: %v\", expected, actual)\n\t}\n\t// wait for all outdated\n\ttime.Sleep(time.Duration(10) * time.Millisecond)\n\texpected = &burst.HealthPingStats{\n\t\tAll:       0,\n\t\tFail:      0,\n\t\tDeviation: 0,\n\t\tAverage:   0,\n\t\tMax:       0,\n\t\tMin:       0,\n\t}\n\tactual = hr.Get()\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"failed 'outdated / not-tested' test, expected: %v, actual: %v\", expected, actual)\n\t}\n\n\thr.Put(time.Duration(60))\n\texpected = &burst.HealthPingStats{\n\t\tAll:  1,\n\t\tFail: 0,\n\t\t// 1 sample, std=0.5rtt\n\t\tDeviation: 30,\n\t\tAverage:   60,\n\t\tMax:       60,\n\t\tMin:       60,\n\t}\n\tactual = hr.Get()\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, actual)\n\t}\n}\n"
  },
  {
    "path": "app/observatory/burst/ping.go",
    "content": "package burst\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\ntype pingClient struct {\n\tdestination string\n\thttpClient  *http.Client\n}\n\nfunc newPingClient(ctx context.Context, destination string, timeout time.Duration, handler string) *pingClient {\n\treturn &pingClient{\n\t\tdestination: destination,\n\t\thttpClient:  newHTTPClient(ctx, handler, timeout),\n\t}\n}\n\nfunc newDirectPingClient(destination string, timeout time.Duration) *pingClient {\n\treturn &pingClient{\n\t\tdestination: destination,\n\t\thttpClient:  &http.Client{Timeout: timeout},\n\t}\n}\n\nfunc newHTTPClient(ctxv context.Context, handler string, timeout time.Duration) *http.Client {\n\ttr := &http.Transport{\n\t\tDisableKeepAlives: true,\n\t\tDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\t\tdest, err := net.ParseDestination(network + \":\" + addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn tagged.Dialer(ctxv, dest, handler)\n\t\t},\n\t}\n\treturn &http.Client{\n\t\tTransport: tr,\n\t\tTimeout:   timeout,\n\t\t// don't follow redirect\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\treturn http.ErrUseLastResponse\n\t\t},\n\t}\n}\n\n// MeasureDelay returns the delay time of the request to dest\nfunc (s *pingClient) MeasureDelay() (time.Duration, error) {\n\tif s.httpClient == nil {\n\t\tpanic(\"pingClient no initialized\")\n\t}\n\treq, err := http.NewRequest(http.MethodHead, s.destination, nil)\n\tif err != nil {\n\t\treturn rttFailed, err\n\t}\n\tstart := time.Now()\n\tresp, err := s.httpClient.Do(req)\n\tif err != nil {\n\t\treturn rttFailed, err\n\t}\n\t// don't wait for body\n\tresp.Body.Close()\n\treturn time.Since(start), nil\n}\n"
  },
  {
    "path": "app/observatory/command/command.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage command\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\ntype service struct {\n\tUnimplementedObservatoryServiceServer\n\tv *core.Instance\n\n\tobservatory extension.Observatory\n}\n\nfunc (s *service) GetOutboundStatus(ctx context.Context, request *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) {\n\tvar result proto.Message\n\tif request.Tag == \"\" {\n\t\tobserveResult, err := s.observatory.GetObservation(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"cannot get observation\").Base(err)\n\t\t}\n\t\tresult = observeResult\n\t} else {\n\t\tif _, ok := s.observatory.(features.TaggedFeatures); !ok {\n\t\t\treturn nil, newError(\"observatory does not support tagged features\")\n\t\t}\n\t\tfet, err := s.observatory.(features.TaggedFeatures).GetFeaturesByTag(request.Tag)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"cannot get tagged observatory\").Base(err)\n\t\t}\n\t\tobserveResult, err := fet.(extension.Observatory).GetObservation(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"cannot get observation\").Base(err)\n\t\t}\n\t\tresult = observeResult\n\t}\n\tretdata := result.(*observatory.ObservationResult)\n\treturn &GetOutboundStatusResponse{\n\t\tStatus: retdata,\n\t}, nil\n}\n\nfunc (s *service) Register(server *grpc.Server) {\n\tRegisterObservatoryServiceServer(server, s)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\ts := core.MustFromContext(ctx)\n\t\tsv := &service{v: s}\n\t\terr := s.RequireFeatures(func(Observatory extension.Observatory) {\n\t\t\tsv.observatory = Observatory\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn sv, nil\n\t}))\n}\n"
  },
  {
    "path": "app/observatory/command/command.pb.go",
    "content": "package command\n\nimport (\n\tobservatory \"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 GetOutboundStatusRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=Tag,proto3\" json:\"Tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetOutboundStatusRequest) Reset() {\n\t*x = GetOutboundStatusRequest{}\n\tmi := &file_app_observatory_command_command_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetOutboundStatusRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetOutboundStatusRequest) ProtoMessage() {}\n\nfunc (x *GetOutboundStatusRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_command_command_proto_msgTypes[0]\n\tif 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 GetOutboundStatusRequest.ProtoReflect.Descriptor instead.\nfunc (*GetOutboundStatusRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_command_command_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *GetOutboundStatusRequest) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\ntype GetOutboundStatusResponse struct {\n\tstate         protoimpl.MessageState         `protogen:\"open.v1\"`\n\tStatus        *observatory.ObservationResult `protobuf:\"bytes,1,opt,name=status,proto3\" json:\"status,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetOutboundStatusResponse) Reset() {\n\t*x = GetOutboundStatusResponse{}\n\tmi := &file_app_observatory_command_command_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetOutboundStatusResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetOutboundStatusResponse) ProtoMessage() {}\n\nfunc (x *GetOutboundStatusResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_command_command_proto_msgTypes[1]\n\tif 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 GetOutboundStatusResponse.ProtoReflect.Descriptor instead.\nfunc (*GetOutboundStatusResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_command_command_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *GetOutboundStatusResponse) GetStatus() *observatory.ObservationResult {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn nil\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_observatory_command_command_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_command_command_proto_msgTypes[2]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_command_command_proto_rawDescGZIP(), []int{2}\n}\n\nvar File_app_observatory_command_command_proto protoreflect.FileDescriptor\n\nconst file_app_observatory_command_command_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"%app/observatory/command/command.proto\\x12\\\"v2ray.core.app.observatory.command\\x1a common/protoext/extensions.proto\\x1a\\x1capp/observatory/config.proto\\\",\\n\" +\n\t\"\\x18GetOutboundStatusRequest\\x12\\x10\\n\" +\n\t\"\\x03Tag\\x18\\x01 \\x01(\\tR\\x03Tag\\\"b\\n\" +\n\t\"\\x19GetOutboundStatusResponse\\x12E\\n\" +\n\t\"\\x06status\\x18\\x01 \\x01(\\v2-.v2ray.core.app.observatory.ObservationResultR\\x06status\\\"(\\n\" +\n\t\"\\x06Config:\\x1e\\x82\\xb5\\x18\\x1a\\n\" +\n\t\"\\vgrpcservice\\x12\\vobservatory2\\xa9\\x01\\n\" +\n\t\"\\x12ObservatoryService\\x12\\x92\\x01\\n\" +\n\t\"\\x11GetOutboundStatus\\x12<.v2ray.core.app.observatory.command.GetOutboundStatusRequest\\x1a=.v2ray.core.app.observatory.command.GetOutboundStatusResponse\\\"\\x00B\\x87\\x01\\n\" +\n\t\"&com.v2ray.core.app.observatory.commandP\\x01Z6github.com/v2fly/v2ray-core/v5/app/observatory/command\\xaa\\x02\\\"V2Ray.Core.App.Observatory.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_observatory_command_command_proto_rawDescOnce sync.Once\n\tfile_app_observatory_command_command_proto_rawDescData []byte\n)\n\nfunc file_app_observatory_command_command_proto_rawDescGZIP() []byte {\n\tfile_app_observatory_command_command_proto_rawDescOnce.Do(func() {\n\t\tfile_app_observatory_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_observatory_command_command_proto_rawDesc), len(file_app_observatory_command_command_proto_rawDesc)))\n\t})\n\treturn file_app_observatory_command_command_proto_rawDescData\n}\n\nvar file_app_observatory_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_app_observatory_command_command_proto_goTypes = []any{\n\t(*GetOutboundStatusRequest)(nil),      // 0: v2ray.core.app.observatory.command.GetOutboundStatusRequest\n\t(*GetOutboundStatusResponse)(nil),     // 1: v2ray.core.app.observatory.command.GetOutboundStatusResponse\n\t(*Config)(nil),                        // 2: v2ray.core.app.observatory.command.Config\n\t(*observatory.ObservationResult)(nil), // 3: v2ray.core.app.observatory.ObservationResult\n}\nvar file_app_observatory_command_command_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.app.observatory.command.GetOutboundStatusResponse.status:type_name -> v2ray.core.app.observatory.ObservationResult\n\t0, // 1: v2ray.core.app.observatory.command.ObservatoryService.GetOutboundStatus:input_type -> v2ray.core.app.observatory.command.GetOutboundStatusRequest\n\t1, // 2: v2ray.core.app.observatory.command.ObservatoryService.GetOutboundStatus:output_type -> v2ray.core.app.observatory.command.GetOutboundStatusResponse\n\t2, // [2:3] is the sub-list for method output_type\n\t1, // [1:2] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_observatory_command_command_proto_init() }\nfunc file_app_observatory_command_command_proto_init() {\n\tif File_app_observatory_command_command_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: unsafe.Slice(unsafe.StringData(file_app_observatory_command_command_proto_rawDesc), len(file_app_observatory_command_command_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_observatory_command_command_proto_goTypes,\n\t\tDependencyIndexes: file_app_observatory_command_command_proto_depIdxs,\n\t\tMessageInfos:      file_app_observatory_command_command_proto_msgTypes,\n\t}.Build()\n\tFile_app_observatory_command_command_proto = out.File\n\tfile_app_observatory_command_command_proto_goTypes = nil\n\tfile_app_observatory_command_command_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/observatory/command/command.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.observatory.command;\noption csharp_namespace = \"V2Ray.Core.App.Observatory.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/observatory/command\";\noption java_package = \"com.v2ray.core.app.observatory.command\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"app/observatory/config.proto\";\n\nmessage GetOutboundStatusRequest {\n  string Tag = 1;\n}\n\nmessage GetOutboundStatusResponse {\n  v2ray.core.app.observatory.ObservationResult status = 1;\n}\n\nservice ObservatoryService {\n  rpc GetOutboundStatus(GetOutboundStatusRequest)\n      returns (GetOutboundStatusResponse) {}\n}\n\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"observatory\";\n}"
  },
  {
    "path": "app/observatory/command/command_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tObservatoryService_GetOutboundStatus_FullMethodName = \"/v2ray.core.app.observatory.command.ObservatoryService/GetOutboundStatus\"\n)\n\n// ObservatoryServiceClient is the client API for ObservatoryService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype ObservatoryServiceClient interface {\n\tGetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error)\n}\n\ntype observatoryServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewObservatoryServiceClient(cc grpc.ClientConnInterface) ObservatoryServiceClient {\n\treturn &observatoryServiceClient{cc}\n}\n\nfunc (c *observatoryServiceClient) GetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(GetOutboundStatusResponse)\n\terr := c.cc.Invoke(ctx, ObservatoryService_GetOutboundStatus_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ObservatoryServiceServer is the server API for ObservatoryService service.\n// All implementations must embed UnimplementedObservatoryServiceServer\n// for forward compatibility.\ntype ObservatoryServiceServer interface {\n\tGetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error)\n\tmustEmbedUnimplementedObservatoryServiceServer()\n}\n\n// UnimplementedObservatoryServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedObservatoryServiceServer struct{}\n\nfunc (UnimplementedObservatoryServiceServer) GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method GetOutboundStatus not implemented\")\n}\nfunc (UnimplementedObservatoryServiceServer) mustEmbedUnimplementedObservatoryServiceServer() {}\nfunc (UnimplementedObservatoryServiceServer) testEmbeddedByValue()                            {}\n\n// UnsafeObservatoryServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to ObservatoryServiceServer will\n// result in compilation errors.\ntype UnsafeObservatoryServiceServer interface {\n\tmustEmbedUnimplementedObservatoryServiceServer()\n}\n\nfunc RegisterObservatoryServiceServer(s grpc.ServiceRegistrar, srv ObservatoryServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedObservatoryServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&ObservatoryService_ServiceDesc, srv)\n}\n\nfunc _ObservatoryService_GetOutboundStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetOutboundStatusRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ObservatoryServiceServer).GetOutboundStatus(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: ObservatoryService_GetOutboundStatus_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ObservatoryServiceServer).GetOutboundStatus(ctx, req.(*GetOutboundStatusRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// ObservatoryService_ServiceDesc is the grpc.ServiceDesc for ObservatoryService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar ObservatoryService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.observatory.command.ObservatoryService\",\n\tHandlerType: (*ObservatoryServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetOutboundStatus\",\n\t\t\tHandler:    _ObservatoryService_GetOutboundStatus_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"app/observatory/command/command.proto\",\n}\n"
  },
  {
    "path": "app/observatory/command/errors.generated.go",
    "content": "package command\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/observatory/config.pb.go",
    "content": "package observatory\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ObservationResult struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tStatus        []*OutboundStatus      `protobuf:\"bytes,1,rep,name=status,proto3\" json:\"status,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ObservationResult) Reset() {\n\t*x = ObservationResult{}\n\tmi := &file_app_observatory_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ObservationResult) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ObservationResult) ProtoMessage() {}\n\nfunc (x *ObservationResult) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_config_proto_msgTypes[0]\n\tif 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 ObservationResult.ProtoReflect.Descriptor instead.\nfunc (*ObservationResult) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ObservationResult) GetStatus() []*OutboundStatus {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn nil\n}\n\ntype HealthPingMeasurementResult struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAll           int64                  `protobuf:\"varint,1,opt,name=all,proto3\" json:\"all,omitempty\"`\n\tFail          int64                  `protobuf:\"varint,2,opt,name=fail,proto3\" json:\"fail,omitempty\"`\n\tDeviation     int64                  `protobuf:\"varint,3,opt,name=deviation,proto3\" json:\"deviation,omitempty\"`\n\tAverage       int64                  `protobuf:\"varint,4,opt,name=average,proto3\" json:\"average,omitempty\"`\n\tMax           int64                  `protobuf:\"varint,5,opt,name=max,proto3\" json:\"max,omitempty\"`\n\tMin           int64                  `protobuf:\"varint,6,opt,name=min,proto3\" json:\"min,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *HealthPingMeasurementResult) Reset() {\n\t*x = HealthPingMeasurementResult{}\n\tmi := &file_app_observatory_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *HealthPingMeasurementResult) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HealthPingMeasurementResult) ProtoMessage() {}\n\nfunc (x *HealthPingMeasurementResult) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_config_proto_msgTypes[1]\n\tif 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 HealthPingMeasurementResult.ProtoReflect.Descriptor instead.\nfunc (*HealthPingMeasurementResult) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HealthPingMeasurementResult) GetAll() int64 {\n\tif x != nil {\n\t\treturn x.All\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingMeasurementResult) GetFail() int64 {\n\tif x != nil {\n\t\treturn x.Fail\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingMeasurementResult) GetDeviation() int64 {\n\tif x != nil {\n\t\treturn x.Deviation\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingMeasurementResult) GetAverage() int64 {\n\tif x != nil {\n\t\treturn x.Average\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingMeasurementResult) GetMax() int64 {\n\tif x != nil {\n\t\treturn x.Max\n\t}\n\treturn 0\n}\n\nfunc (x *HealthPingMeasurementResult) GetMin() int64 {\n\tif x != nil {\n\t\treturn x.Min\n\t}\n\treturn 0\n}\n\ntype OutboundStatus struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// @Document Whether this outbound is usable\n\t// @Restriction ReadOnlyForUser\n\tAlive bool `protobuf:\"varint,1,opt,name=alive,proto3\" json:\"alive,omitempty\"`\n\t// @Document The time for probe request to finish.\n\t// @Type time.ms\n\t// @Restriction ReadOnlyForUser\n\tDelay int64 `protobuf:\"varint,2,opt,name=delay,proto3\" json:\"delay,omitempty\"`\n\t// @Document The last error caused this outbound failed to relay probe request\n\t// @Restriction NotMachineReadable\n\tLastErrorReason string `protobuf:\"bytes,3,opt,name=last_error_reason,json=lastErrorReason,proto3\" json:\"last_error_reason,omitempty\"`\n\t// @Document The outbound tag for this Server\n\t// @Type id.outboundTag\n\tOutboundTag string `protobuf:\"bytes,4,opt,name=outbound_tag,json=outboundTag,proto3\" json:\"outbound_tag,omitempty\"`\n\t// @Document The time this outbound is known to be alive\n\t// @Type id.outboundTag\n\tLastSeenTime int64 `protobuf:\"varint,5,opt,name=last_seen_time,json=lastSeenTime,proto3\" json:\"last_seen_time,omitempty\"`\n\t// @Document The time this outbound is tried\n\t// @Type id.outboundTag\n\tLastTryTime   int64                        `protobuf:\"varint,6,opt,name=last_try_time,json=lastTryTime,proto3\" json:\"last_try_time,omitempty\"`\n\tHealthPing    *HealthPingMeasurementResult `protobuf:\"bytes,7,opt,name=health_ping,json=healthPing,proto3\" json:\"health_ping,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *OutboundStatus) Reset() {\n\t*x = OutboundStatus{}\n\tmi := &file_app_observatory_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *OutboundStatus) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OutboundStatus) ProtoMessage() {}\n\nfunc (x *OutboundStatus) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_config_proto_msgTypes[2]\n\tif 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 OutboundStatus.ProtoReflect.Descriptor instead.\nfunc (*OutboundStatus) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *OutboundStatus) GetAlive() bool {\n\tif x != nil {\n\t\treturn x.Alive\n\t}\n\treturn false\n}\n\nfunc (x *OutboundStatus) GetDelay() int64 {\n\tif x != nil {\n\t\treturn x.Delay\n\t}\n\treturn 0\n}\n\nfunc (x *OutboundStatus) GetLastErrorReason() string {\n\tif x != nil {\n\t\treturn x.LastErrorReason\n\t}\n\treturn \"\"\n}\n\nfunc (x *OutboundStatus) GetOutboundTag() string {\n\tif x != nil {\n\t\treturn x.OutboundTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *OutboundStatus) GetLastSeenTime() int64 {\n\tif x != nil {\n\t\treturn x.LastSeenTime\n\t}\n\treturn 0\n}\n\nfunc (x *OutboundStatus) GetLastTryTime() int64 {\n\tif x != nil {\n\t\treturn x.LastTryTime\n\t}\n\treturn 0\n}\n\nfunc (x *OutboundStatus) GetHealthPing() *HealthPingMeasurementResult {\n\tif x != nil {\n\t\treturn x.HealthPing\n\t}\n\treturn nil\n}\n\ntype ProbeResult struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// @Document Whether this outbound is usable\n\t// @Restriction ReadOnlyForUser\n\tAlive bool `protobuf:\"varint,1,opt,name=alive,proto3\" json:\"alive,omitempty\"`\n\t// @Document The time for probe request to finish.\n\t// @Type time.ms\n\t// @Restriction ReadOnlyForUser\n\tDelay int64 `protobuf:\"varint,2,opt,name=delay,proto3\" json:\"delay,omitempty\"`\n\t// @Document The error caused this outbound failed to relay probe request\n\t// @Restriction NotMachineReadable\n\tLastErrorReason string `protobuf:\"bytes,3,opt,name=last_error_reason,json=lastErrorReason,proto3\" json:\"last_error_reason,omitempty\"`\n\tunknownFields   protoimpl.UnknownFields\n\tsizeCache       protoimpl.SizeCache\n}\n\nfunc (x *ProbeResult) Reset() {\n\t*x = ProbeResult{}\n\tmi := &file_app_observatory_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ProbeResult) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ProbeResult) ProtoMessage() {}\n\nfunc (x *ProbeResult) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_config_proto_msgTypes[3]\n\tif 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 ProbeResult.ProtoReflect.Descriptor instead.\nfunc (*ProbeResult) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *ProbeResult) GetAlive() bool {\n\tif x != nil {\n\t\treturn x.Alive\n\t}\n\treturn false\n}\n\nfunc (x *ProbeResult) GetDelay() int64 {\n\tif x != nil {\n\t\treturn x.Delay\n\t}\n\treturn 0\n}\n\nfunc (x *ProbeResult) GetLastErrorReason() string {\n\tif x != nil {\n\t\treturn x.LastErrorReason\n\t}\n\treturn \"\"\n}\n\ntype Intensity struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// @Document The time interval for a probe request in ms.\n\t// @Type time.ms\n\tProbeInterval uint32 `protobuf:\"varint,1,opt,name=probe_interval,json=probeInterval,proto3\" json:\"probe_interval,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Intensity) Reset() {\n\t*x = Intensity{}\n\tmi := &file_app_observatory_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Intensity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Intensity) ProtoMessage() {}\n\nfunc (x *Intensity) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_config_proto_msgTypes[4]\n\tif 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 Intensity.ProtoReflect.Descriptor instead.\nfunc (*Intensity) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *Intensity) GetProbeInterval() uint32 {\n\tif x != nil {\n\t\treturn x.ProbeInterval\n\t}\n\treturn 0\n}\n\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// @Document The selectors for outbound under observation\n\tSubjectSelector       []string `protobuf:\"bytes,2,rep,name=subject_selector,json=subjectSelector,proto3\" json:\"subject_selector,omitempty\"`\n\tProbeUrl              string   `protobuf:\"bytes,3,opt,name=probe_url,json=probeUrl,proto3\" json:\"probe_url,omitempty\"`\n\tProbeInterval         int64    `protobuf:\"varint,4,opt,name=probe_interval,json=probeInterval,proto3\" json:\"probe_interval,omitempty\"`\n\tPersistentProbeResult bool     `protobuf:\"varint,5,opt,name=persistent_probe_result,json=persistentProbeResult,proto3\" json:\"persistent_probe_result,omitempty\"`\n\tunknownFields         protoimpl.UnknownFields\n\tsizeCache             protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_observatory_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_config_proto_msgTypes[5]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_config_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *Config) GetSubjectSelector() []string {\n\tif x != nil {\n\t\treturn x.SubjectSelector\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetProbeUrl() string {\n\tif x != nil {\n\t\treturn x.ProbeUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetProbeInterval() int64 {\n\tif x != nil {\n\t\treturn x.ProbeInterval\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetPersistentProbeResult() bool {\n\tif x != nil {\n\t\treturn x.PersistentProbeResult\n\t}\n\treturn false\n}\n\nvar File_app_observatory_config_proto protoreflect.FileDescriptor\n\nconst file_app_observatory_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1capp/observatory/config.proto\\x12\\x1av2ray.core.app.observatory\\x1a common/protoext/extensions.proto\\\"W\\n\" +\n\t\"\\x11ObservationResult\\x12B\\n\" +\n\t\"\\x06status\\x18\\x01 \\x03(\\v2*.v2ray.core.app.observatory.OutboundStatusR\\x06status\\\"\\x9f\\x01\\n\" +\n\t\"\\x1bHealthPingMeasurementResult\\x12\\x10\\n\" +\n\t\"\\x03all\\x18\\x01 \\x01(\\x03R\\x03all\\x12\\x12\\n\" +\n\t\"\\x04fail\\x18\\x02 \\x01(\\x03R\\x04fail\\x12\\x1c\\n\" +\n\t\"\\tdeviation\\x18\\x03 \\x01(\\x03R\\tdeviation\\x12\\x18\\n\" +\n\t\"\\aaverage\\x18\\x04 \\x01(\\x03R\\aaverage\\x12\\x10\\n\" +\n\t\"\\x03max\\x18\\x05 \\x01(\\x03R\\x03max\\x12\\x10\\n\" +\n\t\"\\x03min\\x18\\x06 \\x01(\\x03R\\x03min\\\"\\xaf\\x02\\n\" +\n\t\"\\x0eOutboundStatus\\x12\\x14\\n\" +\n\t\"\\x05alive\\x18\\x01 \\x01(\\bR\\x05alive\\x12\\x14\\n\" +\n\t\"\\x05delay\\x18\\x02 \\x01(\\x03R\\x05delay\\x12*\\n\" +\n\t\"\\x11last_error_reason\\x18\\x03 \\x01(\\tR\\x0flastErrorReason\\x12!\\n\" +\n\t\"\\foutbound_tag\\x18\\x04 \\x01(\\tR\\voutboundTag\\x12$\\n\" +\n\t\"\\x0elast_seen_time\\x18\\x05 \\x01(\\x03R\\flastSeenTime\\x12\\\"\\n\" +\n\t\"\\rlast_try_time\\x18\\x06 \\x01(\\x03R\\vlastTryTime\\x12X\\n\" +\n\t\"\\vhealth_ping\\x18\\a \\x01(\\v27.v2ray.core.app.observatory.HealthPingMeasurementResultR\\n\" +\n\t\"healthPing\\\"e\\n\" +\n\t\"\\vProbeResult\\x12\\x14\\n\" +\n\t\"\\x05alive\\x18\\x01 \\x01(\\bR\\x05alive\\x12\\x14\\n\" +\n\t\"\\x05delay\\x18\\x02 \\x01(\\x03R\\x05delay\\x12*\\n\" +\n\t\"\\x11last_error_reason\\x18\\x03 \\x01(\\tR\\x0flastErrorReason\\\"2\\n\" +\n\t\"\\tIntensity\\x12%\\n\" +\n\t\"\\x0eprobe_interval\\x18\\x01 \\x01(\\rR\\rprobeInterval\\\"\\xd5\\x01\\n\" +\n\t\"\\x06Config\\x12)\\n\" +\n\t\"\\x10subject_selector\\x18\\x02 \\x03(\\tR\\x0fsubjectSelector\\x12\\x1b\\n\" +\n\t\"\\tprobe_url\\x18\\x03 \\x01(\\tR\\bprobeUrl\\x12%\\n\" +\n\t\"\\x0eprobe_interval\\x18\\x04 \\x01(\\x03R\\rprobeInterval\\x126\\n\" +\n\t\"\\x17persistent_probe_result\\x18\\x05 \\x01(\\bR\\x15persistentProbeResult:$\\x82\\xb5\\x18 \\n\" +\n\t\"\\aservice\\x12\\x15backgroundObservatoryBo\\n\" +\n\t\"\\x1ecom.v2ray.core.app.observatoryP\\x01Z.github.com/v2fly/v2ray-core/v5/app/observatory\\xaa\\x02\\x1aV2Ray.Core.App.Observatoryb\\x06proto3\"\n\nvar (\n\tfile_app_observatory_config_proto_rawDescOnce sync.Once\n\tfile_app_observatory_config_proto_rawDescData []byte\n)\n\nfunc file_app_observatory_config_proto_rawDescGZIP() []byte {\n\tfile_app_observatory_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_observatory_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_observatory_config_proto_rawDesc), len(file_app_observatory_config_proto_rawDesc)))\n\t})\n\treturn file_app_observatory_config_proto_rawDescData\n}\n\nvar file_app_observatory_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)\nvar file_app_observatory_config_proto_goTypes = []any{\n\t(*ObservationResult)(nil),           // 0: v2ray.core.app.observatory.ObservationResult\n\t(*HealthPingMeasurementResult)(nil), // 1: v2ray.core.app.observatory.HealthPingMeasurementResult\n\t(*OutboundStatus)(nil),              // 2: v2ray.core.app.observatory.OutboundStatus\n\t(*ProbeResult)(nil),                 // 3: v2ray.core.app.observatory.ProbeResult\n\t(*Intensity)(nil),                   // 4: v2ray.core.app.observatory.Intensity\n\t(*Config)(nil),                      // 5: v2ray.core.app.observatory.Config\n}\nvar file_app_observatory_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.app.observatory.ObservationResult.status:type_name -> v2ray.core.app.observatory.OutboundStatus\n\t1, // 1: v2ray.core.app.observatory.OutboundStatus.health_ping:type_name -> v2ray.core.app.observatory.HealthPingMeasurementResult\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_app_observatory_config_proto_init() }\nfunc file_app_observatory_config_proto_init() {\n\tif File_app_observatory_config_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: unsafe.Slice(unsafe.StringData(file_app_observatory_config_proto_rawDesc), len(file_app_observatory_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   6,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_observatory_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_observatory_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_observatory_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_observatory_config_proto = out.File\n\tfile_app_observatory_config_proto_goTypes = nil\n\tfile_app_observatory_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/observatory/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.observatory;\noption csharp_namespace = \"V2Ray.Core.App.Observatory\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/observatory\";\noption java_package = \"com.v2ray.core.app.observatory\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\n\nmessage ObservationResult {\n  repeated OutboundStatus status = 1;\n}\n\nmessage HealthPingMeasurementResult {\n  int64 all = 1;\n  int64 fail = 2;\n  int64 deviation = 3;\n  int64 average = 4;\n  int64 max = 5;\n  int64 min = 6;\n}\n\nmessage OutboundStatus{\n  /* @Document Whether this outbound is usable\n     @Restriction ReadOnlyForUser\n  */\n  bool alive = 1;\n  /* @Document The time for probe request to finish.\n     @Type time.ms\n     @Restriction ReadOnlyForUser\n  */\n  int64 delay = 2;\n  /* @Document The last error caused this outbound failed to relay probe request\n     @Restriction NotMachineReadable\n  */\n  string last_error_reason = 3;\n  /* @Document The outbound tag for this Server\n     @Type id.outboundTag\n  */\n  string outbound_tag = 4;\n  /* @Document The time this outbound is known to be alive\n   @Type id.outboundTag\n*/\n  int64 last_seen_time = 5;\n  /* @Document The time this outbound is tried\n   @Type id.outboundTag\n*/\n  int64 last_try_time = 6;\n\n  HealthPingMeasurementResult health_ping = 7;\n}\n\nmessage ProbeResult{\n  /* @Document Whether this outbound is usable\n     @Restriction ReadOnlyForUser\n  */\n  bool alive = 1;\n  /* @Document The time for probe request to finish.\n     @Type time.ms\n     @Restriction ReadOnlyForUser\n  */\n  int64 delay = 2;\n  /* @Document The error caused this outbound failed to relay probe request\n   @Restriction NotMachineReadable\n*/\n  string last_error_reason = 3;\n}\n\nmessage Intensity{\n  /* @Document The time interval for a probe request in ms.\n     @Type time.ms\n  */\n  uint32 probe_interval = 1;\n}\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"backgroundObservatory\";\n  /* @Document The selectors for outbound under observation\n  */\n  repeated string subject_selector = 2;\n\n  string probe_url = 3;\n\n  int64 probe_interval = 4;\n\n  bool persistent_probe_result = 5;\n}"
  },
  {
    "path": "app/observatory/errors.generated.go",
    "content": "package observatory\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/observatory/explainErrors.go",
    "content": "package observatory\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errorCollector struct {\n\terrors *errors.Error\n}\n\nfunc (e *errorCollector) SubmitError(err error) {\n\tif e.errors == nil {\n\t\te.errors = newError(\"underlying connection error\").Base(err)\n\t\treturn\n\t}\n\te.errors = e.errors.Base(newError(\"underlying connection error\").Base(err))\n}\n\nfunc newErrorCollector() *errorCollector {\n\treturn &errorCollector{}\n}\n\nfunc (e *errorCollector) UnderlyingError() error {\n\tif e.errors == nil {\n\t\treturn newError(\"failed to produce report\")\n\t}\n\treturn e.errors\n}\n"
  },
  {
    "path": "app/observatory/multiobservatory/config.pb.go",
    "content": "package multiobservatory\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\ttaggedfeatures \"github.com/v2fly/v2ray-core/v5/common/taggedfeatures\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tHolders       *taggedfeatures.Config `protobuf:\"bytes,1,opt,name=holders,proto3\" json:\"holders,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_observatory_multiobservatory_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_observatory_multiobservatory_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_observatory_multiobservatory_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetHolders() *taggedfeatures.Config {\n\tif x != nil {\n\t\treturn x.Holders\n\t}\n\treturn nil\n}\n\nvar File_app_observatory_multiobservatory_config_proto protoreflect.FileDescriptor\n\nconst file_app_observatory_multiobservatory_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"-app/observatory/multiobservatory/config.proto\\x12+v2ray.core.app.observatory.multiobservatory\\x1a$common/taggedfeatures/skeleton.proto\\x1a common/protoext/extensions.proto\\\"m\\n\" +\n\t\"\\x06Config\\x12B\\n\" +\n\t\"\\aholders\\x18\\x01 \\x01(\\v2(.v2ray.core.common.taggedfeatures.ConfigR\\aholders:\\x1f\\x82\\xb5\\x18\\x1b\\n\" +\n\t\"\\aservice\\x12\\x10multiobservatoryB\\xa2\\x01\\n\" +\n\t\"/com.v2ray.core.app.observatory.multiObservatoryP\\x01Z?github.com/v2fly/v2ray-core/v5/app/observatory/multiobservatory\\xaa\\x02+V2Ray.Core.App.Observatory.MultiObservatoryb\\x06proto3\"\n\nvar (\n\tfile_app_observatory_multiobservatory_config_proto_rawDescOnce sync.Once\n\tfile_app_observatory_multiobservatory_config_proto_rawDescData []byte\n)\n\nfunc file_app_observatory_multiobservatory_config_proto_rawDescGZIP() []byte {\n\tfile_app_observatory_multiobservatory_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_observatory_multiobservatory_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_observatory_multiobservatory_config_proto_rawDesc), len(file_app_observatory_multiobservatory_config_proto_rawDesc)))\n\t})\n\treturn file_app_observatory_multiobservatory_config_proto_rawDescData\n}\n\nvar file_app_observatory_multiobservatory_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_observatory_multiobservatory_config_proto_goTypes = []any{\n\t(*Config)(nil),                // 0: v2ray.core.app.observatory.multiobservatory.Config\n\t(*taggedfeatures.Config)(nil), // 1: v2ray.core.common.taggedfeatures.Config\n}\nvar file_app_observatory_multiobservatory_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.app.observatory.multiobservatory.Config.holders:type_name -> v2ray.core.common.taggedfeatures.Config\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_observatory_multiobservatory_config_proto_init() }\nfunc file_app_observatory_multiobservatory_config_proto_init() {\n\tif File_app_observatory_multiobservatory_config_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: unsafe.Slice(unsafe.StringData(file_app_observatory_multiobservatory_config_proto_rawDesc), len(file_app_observatory_multiobservatory_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_observatory_multiobservatory_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_observatory_multiobservatory_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_observatory_multiobservatory_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_observatory_multiobservatory_config_proto = out.File\n\tfile_app_observatory_multiobservatory_config_proto_goTypes = nil\n\tfile_app_observatory_multiobservatory_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/observatory/multiobservatory/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.observatory.multiobservatory;\noption csharp_namespace = \"V2Ray.Core.App.Observatory.MultiObservatory\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/observatory/multiobservatory\";\noption java_package = \"com.v2ray.core.app.observatory.multiObservatory\";\noption java_multiple_files = true;\n\nimport \"common/taggedfeatures/skeleton.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config{\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"multiobservatory\";\n\n  v2ray.core.common.taggedfeatures.Config holders = 1 ;\n}\n"
  },
  {
    "path": "app/observatory/multiobservatory/multi.go",
    "content": "package multiobservatory\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/taggedfeatures\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\ntype Observer struct {\n\tfeatures.TaggedFeatures\n\tconfig *Config\n\tctx    context.Context\n}\n\nfunc (o Observer) GetObservation(ctx context.Context) (proto.Message, error) {\n\treturn common.Must2(o.GetFeaturesByTag(\"\")).(extension.Observatory).GetObservation(ctx)\n}\n\nfunc (o Observer) Type() interface{} {\n\treturn extension.ObservatoryType()\n}\n\nfunc New(ctx context.Context, config *Config) (*Observer, error) {\n\tholder, err := taggedfeatures.NewHolderFromConfig(ctx, config.Holders, extension.ObservatoryType())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Observer{config: config, ctx: ctx, TaggedFeatures: holder}, nil\n}\n\nfunc (x *Config) UnmarshalJSONPB(unmarshaler *jsonpb.Unmarshaler, bytes []byte) error {\n\tvar err error\n\tx.Holders, err = taggedfeatures.LoadJSONConfig(context.TODO(), \"service\", \"background\", bytes)\n\treturn err\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/observatory/observatory.go",
    "content": "package observatory\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/observatory/observer.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage observatory\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sort\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/persistentstorage\"\n\t\"github.com/v2fly/v2ray-core/v5/app/persistentstorage/protostorage\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\ntype Observer struct {\n\tconfig *Config\n\tctx    context.Context\n\n\tstatusLock sync.Mutex\n\tstatus     []*OutboundStatus\n\n\tfinished *done.Instance\n\n\tohm            outbound.Manager\n\tpersistStorage persistentstorage.ScopedPersistentStorage\n\n\tpersistOutboundStatusProtoStorage protostorage.ProtoPersistentStorage\n}\n\nfunc (o *Observer) GetObservation(ctx context.Context) (proto.Message, error) {\n\treturn &ObservationResult{Status: o.status}, nil\n}\n\nfunc (o *Observer) Type() interface{} {\n\treturn extension.ObservatoryType()\n}\n\nfunc (o *Observer) Start() error {\n\tif o.config != nil && len(o.config.SubjectSelector) != 0 {\n\t\tif o.config.PersistentProbeResult {\n\t\t\tappEnvironment := envctx.EnvironmentFromContext(o.ctx).(environment.AppEnvironment)\n\t\t\to.persistStorage = appEnvironment.PersistentStorage()\n\n\t\t\toutboundStatusStorage, err := o.persistStorage.NarrowScope(o.ctx, []byte(\"outbound_status\"))\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to get persistent storage for outbound_status\").Base(err)\n\t\t\t}\n\t\t\to.persistOutboundStatusProtoStorage = outboundStatusStorage.(protostorage.ProtoPersistentStorage)\n\t\t\tlist, err := outboundStatusStorage.List(o.ctx, []byte(\"\"))\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to list persisted outbound status\").Base(err).WriteToLog()\n\t\t\t} else {\n\t\t\t\tfor _, v := range list {\n\t\t\t\t\to.loadOutboundStatus(string(v))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\to.finished = done.New()\n\t\tgo o.background()\n\t}\n\treturn nil\n}\n\nfunc (o *Observer) Close() error {\n\tif o.finished != nil {\n\t\treturn o.finished.Close()\n\t}\n\treturn nil\n}\n\nfunc (o *Observer) background() {\n\tfor !o.finished.Done() {\n\t\ths, ok := o.ohm.(outbound.HandlerSelector)\n\t\tif !ok {\n\t\t\tnewError(\"outbound.Manager is not a HandlerSelector\").WriteToLog()\n\t\t\treturn\n\t\t}\n\n\t\toutbounds := hs.Select(o.config.SubjectSelector)\n\t\tsort.Strings(outbounds)\n\n\t\to.updateStatus(outbounds)\n\n\t\tslept := false\n\t\tfor _, v := range outbounds {\n\t\t\tresult := o.probe(v)\n\t\t\to.updateStatusForResult(v, &result)\n\t\t\tif o.finished.Done() {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsleepTime := time.Second * 10\n\t\t\tif o.config.ProbeInterval != 0 {\n\t\t\t\tsleepTime = time.Duration(o.config.ProbeInterval)\n\t\t\t}\n\t\t\ttime.Sleep(sleepTime)\n\t\t\tslept = true\n\t\t}\n\t\tif !slept {\n\t\t\tsleepTime := time.Second * 10\n\t\t\tif o.config.ProbeInterval != 0 {\n\t\t\t\tsleepTime = time.Duration(o.config.ProbeInterval)\n\t\t\t}\n\t\t\ttime.Sleep(sleepTime)\n\t\t}\n\t}\n}\n\nfunc (o *Observer) updateStatus(outbounds []string) {\n\to.statusLock.Lock()\n\tdefer o.statusLock.Unlock()\n\t// TODO should remove old inbound that is removed\n\t_ = outbounds\n}\n\nfunc (o *Observer) probe(outbound string) ProbeResult {\n\terrorCollectorForRequest := newErrorCollector()\n\n\thttpTransport := http.Transport{\n\t\tProxy: func(*http.Request) (*url.URL, error) {\n\t\t\treturn nil, nil\n\t\t},\n\t\tDialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {\n\t\t\tvar connection net.Conn\n\t\t\ttaskErr := task.Run(ctx, func() error {\n\t\t\t\t// MUST use V2Fly's built in context system\n\t\t\t\tdest, err := v2net.ParseDestination(network + \":\" + addr)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn newError(\"cannot understand address\").Base(err)\n\t\t\t\t}\n\t\t\t\ttrackedCtx := session.TrackedConnectionError(o.ctx, errorCollectorForRequest)\n\t\t\t\tconn, err := tagged.Dialer(trackedCtx, dest, outbound)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn newError(\"cannot dial remote address \", dest).Base(err)\n\t\t\t\t}\n\t\t\t\tconnection = conn\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\tif taskErr != nil {\n\t\t\t\treturn nil, newError(\"cannot finish connection\").Base(taskErr)\n\t\t\t}\n\t\t\treturn connection, nil\n\t\t},\n\t\tTLSHandshakeTimeout: time.Second * 5,\n\t}\n\thttpClient := &http.Client{\n\t\tTransport: &httpTransport,\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\treturn http.ErrUseLastResponse\n\t\t},\n\t\tJar:     nil,\n\t\tTimeout: time.Second * 5,\n\t}\n\tvar GETTime time.Duration\n\terr := task.Run(o.ctx, func() error {\n\t\tstartTime := time.Now()\n\t\tprobeURL := \"https://api.v2fly.org/checkConnection.svgz\"\n\t\tif o.config.ProbeUrl != \"\" {\n\t\t\tprobeURL = o.config.ProbeUrl\n\t\t}\n\t\tresponse, err := httpClient.Get(probeURL)\n\t\tif err != nil {\n\t\t\treturn newError(\"outbound failed to relay connection\").Base(err)\n\t\t}\n\t\tif response.Body != nil {\n\t\t\tresponse.Body.Close()\n\t\t}\n\t\tendTime := time.Now()\n\t\tGETTime = endTime.Sub(startTime)\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\tfullerr := newError(\"underlying connection failed\").Base(errorCollectorForRequest.UnderlyingError())\n\t\tfullerr = newError(\"with outbound handler report\").Base(fullerr)\n\t\tfullerr = newError(\"GET request failed:\", err).Base(fullerr)\n\t\tfullerr = newError(\"the outbound \", outbound, \" is dead:\").Base(fullerr)\n\t\tfullerr = fullerr.AtInfo()\n\t\tfullerr.WriteToLog()\n\t\treturn ProbeResult{Alive: false, LastErrorReason: fullerr.Error()}\n\t}\n\tnewError(\"the outbound \", outbound, \" is alive:\", GETTime.Seconds()).AtInfo().WriteToLog()\n\treturn ProbeResult{Alive: true, Delay: GETTime.Milliseconds()}\n}\n\nfunc (o *Observer) updateStatusForResult(outbound string, result *ProbeResult) {\n\to.statusLock.Lock()\n\tdefer o.statusLock.Unlock()\n\tvar status *OutboundStatus\n\tif location := o.findStatusLocationLockHolderOnly(outbound); location != -1 {\n\t\tstatus = o.status[location]\n\t} else {\n\t\tstatus = &OutboundStatus{}\n\t\to.status = append(o.status, status)\n\t}\n\n\tstatus.LastTryTime = time.Now().Unix()\n\tstatus.OutboundTag = outbound\n\tstatus.Alive = result.Alive\n\tif result.Alive {\n\t\tstatus.Delay = result.Delay\n\t\tstatus.LastSeenTime = status.LastTryTime\n\t\tstatus.LastErrorReason = \"\"\n\t} else {\n\t\tstatus.LastErrorReason = result.LastErrorReason\n\t\tstatus.Delay = 99999999\n\t}\n\tif o.config.PersistentProbeResult {\n\t\terr := o.persistOutboundStatusProtoStorage.PutProto(o.ctx, outbound, status)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to persist outbound status\").Base(err).WriteToLog()\n\t\t}\n\t}\n}\n\nfunc (o *Observer) findStatusLocationLockHolderOnly(outbound string) int {\n\tfor i, v := range o.status {\n\t\tif v.OutboundTag == outbound {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\nfunc (o *Observer) loadOutboundStatus(name string) {\n\tif o.persistOutboundStatusProtoStorage == nil {\n\t\treturn\n\t}\n\tstatus := &OutboundStatus{}\n\terr := o.persistOutboundStatusProtoStorage.GetProto(o.ctx, name, status)\n\tif err != nil {\n\t\tnewError(\"failed to load outbound status\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\to.status = append(o.status, status)\n}\n\nfunc New(ctx context.Context, config *Config) (*Observer, error) {\n\tobs := &Observer{\n\t\tconfig: config,\n\t\tctx:    ctx,\n\t}\n\n\terr := core.RequireFeatures(ctx, func(om outbound.Manager) {\n\t\tobs.ohm = om\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"Cannot get depended features\").Base(err)\n\t}\n\n\treturn obs, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/persistentstorage/filesystemstorage/config.pb.go",
    "content": "package filesystemstorage\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 StateStorageRoot int32\n\nconst (\n\tStateStorageRoot_WorkDir StateStorageRoot = 0\n)\n\n// Enum value maps for StateStorageRoot.\nvar (\n\tStateStorageRoot_name = map[int32]string{\n\t\t0: \"WorkDir\",\n\t}\n\tStateStorageRoot_value = map[string]int32{\n\t\t\"WorkDir\": 0,\n\t}\n)\n\nfunc (x StateStorageRoot) Enum() *StateStorageRoot {\n\tp := new(StateStorageRoot)\n\t*p = x\n\treturn p\n}\n\nfunc (x StateStorageRoot) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (StateStorageRoot) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_persistentstorage_filesystemstorage_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (StateStorageRoot) Type() protoreflect.EnumType {\n\treturn &file_app_persistentstorage_filesystemstorage_config_proto_enumTypes[0]\n}\n\nfunc (x StateStorageRoot) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use StateStorageRoot.Descriptor instead.\nfunc (StateStorageRoot) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_persistentstorage_filesystemstorage_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Config struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tStateStorageRoot StateStorageRoot       `protobuf:\"varint,1,opt,name=state_storage_root,json=stateStorageRoot,proto3,enum=v2ray.core.app.persistentstorage.filesystemstorage.StateStorageRoot\" json:\"state_storage_root,omitempty\"`\n\tInstanceName     string                 `protobuf:\"bytes,4,opt,name=instance_name,json=instanceName,proto3\" json:\"instance_name,omitempty\"`\n\tProtojson        bool                   `protobuf:\"varint,5,opt,name=protojson,proto3\" json:\"protojson,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_persistentstorage_filesystemstorage_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_persistentstorage_filesystemstorage_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_persistentstorage_filesystemstorage_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetStateStorageRoot() StateStorageRoot {\n\tif x != nil {\n\t\treturn x.StateStorageRoot\n\t}\n\treturn StateStorageRoot_WorkDir\n}\n\nfunc (x *Config) GetInstanceName() string {\n\tif x != nil {\n\t\treturn x.InstanceName\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetProtojson() bool {\n\tif x != nil {\n\t\treturn x.Protojson\n\t}\n\treturn false\n}\n\nvar File_app_persistentstorage_filesystemstorage_config_proto protoreflect.FileDescriptor\n\nconst file_app_persistentstorage_filesystemstorage_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"4app/persistentstorage/filesystemstorage/config.proto\\x122v2ray.core.app.persistentstorage.filesystemstorage\\x1a common/protoext/extensions.proto\\\"\\xe1\\x01\\n\" +\n\t\"\\x06Config\\x12r\\n\" +\n\t\"\\x12state_storage_root\\x18\\x01 \\x01(\\x0e2D.v2ray.core.app.persistentstorage.filesystemstorage.StateStorageRootR\\x10stateStorageRoot\\x12#\\n\" +\n\t\"\\rinstance_name\\x18\\x04 \\x01(\\tR\\finstanceName\\x12\\x1c\\n\" +\n\t\"\\tprotojson\\x18\\x05 \\x01(\\bR\\tprotojson: \\x82\\xb5\\x18\\x1c\\n\" +\n\t\"\\aservice\\x12\\x11filesystemstorage*\\x1f\\n\" +\n\t\"\\x10StateStorageRoot\\x12\\v\\n\" +\n\t\"\\aWorkDir\\x10\\x00B\\xb3\\x01\\n\" +\n\t\"2com.v2ray.core.persistentstorage.filesystemstorageP\\x01ZFgithub.com/v2fly/v2ray-core/v5/app/persistentstorage/filesystemstorage\\xaa\\x022V2Ray.Core.App.Persistentstorage.Filesystemstorageb\\x06proto3\"\n\nvar (\n\tfile_app_persistentstorage_filesystemstorage_config_proto_rawDescOnce sync.Once\n\tfile_app_persistentstorage_filesystemstorage_config_proto_rawDescData []byte\n)\n\nfunc file_app_persistentstorage_filesystemstorage_config_proto_rawDescGZIP() []byte {\n\tfile_app_persistentstorage_filesystemstorage_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_persistentstorage_filesystemstorage_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_persistentstorage_filesystemstorage_config_proto_rawDesc), len(file_app_persistentstorage_filesystemstorage_config_proto_rawDesc)))\n\t})\n\treturn file_app_persistentstorage_filesystemstorage_config_proto_rawDescData\n}\n\nvar file_app_persistentstorage_filesystemstorage_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_app_persistentstorage_filesystemstorage_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_persistentstorage_filesystemstorage_config_proto_goTypes = []any{\n\t(StateStorageRoot)(0), // 0: v2ray.core.app.persistentstorage.filesystemstorage.StateStorageRoot\n\t(*Config)(nil),        // 1: v2ray.core.app.persistentstorage.filesystemstorage.Config\n}\nvar file_app_persistentstorage_filesystemstorage_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.persistentstorage.filesystemstorage.Config.state_storage_root:type_name -> v2ray.core.app.persistentstorage.filesystemstorage.StateStorageRoot\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_persistentstorage_filesystemstorage_config_proto_init() }\nfunc file_app_persistentstorage_filesystemstorage_config_proto_init() {\n\tif File_app_persistentstorage_filesystemstorage_config_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: unsafe.Slice(unsafe.StringData(file_app_persistentstorage_filesystemstorage_config_proto_rawDesc), len(file_app_persistentstorage_filesystemstorage_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_persistentstorage_filesystemstorage_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_persistentstorage_filesystemstorage_config_proto_depIdxs,\n\t\tEnumInfos:         file_app_persistentstorage_filesystemstorage_config_proto_enumTypes,\n\t\tMessageInfos:      file_app_persistentstorage_filesystemstorage_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_persistentstorage_filesystemstorage_config_proto = out.File\n\tfile_app_persistentstorage_filesystemstorage_config_proto_goTypes = nil\n\tfile_app_persistentstorage_filesystemstorage_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/persistentstorage/filesystemstorage/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.persistentstorage.filesystemstorage;\noption csharp_namespace = \"V2Ray.Core.App.Persistentstorage.Filesystemstorage\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/persistentstorage/filesystemstorage\";\noption java_package = \"com.v2ray.core.persistentstorage.filesystemstorage\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nenum StateStorageRoot {\n  WorkDir = 0;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"filesystemstorage\";\n\n  StateStorageRoot state_storage_root = 1;\n  string instance_name = 4;\n\n  bool protojson = 5;\n}\n"
  },
  {
    "path": "app/persistentstorage/filesystemstorage/fs.go",
    "content": "package filesystemstorage\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/persistentstorage/protostorage\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n)\n\nfunc newFileSystemStorage(ctx context.Context, config *Config) storage.ScopedPersistentStorageService {\n\tappEnvironment := envctx.EnvironmentFromContext(ctx).(environment.AppEnvironment)\n\tfss := &fileSystemStorage{\n\t\tfs:              appEnvironment,\n\t\tpathRoot:        config.InstanceName,\n\t\tcurrentLocation: nil,\n\t\tconfig:          config,\n\t}\n\n\tprotoStorageInst := protostorage.NewProtoStorage(fss, config.Protojson)\n\tfss.proto = protoStorageInst\n\treturn fss\n}\n\ntype fileSystemStorage struct {\n\tfs    environment.FileSystemCapabilitySet\n\tproto protostorage.ProtoPersistentStorage\n\n\tpathRoot        string\n\tcurrentLocation []string\n\tconfig          *Config\n}\n\nfunc (f *fileSystemStorage) Type() interface{} {\n\treturn storage.ScopedPersistentStorageServiceType\n}\n\nfunc (f *fileSystemStorage) Start() error {\n\treturn nil\n}\n\nfunc (f *fileSystemStorage) Close() error {\n\treturn nil\n}\n\nfunc (f *fileSystemStorage) PutProto(ctx context.Context, key string, pb proto.Message) error {\n\treturn f.proto.PutProto(ctx, key, pb)\n}\n\nfunc (f *fileSystemStorage) GetProto(ctx context.Context, key string, pb proto.Message) error {\n\treturn f.proto.GetProto(ctx, key, pb)\n}\n\nfunc (f *fileSystemStorage) ScopedPersistentStorageEngine() {\n}\n\nfunc (f *fileSystemStorage) Put(ctx context.Context, key []byte, value []byte) error {\n\tfinalPath := filepath.Join(f.pathRoot, filepath.Join(f.currentLocation...), string(key))\n\tif value == nil {\n\t\treturn f.fs.RemoveFile()(finalPath)\n\t}\n\twriter, err := f.fs.OpenFileForWrite()(finalPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer writer.Close()\n\t_, err = io.Copy(writer, io.NopCloser(bytes.NewReader(value)))\n\treturn err\n}\n\nfunc (f *fileSystemStorage) Get(ctx context.Context, key []byte) ([]byte, error) {\n\tfinalPath := filepath.Join(f.pathRoot, filepath.Join(f.currentLocation...), string(key))\n\treader, err := f.fs.OpenFileForRead()(finalPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer reader.Close()\n\treturn io.ReadAll(reader)\n}\n\nfunc (f *fileSystemStorage) List(ctx context.Context, keyPrefix []byte) ([][]byte, error) {\n\tres, err := f.fs.ReadDir()(filepath.Join(f.pathRoot, filepath.Join(f.currentLocation...)))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar result [][]byte\n\tfor _, entry := range res {\n\t\tif !entry.IsDir() && bytes.HasPrefix([]byte(entry.Name()), keyPrefix) {\n\t\t\tresult = append(result, []byte(entry.Name()))\n\t\t}\n\t}\n\treturn result, nil\n}\n\nfunc (f *fileSystemStorage) Clear(ctx context.Context) {\n\tallFile, err := f.List(ctx, []byte{})\n\tif err != nil {\n\t\treturn\n\t}\n\tfor _, file := range allFile {\n\t\t_ = f.Put(ctx, file, nil)\n\t}\n}\n\nfunc (f *fileSystemStorage) NarrowScope(ctx context.Context, key []byte) (storage.ScopedPersistentStorage, error) {\n\tescapedKey := strings.ReplaceAll(string(key), \"/\", \"_\")\n\tfss := &fileSystemStorage{\n\t\tfs:              f.fs,\n\t\tpathRoot:        f.pathRoot,\n\t\tcurrentLocation: append(f.currentLocation, escapedKey),\n\t\tconfig:          f.config,\n\t}\n\tfss.proto = protostorage.NewProtoStorage(fss, f.config.Protojson)\n\treturn fss, nil\n}\n\nfunc (f *fileSystemStorage) DropScope(ctx context.Context, key []byte) error {\n\tpanic(\"unimplemented\")\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn newFileSystemStorage(ctx, config.(*Config)), nil\n\t}))\n}\n"
  },
  {
    "path": "app/persistentstorage/protostorage/protokv.go",
    "content": "package protostorage\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n)\n\ntype ProtoPersistentStorage interface {\n\tPutProto(ctx context.Context, key string, pb proto.Message) error\n\tGetProto(ctx context.Context, key string, pb proto.Message) error\n}\n\ntype protoStorage struct {\n\tstorage    storage.ScopedPersistentStorage\n\ttextFormat bool\n}\n\nfunc (p *protoStorage) PutProto(ctx context.Context, key string, pb proto.Message) error {\n\tif !p.textFormat {\n\t\tdata, err := proto.Marshal(pb)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn p.storage.Put(ctx, []byte(key), data)\n\t} else {\n\t\tprotojsonStr := protojson.Format(pb)\n\t\treturn p.storage.Put(ctx, []byte(key), []byte(protojsonStr))\n\t}\n}\n\nfunc (p *protoStorage) GetProto(ctx context.Context, key string, pb proto.Message) error {\n\tdata, err := p.storage.Get(ctx, []byte(key))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !p.textFormat {\n\t\treturn proto.Unmarshal(data, pb)\n\t}\n\treturn protojson.Unmarshal(data, pb)\n}\n\nfunc NewProtoStorage(storage storage.ScopedPersistentStorage, textFormat bool) ProtoPersistentStorage {\n\treturn &protoStorage{\n\t\tstorage:    storage,\n\t\ttextFormat: textFormat,\n\t}\n}\n"
  },
  {
    "path": "app/persistentstorage/storage.go",
    "content": "package persistentstorage\n\nimport \"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n\ntype ScopedPersistentStorage = storage.ScopedPersistentStorage\n"
  },
  {
    "path": "app/policy/config.go",
    "content": "package policy\n\nimport (\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n)\n\n// Duration converts Second to time.Duration.\nfunc (s *Second) Duration() time.Duration {\n\tif s == nil {\n\t\treturn 0\n\t}\n\treturn time.Second * time.Duration(s.Value)\n}\n\nfunc defaultPolicy() *Policy {\n\tp := policy.SessionDefault()\n\n\treturn &Policy{\n\t\tTimeout: &Policy_Timeout{\n\t\t\tHandshake:      &Second{Value: uint32(p.Timeouts.Handshake / time.Second)},\n\t\t\tConnectionIdle: &Second{Value: uint32(p.Timeouts.ConnectionIdle / time.Second)},\n\t\t\tUplinkOnly:     &Second{Value: uint32(p.Timeouts.UplinkOnly / time.Second)},\n\t\t\tDownlinkOnly:   &Second{Value: uint32(p.Timeouts.DownlinkOnly / time.Second)},\n\t\t},\n\t\tBuffer: &Policy_Buffer{\n\t\t\tConnection: p.Buffer.PerConnection,\n\t\t},\n\t}\n}\n\nfunc (p *Policy_Timeout) overrideWith(another *Policy_Timeout) {\n\tif another.Handshake != nil {\n\t\tp.Handshake = &Second{Value: another.Handshake.Value}\n\t}\n\tif another.ConnectionIdle != nil {\n\t\tp.ConnectionIdle = &Second{Value: another.ConnectionIdle.Value}\n\t}\n\tif another.UplinkOnly != nil {\n\t\tp.UplinkOnly = &Second{Value: another.UplinkOnly.Value}\n\t}\n\tif another.DownlinkOnly != nil {\n\t\tp.DownlinkOnly = &Second{Value: another.DownlinkOnly.Value}\n\t}\n}\n\nfunc (p *Policy) overrideWith(another *Policy) {\n\tif another.Timeout != nil {\n\t\tp.Timeout.overrideWith(another.Timeout)\n\t}\n\tif another.Stats != nil && p.Stats == nil {\n\t\tp.Stats = &Policy_Stats{}\n\t\tp.Stats = another.Stats\n\t}\n\tif another.Buffer != nil {\n\t\tp.Buffer = &Policy_Buffer{\n\t\t\tConnection: another.Buffer.Connection,\n\t\t}\n\t}\n}\n\n// ToCorePolicy converts this Policy to policy.Session.\nfunc (p *Policy) ToCorePolicy() policy.Session {\n\tcp := policy.SessionDefault()\n\n\tif p.Timeout != nil {\n\t\tcp.Timeouts.ConnectionIdle = p.Timeout.ConnectionIdle.Duration()\n\t\tcp.Timeouts.Handshake = p.Timeout.Handshake.Duration()\n\t\tcp.Timeouts.DownlinkOnly = p.Timeout.DownlinkOnly.Duration()\n\t\tcp.Timeouts.UplinkOnly = p.Timeout.UplinkOnly.Duration()\n\t}\n\tif p.Stats != nil {\n\t\tcp.Stats.UserUplink = p.Stats.UserUplink\n\t\tcp.Stats.UserDownlink = p.Stats.UserDownlink\n\t}\n\tif p.Buffer != nil {\n\t\tcp.Buffer.PerConnection = p.Buffer.Connection\n\t}\n\treturn cp\n}\n\n// ToCorePolicy converts this SystemPolicy to policy.System.\nfunc (p *SystemPolicy) ToCorePolicy() policy.System {\n\treturn policy.System{\n\t\tStats: policy.SystemStats{\n\t\t\tInboundUplink:    p.Stats.InboundUplink,\n\t\t\tInboundDownlink:  p.Stats.InboundDownlink,\n\t\t\tOutboundUplink:   p.Stats.OutboundUplink,\n\t\t\tOutboundDownlink: p.Stats.OutboundDownlink,\n\t\t},\n\t\tOverrideAccessLogDest: p.OverrideAccessLogDest,\n\t}\n}\n"
  },
  {
    "path": "app/policy/config.pb.go",
    "content": "package policy\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Second struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Second) Reset() {\n\t*x = Second{}\n\tmi := &file_app_policy_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Second) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Second) ProtoMessage() {}\n\nfunc (x *Second) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[0]\n\tif 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 Second.ProtoReflect.Descriptor instead.\nfunc (*Second) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Second) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\ntype Policy struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTimeout       *Policy_Timeout        `protobuf:\"bytes,1,opt,name=timeout,proto3\" json:\"timeout,omitempty\"`\n\tStats         *Policy_Stats          `protobuf:\"bytes,2,opt,name=stats,proto3\" json:\"stats,omitempty\"`\n\tBuffer        *Policy_Buffer         `protobuf:\"bytes,3,opt,name=buffer,proto3\" json:\"buffer,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Policy) Reset() {\n\t*x = Policy{}\n\tmi := &file_app_policy_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Policy) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Policy) ProtoMessage() {}\n\nfunc (x *Policy) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[1]\n\tif 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 Policy.ProtoReflect.Descriptor instead.\nfunc (*Policy) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Policy) GetTimeout() *Policy_Timeout {\n\tif x != nil {\n\t\treturn x.Timeout\n\t}\n\treturn nil\n}\n\nfunc (x *Policy) GetStats() *Policy_Stats {\n\tif x != nil {\n\t\treturn x.Stats\n\t}\n\treturn nil\n}\n\nfunc (x *Policy) GetBuffer() *Policy_Buffer {\n\tif x != nil {\n\t\treturn x.Buffer\n\t}\n\treturn nil\n}\n\ntype SystemPolicy struct {\n\tstate                 protoimpl.MessageState `protogen:\"open.v1\"`\n\tStats                 *SystemPolicy_Stats    `protobuf:\"bytes,1,opt,name=stats,proto3\" json:\"stats,omitempty\"`\n\tOverrideAccessLogDest bool                   `protobuf:\"varint,2,opt,name=override_access_log_dest,json=overrideAccessLogDest,proto3\" json:\"override_access_log_dest,omitempty\"`\n\tunknownFields         protoimpl.UnknownFields\n\tsizeCache             protoimpl.SizeCache\n}\n\nfunc (x *SystemPolicy) Reset() {\n\t*x = SystemPolicy{}\n\tmi := &file_app_policy_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SystemPolicy) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SystemPolicy) ProtoMessage() {}\n\nfunc (x *SystemPolicy) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[2]\n\tif 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 SystemPolicy.ProtoReflect.Descriptor instead.\nfunc (*SystemPolicy) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SystemPolicy) GetStats() *SystemPolicy_Stats {\n\tif x != nil {\n\t\treturn x.Stats\n\t}\n\treturn nil\n}\n\nfunc (x *SystemPolicy) GetOverrideAccessLogDest() bool {\n\tif x != nil {\n\t\treturn x.OverrideAccessLogDest\n\t}\n\treturn false\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tLevel         map[uint32]*Policy     `protobuf:\"bytes,1,rep,name=level,proto3\" json:\"level,omitempty\" protobuf_key:\"varint,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tSystem        *SystemPolicy          `protobuf:\"bytes,2,opt,name=system,proto3\" json:\"system,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_policy_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[3]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Config) GetLevel() map[uint32]*Policy {\n\tif x != nil {\n\t\treturn x.Level\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetSystem() *SystemPolicy {\n\tif x != nil {\n\t\treturn x.System\n\t}\n\treturn nil\n}\n\n// Timeout is a message for timeout settings in various stages, in seconds.\ntype Policy_Timeout struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tHandshake      *Second                `protobuf:\"bytes,1,opt,name=handshake,proto3\" json:\"handshake,omitempty\"`\n\tConnectionIdle *Second                `protobuf:\"bytes,2,opt,name=connection_idle,json=connectionIdle,proto3\" json:\"connection_idle,omitempty\"`\n\tUplinkOnly     *Second                `protobuf:\"bytes,3,opt,name=uplink_only,json=uplinkOnly,proto3\" json:\"uplink_only,omitempty\"`\n\tDownlinkOnly   *Second                `protobuf:\"bytes,4,opt,name=downlink_only,json=downlinkOnly,proto3\" json:\"downlink_only,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *Policy_Timeout) Reset() {\n\t*x = Policy_Timeout{}\n\tmi := &file_app_policy_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Policy_Timeout) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Policy_Timeout) ProtoMessage() {}\n\nfunc (x *Policy_Timeout) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[4]\n\tif 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 Policy_Timeout.ProtoReflect.Descriptor instead.\nfunc (*Policy_Timeout) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{1, 0}\n}\n\nfunc (x *Policy_Timeout) GetHandshake() *Second {\n\tif x != nil {\n\t\treturn x.Handshake\n\t}\n\treturn nil\n}\n\nfunc (x *Policy_Timeout) GetConnectionIdle() *Second {\n\tif x != nil {\n\t\treturn x.ConnectionIdle\n\t}\n\treturn nil\n}\n\nfunc (x *Policy_Timeout) GetUplinkOnly() *Second {\n\tif x != nil {\n\t\treturn x.UplinkOnly\n\t}\n\treturn nil\n}\n\nfunc (x *Policy_Timeout) GetDownlinkOnly() *Second {\n\tif x != nil {\n\t\treturn x.DownlinkOnly\n\t}\n\treturn nil\n}\n\ntype Policy_Stats struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUserUplink    bool                   `protobuf:\"varint,1,opt,name=user_uplink,json=userUplink,proto3\" json:\"user_uplink,omitempty\"`\n\tUserDownlink  bool                   `protobuf:\"varint,2,opt,name=user_downlink,json=userDownlink,proto3\" json:\"user_downlink,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Policy_Stats) Reset() {\n\t*x = Policy_Stats{}\n\tmi := &file_app_policy_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Policy_Stats) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Policy_Stats) ProtoMessage() {}\n\nfunc (x *Policy_Stats) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[5]\n\tif 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 Policy_Stats.ProtoReflect.Descriptor instead.\nfunc (*Policy_Stats) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{1, 1}\n}\n\nfunc (x *Policy_Stats) GetUserUplink() bool {\n\tif x != nil {\n\t\treturn x.UserUplink\n\t}\n\treturn false\n}\n\nfunc (x *Policy_Stats) GetUserDownlink() bool {\n\tif x != nil {\n\t\treturn x.UserDownlink\n\t}\n\treturn false\n}\n\ntype Policy_Buffer struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Buffer size per connection, in bytes. -1 for unlimited buffer.\n\tConnection    int32 `protobuf:\"varint,1,opt,name=connection,proto3\" json:\"connection,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Policy_Buffer) Reset() {\n\t*x = Policy_Buffer{}\n\tmi := &file_app_policy_config_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Policy_Buffer) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Policy_Buffer) ProtoMessage() {}\n\nfunc (x *Policy_Buffer) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[6]\n\tif 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 Policy_Buffer.ProtoReflect.Descriptor instead.\nfunc (*Policy_Buffer) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{1, 2}\n}\n\nfunc (x *Policy_Buffer) GetConnection() int32 {\n\tif x != nil {\n\t\treturn x.Connection\n\t}\n\treturn 0\n}\n\ntype SystemPolicy_Stats struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tInboundUplink    bool                   `protobuf:\"varint,1,opt,name=inbound_uplink,json=inboundUplink,proto3\" json:\"inbound_uplink,omitempty\"`\n\tInboundDownlink  bool                   `protobuf:\"varint,2,opt,name=inbound_downlink,json=inboundDownlink,proto3\" json:\"inbound_downlink,omitempty\"`\n\tOutboundUplink   bool                   `protobuf:\"varint,3,opt,name=outbound_uplink,json=outboundUplink,proto3\" json:\"outbound_uplink,omitempty\"`\n\tOutboundDownlink bool                   `protobuf:\"varint,4,opt,name=outbound_downlink,json=outboundDownlink,proto3\" json:\"outbound_downlink,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *SystemPolicy_Stats) Reset() {\n\t*x = SystemPolicy_Stats{}\n\tmi := &file_app_policy_config_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SystemPolicy_Stats) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SystemPolicy_Stats) ProtoMessage() {}\n\nfunc (x *SystemPolicy_Stats) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_policy_config_proto_msgTypes[7]\n\tif 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 SystemPolicy_Stats.ProtoReflect.Descriptor instead.\nfunc (*SystemPolicy_Stats) Descriptor() ([]byte, []int) {\n\treturn file_app_policy_config_proto_rawDescGZIP(), []int{2, 0}\n}\n\nfunc (x *SystemPolicy_Stats) GetInboundUplink() bool {\n\tif x != nil {\n\t\treturn x.InboundUplink\n\t}\n\treturn false\n}\n\nfunc (x *SystemPolicy_Stats) GetInboundDownlink() bool {\n\tif x != nil {\n\t\treturn x.InboundDownlink\n\t}\n\treturn false\n}\n\nfunc (x *SystemPolicy_Stats) GetOutboundUplink() bool {\n\tif x != nil {\n\t\treturn x.OutboundUplink\n\t}\n\treturn false\n}\n\nfunc (x *SystemPolicy_Stats) GetOutboundDownlink() bool {\n\tif x != nil {\n\t\treturn x.OutboundDownlink\n\t}\n\treturn false\n}\n\nvar File_app_policy_config_proto protoreflect.FileDescriptor\n\nconst file_app_policy_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x17app/policy/config.proto\\x12\\x15v2ray.core.app.policy\\x1a common/protoext/extensions.proto\\\"\\x1e\\n\" +\n\t\"\\x06Second\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\\"\\xd0\\x04\\n\" +\n\t\"\\x06Policy\\x12?\\n\" +\n\t\"\\atimeout\\x18\\x01 \\x01(\\v2%.v2ray.core.app.policy.Policy.TimeoutR\\atimeout\\x129\\n\" +\n\t\"\\x05stats\\x18\\x02 \\x01(\\v2#.v2ray.core.app.policy.Policy.StatsR\\x05stats\\x12<\\n\" +\n\t\"\\x06buffer\\x18\\x03 \\x01(\\v2$.v2ray.core.app.policy.Policy.BufferR\\x06buffer\\x1a\\x92\\x02\\n\" +\n\t\"\\aTimeout\\x12;\\n\" +\n\t\"\\thandshake\\x18\\x01 \\x01(\\v2\\x1d.v2ray.core.app.policy.SecondR\\thandshake\\x12F\\n\" +\n\t\"\\x0fconnection_idle\\x18\\x02 \\x01(\\v2\\x1d.v2ray.core.app.policy.SecondR\\x0econnectionIdle\\x12>\\n\" +\n\t\"\\vuplink_only\\x18\\x03 \\x01(\\v2\\x1d.v2ray.core.app.policy.SecondR\\n\" +\n\t\"uplinkOnly\\x12B\\n\" +\n\t\"\\rdownlink_only\\x18\\x04 \\x01(\\v2\\x1d.v2ray.core.app.policy.SecondR\\fdownlinkOnly\\x1aM\\n\" +\n\t\"\\x05Stats\\x12\\x1f\\n\" +\n\t\"\\vuser_uplink\\x18\\x01 \\x01(\\bR\\n\" +\n\t\"userUplink\\x12#\\n\" +\n\t\"\\ruser_downlink\\x18\\x02 \\x01(\\bR\\fuserDownlink\\x1a(\\n\" +\n\t\"\\x06Buffer\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"connection\\x18\\x01 \\x01(\\x05R\\n\" +\n\t\"connection\\\"\\xba\\x02\\n\" +\n\t\"\\fSystemPolicy\\x12?\\n\" +\n\t\"\\x05stats\\x18\\x01 \\x01(\\v2).v2ray.core.app.policy.SystemPolicy.StatsR\\x05stats\\x127\\n\" +\n\t\"\\x18override_access_log_dest\\x18\\x02 \\x01(\\bR\\x15overrideAccessLogDest\\x1a\\xaf\\x01\\n\" +\n\t\"\\x05Stats\\x12%\\n\" +\n\t\"\\x0einbound_uplink\\x18\\x01 \\x01(\\bR\\rinboundUplink\\x12)\\n\" +\n\t\"\\x10inbound_downlink\\x18\\x02 \\x01(\\bR\\x0finboundDownlink\\x12'\\n\" +\n\t\"\\x0foutbound_uplink\\x18\\x03 \\x01(\\bR\\x0eoutboundUplink\\x12+\\n\" +\n\t\"\\x11outbound_downlink\\x18\\x04 \\x01(\\bR\\x10outboundDownlink\\\"\\xf5\\x01\\n\" +\n\t\"\\x06Config\\x12>\\n\" +\n\t\"\\x05level\\x18\\x01 \\x03(\\v2(.v2ray.core.app.policy.Config.LevelEntryR\\x05level\\x12;\\n\" +\n\t\"\\x06system\\x18\\x02 \\x01(\\v2#.v2ray.core.app.policy.SystemPolicyR\\x06system\\x1aW\\n\" +\n\t\"\\n\" +\n\t\"LevelEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\rR\\x03key\\x123\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\v2\\x1d.v2ray.core.app.policy.PolicyR\\x05value:\\x028\\x01:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\aservice\\x12\\x06policyB`\\n\" +\n\t\"\\x19com.v2ray.core.app.policyP\\x01Z)github.com/v2fly/v2ray-core/v5/app/policy\\xaa\\x02\\x15V2Ray.Core.App.Policyb\\x06proto3\"\n\nvar (\n\tfile_app_policy_config_proto_rawDescOnce sync.Once\n\tfile_app_policy_config_proto_rawDescData []byte\n)\n\nfunc file_app_policy_config_proto_rawDescGZIP() []byte {\n\tfile_app_policy_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_policy_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_policy_config_proto_rawDesc), len(file_app_policy_config_proto_rawDesc)))\n\t})\n\treturn file_app_policy_config_proto_rawDescData\n}\n\nvar file_app_policy_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9)\nvar file_app_policy_config_proto_goTypes = []any{\n\t(*Second)(nil),             // 0: v2ray.core.app.policy.Second\n\t(*Policy)(nil),             // 1: v2ray.core.app.policy.Policy\n\t(*SystemPolicy)(nil),       // 2: v2ray.core.app.policy.SystemPolicy\n\t(*Config)(nil),             // 3: v2ray.core.app.policy.Config\n\t(*Policy_Timeout)(nil),     // 4: v2ray.core.app.policy.Policy.Timeout\n\t(*Policy_Stats)(nil),       // 5: v2ray.core.app.policy.Policy.Stats\n\t(*Policy_Buffer)(nil),      // 6: v2ray.core.app.policy.Policy.Buffer\n\t(*SystemPolicy_Stats)(nil), // 7: v2ray.core.app.policy.SystemPolicy.Stats\n\tnil,                        // 8: v2ray.core.app.policy.Config.LevelEntry\n}\nvar file_app_policy_config_proto_depIdxs = []int32{\n\t4,  // 0: v2ray.core.app.policy.Policy.timeout:type_name -> v2ray.core.app.policy.Policy.Timeout\n\t5,  // 1: v2ray.core.app.policy.Policy.stats:type_name -> v2ray.core.app.policy.Policy.Stats\n\t6,  // 2: v2ray.core.app.policy.Policy.buffer:type_name -> v2ray.core.app.policy.Policy.Buffer\n\t7,  // 3: v2ray.core.app.policy.SystemPolicy.stats:type_name -> v2ray.core.app.policy.SystemPolicy.Stats\n\t8,  // 4: v2ray.core.app.policy.Config.level:type_name -> v2ray.core.app.policy.Config.LevelEntry\n\t2,  // 5: v2ray.core.app.policy.Config.system:type_name -> v2ray.core.app.policy.SystemPolicy\n\t0,  // 6: v2ray.core.app.policy.Policy.Timeout.handshake:type_name -> v2ray.core.app.policy.Second\n\t0,  // 7: v2ray.core.app.policy.Policy.Timeout.connection_idle:type_name -> v2ray.core.app.policy.Second\n\t0,  // 8: v2ray.core.app.policy.Policy.Timeout.uplink_only:type_name -> v2ray.core.app.policy.Second\n\t0,  // 9: v2ray.core.app.policy.Policy.Timeout.downlink_only:type_name -> v2ray.core.app.policy.Second\n\t1,  // 10: v2ray.core.app.policy.Config.LevelEntry.value:type_name -> v2ray.core.app.policy.Policy\n\t11, // [11:11] is the sub-list for method output_type\n\t11, // [11:11] is the sub-list for method input_type\n\t11, // [11:11] is the sub-list for extension type_name\n\t11, // [11:11] is the sub-list for extension extendee\n\t0,  // [0:11] is the sub-list for field type_name\n}\n\nfunc init() { file_app_policy_config_proto_init() }\nfunc file_app_policy_config_proto_init() {\n\tif File_app_policy_config_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: unsafe.Slice(unsafe.StringData(file_app_policy_config_proto_rawDesc), len(file_app_policy_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   9,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_policy_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_policy_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_policy_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_policy_config_proto = out.File\n\tfile_app_policy_config_proto_goTypes = nil\n\tfile_app_policy_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/policy/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.policy;\noption csharp_namespace = \"V2Ray.Core.App.Policy\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/policy\";\noption java_package = \"com.v2ray.core.app.policy\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Second {\n  uint32 value = 1;\n}\n\nmessage Policy {\n  // Timeout is a message for timeout settings in various stages, in seconds.\n  message Timeout {\n    Second handshake = 1;\n    Second connection_idle = 2;\n    Second uplink_only = 3;\n    Second downlink_only = 4;\n  }\n\n  message Stats {\n    bool user_uplink = 1;\n    bool user_downlink = 2;\n  }\n\n  message Buffer {\n    // Buffer size per connection, in bytes. -1 for unlimited buffer.\n    int32 connection = 1;\n  }\n\n  Timeout timeout = 1;\n  Stats stats = 2;\n  Buffer buffer = 3;\n}\n\nmessage SystemPolicy {\n  message Stats {\n    bool inbound_uplink = 1;\n    bool inbound_downlink = 2;\n    bool outbound_uplink = 3;\n    bool outbound_downlink = 4;\n  }\n\n  Stats stats = 1;\n  bool override_access_log_dest = 2;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"policy\";\n\n  map<uint32, Policy> level = 1;\n  SystemPolicy system = 2;\n}\n"
  },
  {
    "path": "app/policy/errors.generated.go",
    "content": "package policy\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/policy/manager.go",
    "content": "package policy\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n)\n\n// Instance is an instance of Policy manager.\ntype Instance struct {\n\tlevels map[uint32]*Policy\n\tsystem *SystemPolicy\n}\n\n// New creates new Policy manager instance.\nfunc New(ctx context.Context, config *Config) (*Instance, error) {\n\tm := &Instance{\n\t\tlevels: make(map[uint32]*Policy),\n\t\tsystem: config.System,\n\t}\n\tif len(config.Level) > 0 {\n\t\tfor lv, p := range config.Level {\n\t\t\tpp := defaultPolicy()\n\t\t\tpp.overrideWith(p)\n\t\t\tm.levels[lv] = pp\n\t\t}\n\t}\n\n\treturn m, nil\n}\n\n// Type implements common.HasType.\nfunc (*Instance) Type() interface{} {\n\treturn policy.ManagerType()\n}\n\n// ForLevel implements policy.Manager.\nfunc (m *Instance) ForLevel(level uint32) policy.Session {\n\tif p, ok := m.levels[level]; ok {\n\t\treturn p.ToCorePolicy()\n\t}\n\treturn policy.SessionDefault()\n}\n\n// ForSystem implements policy.Manager.\nfunc (m *Instance) ForSystem() policy.System {\n\tif m.system == nil {\n\t\treturn policy.System{}\n\t}\n\treturn m.system.ToCorePolicy()\n}\n\n// Start implements common.Runnable.Start().\nfunc (m *Instance) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.Close().\nfunc (m *Instance) Close() error {\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/policy/manager_test.go",
    "content": "package policy_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n)\n\nfunc TestPolicy(t *testing.T) {\n\tmanager, err := New(context.Background(), &Config{\n\t\tLevel: map[uint32]*Policy{\n\t\t\t0: {\n\t\t\t\tTimeout: &Policy_Timeout{\n\t\t\t\t\tHandshake: &Second{\n\t\t\t\t\t\tValue: 2,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\n\tpDefault := policy.SessionDefault()\n\n\t{\n\t\tp := manager.ForLevel(0)\n\t\tif p.Timeouts.Handshake != 2*time.Second {\n\t\t\tt.Error(\"expect 2 sec timeout, but got \", p.Timeouts.Handshake)\n\t\t}\n\t\tif p.Timeouts.ConnectionIdle != pDefault.Timeouts.ConnectionIdle {\n\t\t\tt.Error(\"expect \", pDefault.Timeouts.ConnectionIdle, \" sec timeout, but got \", p.Timeouts.ConnectionIdle)\n\t\t}\n\t}\n\n\t{\n\t\tp := manager.ForLevel(1)\n\t\tif p.Timeouts.Handshake != pDefault.Timeouts.Handshake {\n\t\t\tt.Error(\"expect \", pDefault.Timeouts.Handshake, \" sec timeout, but got \", p.Timeouts.Handshake)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/policy/policy.go",
    "content": "// Package policy is an implementation of policy.Manager feature.\npackage policy\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/proxyman/command/command.go",
    "content": "package command\n\nimport (\n\t\"context\"\n\n\tgrpc \"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n)\n\n// InboundOperation is the interface for operations that applies to inbound handlers.\ntype InboundOperation interface {\n\t// ApplyInbound applies this operation to the given inbound handler.\n\tApplyInbound(context.Context, inbound.Handler) error\n}\n\n// OutboundOperation is the interface for operations that applies to outbound handlers.\ntype OutboundOperation interface {\n\t// ApplyOutbound applies this operation to the given outbound handler.\n\tApplyOutbound(context.Context, outbound.Handler) error\n}\n\nfunc getInbound(handler inbound.Handler) (proxy.Inbound, error) {\n\tgi, ok := handler.(proxy.GetInbound)\n\tif !ok {\n\t\treturn nil, newError(\"can't get inbound proxy from handler.\")\n\t}\n\treturn gi.GetInbound(), nil\n}\n\n// ApplyInbound implements InboundOperation.\nfunc (op *AddUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {\n\tp, err := getInbound(handler)\n\tif err != nil {\n\t\treturn err\n\t}\n\tum, ok := p.(proxy.UserManager)\n\tif !ok {\n\t\treturn newError(\"proxy is not a UserManager\")\n\t}\n\tmUser, err := op.User.ToMemoryUser()\n\tif err != nil {\n\t\treturn newError(\"failed to parse user\").Base(err)\n\t}\n\treturn um.AddUser(ctx, mUser)\n}\n\n// ApplyInbound implements InboundOperation.\nfunc (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {\n\tp, err := getInbound(handler)\n\tif err != nil {\n\t\treturn err\n\t}\n\tum, ok := p.(proxy.UserManager)\n\tif !ok {\n\t\treturn newError(\"proxy is not a UserManager\")\n\t}\n\treturn um.RemoveUser(ctx, op.Email)\n}\n\ntype handlerServer struct {\n\ts   *core.Instance\n\tihm inbound.Manager\n\tohm outbound.Manager\n}\n\nfunc (s *handlerServer) AddInbound(ctx context.Context, request *AddInboundRequest) (*AddInboundResponse, error) {\n\tif err := core.AddInboundHandler(s.s, request.Inbound); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AddInboundResponse{}, nil\n}\n\nfunc (s *handlerServer) RemoveInbound(ctx context.Context, request *RemoveInboundRequest) (*RemoveInboundResponse, error) {\n\treturn &RemoveInboundResponse{}, s.ihm.RemoveHandler(ctx, request.Tag)\n}\n\nfunc (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {\n\trawOperation, err := serial.GetInstanceOf(request.Operation)\n\tif err != nil {\n\t\treturn nil, newError(\"unknown operation\").Base(err)\n\t}\n\toperation, ok := rawOperation.(InboundOperation)\n\tif !ok {\n\t\treturn nil, newError(\"not an inbound operation\")\n\t}\n\n\thandler, err := s.ihm.GetHandler(ctx, request.Tag)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get handler: \", request.Tag).Base(err)\n\t}\n\n\treturn &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)\n}\n\nfunc (s *handlerServer) AddOutbound(ctx context.Context, request *AddOutboundRequest) (*AddOutboundResponse, error) {\n\tif err := core.AddOutboundHandler(s.s, request.Outbound); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &AddOutboundResponse{}, nil\n}\n\nfunc (s *handlerServer) RemoveOutbound(ctx context.Context, request *RemoveOutboundRequest) (*RemoveOutboundResponse, error) {\n\treturn &RemoveOutboundResponse{}, core.RemoveOutboundHandler(s.s, request.Tag)\n}\n\nfunc (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) {\n\trawOperation, err := serial.GetInstanceOf(request.Operation)\n\tif err != nil {\n\t\treturn nil, newError(\"unknown operation\").Base(err)\n\t}\n\toperation, ok := rawOperation.(OutboundOperation)\n\tif !ok {\n\t\treturn nil, newError(\"not an outbound operation\")\n\t}\n\n\thandler := s.ohm.GetHandler(request.Tag)\n\treturn &AlterOutboundResponse{}, operation.ApplyOutbound(ctx, handler)\n}\n\nfunc (s *handlerServer) mustEmbedUnimplementedHandlerServiceServer() {}\n\ntype service struct {\n\tv *core.Instance\n}\n\nfunc (s *service) Register(server *grpc.Server) {\n\ths := &handlerServer{\n\t\ts: s.v,\n\t}\n\tcommon.Must(s.v.RequireFeatures(func(im inbound.Manager, om outbound.Manager) {\n\t\ths.ihm = im\n\t\ths.ohm = om\n\t}))\n\tRegisterHandlerServiceServer(server, hs)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\ts := core.MustFromContext(ctx)\n\t\treturn &service{v: s}, nil\n\t}))\n}\n"
  },
  {
    "path": "app/proxyman/command/command.pb.go",
    "content": "package command\n\nimport (\n\tv5 \"github.com/v2fly/v2ray-core/v5\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 AddUserOperation struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUser          *protocol.User         `protobuf:\"bytes,1,opt,name=user,proto3\" json:\"user,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddUserOperation) Reset() {\n\t*x = AddUserOperation{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddUserOperation) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddUserOperation) ProtoMessage() {}\n\nfunc (x *AddUserOperation) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[0]\n\tif 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 AddUserOperation.ProtoReflect.Descriptor instead.\nfunc (*AddUserOperation) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *AddUserOperation) GetUser() *protocol.User {\n\tif x != nil {\n\t\treturn x.User\n\t}\n\treturn nil\n}\n\ntype RemoveUserOperation struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tEmail         string                 `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveUserOperation) Reset() {\n\t*x = RemoveUserOperation{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveUserOperation) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveUserOperation) ProtoMessage() {}\n\nfunc (x *RemoveUserOperation) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[1]\n\tif 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 RemoveUserOperation.ProtoReflect.Descriptor instead.\nfunc (*RemoveUserOperation) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *RemoveUserOperation) GetEmail() string {\n\tif x != nil {\n\t\treturn x.Email\n\t}\n\treturn \"\"\n}\n\ntype AddInboundRequest struct {\n\tstate         protoimpl.MessageState   `protogen:\"open.v1\"`\n\tInbound       *v5.InboundHandlerConfig `protobuf:\"bytes,1,opt,name=inbound,proto3\" json:\"inbound,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddInboundRequest) Reset() {\n\t*x = AddInboundRequest{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddInboundRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddInboundRequest) ProtoMessage() {}\n\nfunc (x *AddInboundRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[2]\n\tif 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 AddInboundRequest.ProtoReflect.Descriptor instead.\nfunc (*AddInboundRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *AddInboundRequest) GetInbound() *v5.InboundHandlerConfig {\n\tif x != nil {\n\t\treturn x.Inbound\n\t}\n\treturn nil\n}\n\ntype AddInboundResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddInboundResponse) Reset() {\n\t*x = AddInboundResponse{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddInboundResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddInboundResponse) ProtoMessage() {}\n\nfunc (x *AddInboundResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[3]\n\tif 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 AddInboundResponse.ProtoReflect.Descriptor instead.\nfunc (*AddInboundResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{3}\n}\n\ntype RemoveInboundRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveInboundRequest) Reset() {\n\t*x = RemoveInboundRequest{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveInboundRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveInboundRequest) ProtoMessage() {}\n\nfunc (x *RemoveInboundRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[4]\n\tif 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 RemoveInboundRequest.ProtoReflect.Descriptor instead.\nfunc (*RemoveInboundRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *RemoveInboundRequest) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\ntype RemoveInboundResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveInboundResponse) Reset() {\n\t*x = RemoveInboundResponse{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveInboundResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveInboundResponse) ProtoMessage() {}\n\nfunc (x *RemoveInboundResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[5]\n\tif 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 RemoveInboundResponse.ProtoReflect.Descriptor instead.\nfunc (*RemoveInboundResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{5}\n}\n\ntype AlterInboundRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tOperation     *anypb.Any             `protobuf:\"bytes,2,opt,name=operation,proto3\" json:\"operation,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AlterInboundRequest) Reset() {\n\t*x = AlterInboundRequest{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AlterInboundRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AlterInboundRequest) ProtoMessage() {}\n\nfunc (x *AlterInboundRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[6]\n\tif 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 AlterInboundRequest.ProtoReflect.Descriptor instead.\nfunc (*AlterInboundRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *AlterInboundRequest) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *AlterInboundRequest) GetOperation() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Operation\n\t}\n\treturn nil\n}\n\ntype AlterInboundResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AlterInboundResponse) Reset() {\n\t*x = AlterInboundResponse{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AlterInboundResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AlterInboundResponse) ProtoMessage() {}\n\nfunc (x *AlterInboundResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[7]\n\tif 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 AlterInboundResponse.ProtoReflect.Descriptor instead.\nfunc (*AlterInboundResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{7}\n}\n\ntype AddOutboundRequest struct {\n\tstate         protoimpl.MessageState    `protogen:\"open.v1\"`\n\tOutbound      *v5.OutboundHandlerConfig `protobuf:\"bytes,1,opt,name=outbound,proto3\" json:\"outbound,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddOutboundRequest) Reset() {\n\t*x = AddOutboundRequest{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddOutboundRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddOutboundRequest) ProtoMessage() {}\n\nfunc (x *AddOutboundRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[8]\n\tif 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 AddOutboundRequest.ProtoReflect.Descriptor instead.\nfunc (*AddOutboundRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *AddOutboundRequest) GetOutbound() *v5.OutboundHandlerConfig {\n\tif x != nil {\n\t\treturn x.Outbound\n\t}\n\treturn nil\n}\n\ntype AddOutboundResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddOutboundResponse) Reset() {\n\t*x = AddOutboundResponse{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[9]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddOutboundResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddOutboundResponse) ProtoMessage() {}\n\nfunc (x *AddOutboundResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[9]\n\tif 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 AddOutboundResponse.ProtoReflect.Descriptor instead.\nfunc (*AddOutboundResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{9}\n}\n\ntype RemoveOutboundRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveOutboundRequest) Reset() {\n\t*x = RemoveOutboundRequest{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[10]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveOutboundRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveOutboundRequest) ProtoMessage() {}\n\nfunc (x *RemoveOutboundRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[10]\n\tif 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 RemoveOutboundRequest.ProtoReflect.Descriptor instead.\nfunc (*RemoveOutboundRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *RemoveOutboundRequest) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\ntype RemoveOutboundResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveOutboundResponse) Reset() {\n\t*x = RemoveOutboundResponse{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[11]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveOutboundResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveOutboundResponse) ProtoMessage() {}\n\nfunc (x *RemoveOutboundResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[11]\n\tif 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 RemoveOutboundResponse.ProtoReflect.Descriptor instead.\nfunc (*RemoveOutboundResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{11}\n}\n\ntype AlterOutboundRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tOperation     *anypb.Any             `protobuf:\"bytes,2,opt,name=operation,proto3\" json:\"operation,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AlterOutboundRequest) Reset() {\n\t*x = AlterOutboundRequest{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[12]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AlterOutboundRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AlterOutboundRequest) ProtoMessage() {}\n\nfunc (x *AlterOutboundRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[12]\n\tif 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 AlterOutboundRequest.ProtoReflect.Descriptor instead.\nfunc (*AlterOutboundRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{12}\n}\n\nfunc (x *AlterOutboundRequest) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *AlterOutboundRequest) GetOperation() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Operation\n\t}\n\treturn nil\n}\n\ntype AlterOutboundResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AlterOutboundResponse) Reset() {\n\t*x = AlterOutboundResponse{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[13]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AlterOutboundResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AlterOutboundResponse) ProtoMessage() {}\n\nfunc (x *AlterOutboundResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[13]\n\tif 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 AlterOutboundResponse.ProtoReflect.Descriptor instead.\nfunc (*AlterOutboundResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{13}\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[14]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_command_command_proto_msgTypes[14]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_command_command_proto_rawDescGZIP(), []int{14}\n}\n\nvar File_app_proxyman_command_command_proto protoreflect.FileDescriptor\n\nconst file_app_proxyman_command_command_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\\"app/proxyman/command/command.proto\\x12\\x1fv2ray.core.app.proxyman.command\\x1a\\x1acommon/protocol/user.proto\\x1a\\x19google/protobuf/any.proto\\x1a common/protoext/extensions.proto\\x1a\\fconfig.proto\\\"H\\n\" +\n\t\"\\x10AddUserOperation\\x124\\n\" +\n\t\"\\x04user\\x18\\x01 \\x01(\\v2 .v2ray.core.common.protocol.UserR\\x04user\\\"+\\n\" +\n\t\"\\x13RemoveUserOperation\\x12\\x14\\n\" +\n\t\"\\x05email\\x18\\x01 \\x01(\\tR\\x05email\\\"O\\n\" +\n\t\"\\x11AddInboundRequest\\x12:\\n\" +\n\t\"\\ainbound\\x18\\x01 \\x01(\\v2 .v2ray.core.InboundHandlerConfigR\\ainbound\\\"\\x14\\n\" +\n\t\"\\x12AddInboundResponse\\\"(\\n\" +\n\t\"\\x14RemoveInboundRequest\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\\"\\x17\\n\" +\n\t\"\\x15RemoveInboundResponse\\\"[\\n\" +\n\t\"\\x13AlterInboundRequest\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x122\\n\" +\n\t\"\\toperation\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\toperation\\\"\\x16\\n\" +\n\t\"\\x14AlterInboundResponse\\\"S\\n\" +\n\t\"\\x12AddOutboundRequest\\x12=\\n\" +\n\t\"\\boutbound\\x18\\x01 \\x01(\\v2!.v2ray.core.OutboundHandlerConfigR\\boutbound\\\"\\x15\\n\" +\n\t\"\\x13AddOutboundResponse\\\")\\n\" +\n\t\"\\x15RemoveOutboundRequest\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\\"\\x18\\n\" +\n\t\"\\x16RemoveOutboundResponse\\\"\\\\\\n\" +\n\t\"\\x14AlterOutboundRequest\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x122\\n\" +\n\t\"\\toperation\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\toperation\\\"\\x17\\n\" +\n\t\"\\x15AlterOutboundResponse\\\"%\\n\" +\n\t\"\\x06Config:\\x1b\\x82\\xb5\\x18\\x17\\n\" +\n\t\"\\vgrpcservice\\x12\\bproxyman2\\x90\\x06\\n\" +\n\t\"\\x0eHandlerService\\x12w\\n\" +\n\t\"\\n\" +\n\t\"AddInbound\\x122.v2ray.core.app.proxyman.command.AddInboundRequest\\x1a3.v2ray.core.app.proxyman.command.AddInboundResponse\\\"\\x00\\x12\\x80\\x01\\n\" +\n\t\"\\rRemoveInbound\\x125.v2ray.core.app.proxyman.command.RemoveInboundRequest\\x1a6.v2ray.core.app.proxyman.command.RemoveInboundResponse\\\"\\x00\\x12}\\n\" +\n\t\"\\fAlterInbound\\x124.v2ray.core.app.proxyman.command.AlterInboundRequest\\x1a5.v2ray.core.app.proxyman.command.AlterInboundResponse\\\"\\x00\\x12z\\n\" +\n\t\"\\vAddOutbound\\x123.v2ray.core.app.proxyman.command.AddOutboundRequest\\x1a4.v2ray.core.app.proxyman.command.AddOutboundResponse\\\"\\x00\\x12\\x83\\x01\\n\" +\n\t\"\\x0eRemoveOutbound\\x126.v2ray.core.app.proxyman.command.RemoveOutboundRequest\\x1a7.v2ray.core.app.proxyman.command.RemoveOutboundResponse\\\"\\x00\\x12\\x80\\x01\\n\" +\n\t\"\\rAlterOutbound\\x125.v2ray.core.app.proxyman.command.AlterOutboundRequest\\x1a6.v2ray.core.app.proxyman.command.AlterOutboundResponse\\\"\\x00B~\\n\" +\n\t\"#com.v2ray.core.app.proxyman.commandP\\x01Z3github.com/v2fly/v2ray-core/v5/app/proxyman/command\\xaa\\x02\\x1fV2Ray.Core.App.Proxyman.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_proxyman_command_command_proto_rawDescOnce sync.Once\n\tfile_app_proxyman_command_command_proto_rawDescData []byte\n)\n\nfunc file_app_proxyman_command_command_proto_rawDescGZIP() []byte {\n\tfile_app_proxyman_command_command_proto_rawDescOnce.Do(func() {\n\t\tfile_app_proxyman_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_proxyman_command_command_proto_rawDesc), len(file_app_proxyman_command_command_proto_rawDesc)))\n\t})\n\treturn file_app_proxyman_command_command_proto_rawDescData\n}\n\nvar file_app_proxyman_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 15)\nvar file_app_proxyman_command_command_proto_goTypes = []any{\n\t(*AddUserOperation)(nil),         // 0: v2ray.core.app.proxyman.command.AddUserOperation\n\t(*RemoveUserOperation)(nil),      // 1: v2ray.core.app.proxyman.command.RemoveUserOperation\n\t(*AddInboundRequest)(nil),        // 2: v2ray.core.app.proxyman.command.AddInboundRequest\n\t(*AddInboundResponse)(nil),       // 3: v2ray.core.app.proxyman.command.AddInboundResponse\n\t(*RemoveInboundRequest)(nil),     // 4: v2ray.core.app.proxyman.command.RemoveInboundRequest\n\t(*RemoveInboundResponse)(nil),    // 5: v2ray.core.app.proxyman.command.RemoveInboundResponse\n\t(*AlterInboundRequest)(nil),      // 6: v2ray.core.app.proxyman.command.AlterInboundRequest\n\t(*AlterInboundResponse)(nil),     // 7: v2ray.core.app.proxyman.command.AlterInboundResponse\n\t(*AddOutboundRequest)(nil),       // 8: v2ray.core.app.proxyman.command.AddOutboundRequest\n\t(*AddOutboundResponse)(nil),      // 9: v2ray.core.app.proxyman.command.AddOutboundResponse\n\t(*RemoveOutboundRequest)(nil),    // 10: v2ray.core.app.proxyman.command.RemoveOutboundRequest\n\t(*RemoveOutboundResponse)(nil),   // 11: v2ray.core.app.proxyman.command.RemoveOutboundResponse\n\t(*AlterOutboundRequest)(nil),     // 12: v2ray.core.app.proxyman.command.AlterOutboundRequest\n\t(*AlterOutboundResponse)(nil),    // 13: v2ray.core.app.proxyman.command.AlterOutboundResponse\n\t(*Config)(nil),                   // 14: v2ray.core.app.proxyman.command.Config\n\t(*protocol.User)(nil),            // 15: v2ray.core.common.protocol.User\n\t(*v5.InboundHandlerConfig)(nil),  // 16: v2ray.core.InboundHandlerConfig\n\t(*anypb.Any)(nil),                // 17: google.protobuf.Any\n\t(*v5.OutboundHandlerConfig)(nil), // 18: v2ray.core.OutboundHandlerConfig\n}\nvar file_app_proxyman_command_command_proto_depIdxs = []int32{\n\t15, // 0: v2ray.core.app.proxyman.command.AddUserOperation.user:type_name -> v2ray.core.common.protocol.User\n\t16, // 1: v2ray.core.app.proxyman.command.AddInboundRequest.inbound:type_name -> v2ray.core.InboundHandlerConfig\n\t17, // 2: v2ray.core.app.proxyman.command.AlterInboundRequest.operation:type_name -> google.protobuf.Any\n\t18, // 3: v2ray.core.app.proxyman.command.AddOutboundRequest.outbound:type_name -> v2ray.core.OutboundHandlerConfig\n\t17, // 4: v2ray.core.app.proxyman.command.AlterOutboundRequest.operation:type_name -> google.protobuf.Any\n\t2,  // 5: v2ray.core.app.proxyman.command.HandlerService.AddInbound:input_type -> v2ray.core.app.proxyman.command.AddInboundRequest\n\t4,  // 6: v2ray.core.app.proxyman.command.HandlerService.RemoveInbound:input_type -> v2ray.core.app.proxyman.command.RemoveInboundRequest\n\t6,  // 7: v2ray.core.app.proxyman.command.HandlerService.AlterInbound:input_type -> v2ray.core.app.proxyman.command.AlterInboundRequest\n\t8,  // 8: v2ray.core.app.proxyman.command.HandlerService.AddOutbound:input_type -> v2ray.core.app.proxyman.command.AddOutboundRequest\n\t10, // 9: v2ray.core.app.proxyman.command.HandlerService.RemoveOutbound:input_type -> v2ray.core.app.proxyman.command.RemoveOutboundRequest\n\t12, // 10: v2ray.core.app.proxyman.command.HandlerService.AlterOutbound:input_type -> v2ray.core.app.proxyman.command.AlterOutboundRequest\n\t3,  // 11: v2ray.core.app.proxyman.command.HandlerService.AddInbound:output_type -> v2ray.core.app.proxyman.command.AddInboundResponse\n\t5,  // 12: v2ray.core.app.proxyman.command.HandlerService.RemoveInbound:output_type -> v2ray.core.app.proxyman.command.RemoveInboundResponse\n\t7,  // 13: v2ray.core.app.proxyman.command.HandlerService.AlterInbound:output_type -> v2ray.core.app.proxyman.command.AlterInboundResponse\n\t9,  // 14: v2ray.core.app.proxyman.command.HandlerService.AddOutbound:output_type -> v2ray.core.app.proxyman.command.AddOutboundResponse\n\t11, // 15: v2ray.core.app.proxyman.command.HandlerService.RemoveOutbound:output_type -> v2ray.core.app.proxyman.command.RemoveOutboundResponse\n\t13, // 16: v2ray.core.app.proxyman.command.HandlerService.AlterOutbound:output_type -> v2ray.core.app.proxyman.command.AlterOutboundResponse\n\t11, // [11:17] is the sub-list for method output_type\n\t5,  // [5:11] is the sub-list for method input_type\n\t5,  // [5:5] is the sub-list for extension type_name\n\t5,  // [5:5] is the sub-list for extension extendee\n\t0,  // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_app_proxyman_command_command_proto_init() }\nfunc file_app_proxyman_command_command_proto_init() {\n\tif File_app_proxyman_command_command_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: unsafe.Slice(unsafe.StringData(file_app_proxyman_command_command_proto_rawDesc), len(file_app_proxyman_command_command_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   15,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_proxyman_command_command_proto_goTypes,\n\t\tDependencyIndexes: file_app_proxyman_command_command_proto_depIdxs,\n\t\tMessageInfos:      file_app_proxyman_command_command_proto_msgTypes,\n\t}.Build()\n\tFile_app_proxyman_command_command_proto = out.File\n\tfile_app_proxyman_command_command_proto_goTypes = nil\n\tfile_app_proxyman_command_command_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/proxyman/command/command.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.proxyman.command;\noption csharp_namespace = \"V2Ray.Core.App.Proxyman.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\";\noption java_package = \"com.v2ray.core.app.proxyman.command\";\noption java_multiple_files = true;\n\nimport \"common/protocol/user.proto\";\nimport \"google/protobuf/any.proto\";\nimport \"common/protoext/extensions.proto\";\nimport \"config.proto\";\n\nmessage AddUserOperation {\n  v2ray.core.common.protocol.User user = 1;\n}\n\nmessage RemoveUserOperation {\n  string email = 1;\n}\n\nmessage AddInboundRequest {\n  core.InboundHandlerConfig inbound = 1;\n}\n\nmessage AddInboundResponse {}\n\nmessage RemoveInboundRequest {\n  string tag = 1;\n}\n\nmessage RemoveInboundResponse {}\n\nmessage AlterInboundRequest {\n  string tag = 1;\n  google.protobuf.Any operation = 2;\n}\n\nmessage AlterInboundResponse {}\n\nmessage AddOutboundRequest {\n  core.OutboundHandlerConfig outbound = 1;\n}\n\nmessage AddOutboundResponse {}\n\nmessage RemoveOutboundRequest {\n  string tag = 1;\n}\n\nmessage RemoveOutboundResponse {}\n\nmessage AlterOutboundRequest {\n  string tag = 1;\n  google.protobuf.Any operation = 2;\n}\n\nmessage AlterOutboundResponse {}\n\nservice HandlerService {\n  rpc AddInbound(AddInboundRequest) returns (AddInboundResponse) {}\n\n  rpc RemoveInbound(RemoveInboundRequest) returns (RemoveInboundResponse) {}\n\n  rpc AlterInbound(AlterInboundRequest) returns (AlterInboundResponse) {}\n\n  rpc AddOutbound(AddOutboundRequest) returns (AddOutboundResponse) {}\n\n  rpc RemoveOutbound(RemoveOutboundRequest) returns (RemoveOutboundResponse) {}\n\n  rpc AlterOutbound(AlterOutboundRequest) returns (AlterOutboundResponse) {}\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"proxyman\";\n}\n"
  },
  {
    "path": "app/proxyman/command/command_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tHandlerService_AddInbound_FullMethodName     = \"/v2ray.core.app.proxyman.command.HandlerService/AddInbound\"\n\tHandlerService_RemoveInbound_FullMethodName  = \"/v2ray.core.app.proxyman.command.HandlerService/RemoveInbound\"\n\tHandlerService_AlterInbound_FullMethodName   = \"/v2ray.core.app.proxyman.command.HandlerService/AlterInbound\"\n\tHandlerService_AddOutbound_FullMethodName    = \"/v2ray.core.app.proxyman.command.HandlerService/AddOutbound\"\n\tHandlerService_RemoveOutbound_FullMethodName = \"/v2ray.core.app.proxyman.command.HandlerService/RemoveOutbound\"\n\tHandlerService_AlterOutbound_FullMethodName  = \"/v2ray.core.app.proxyman.command.HandlerService/AlterOutbound\"\n)\n\n// HandlerServiceClient is the client API for HandlerService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype HandlerServiceClient interface {\n\tAddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error)\n\tRemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error)\n\tAlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error)\n\tAddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error)\n\tRemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error)\n\tAlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error)\n}\n\ntype handlerServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewHandlerServiceClient(cc grpc.ClientConnInterface) HandlerServiceClient {\n\treturn &handlerServiceClient{cc}\n}\n\nfunc (c *handlerServiceClient) AddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(AddInboundResponse)\n\terr := c.cc.Invoke(ctx, HandlerService_AddInbound_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(RemoveInboundResponse)\n\terr := c.cc.Invoke(ctx, HandlerService_RemoveInbound_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *handlerServiceClient) AlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(AlterInboundResponse)\n\terr := c.cc.Invoke(ctx, HandlerService_AlterInbound_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *handlerServiceClient) AddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(AddOutboundResponse)\n\terr := c.cc.Invoke(ctx, HandlerService_AddOutbound_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(RemoveOutboundResponse)\n\terr := c.cc.Invoke(ctx, HandlerService_RemoveOutbound_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *handlerServiceClient) AlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(AlterOutboundResponse)\n\terr := c.cc.Invoke(ctx, HandlerService_AlterOutbound_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// HandlerServiceServer is the server API for HandlerService service.\n// All implementations must embed UnimplementedHandlerServiceServer\n// for forward compatibility.\ntype HandlerServiceServer interface {\n\tAddInbound(context.Context, *AddInboundRequest) (*AddInboundResponse, error)\n\tRemoveInbound(context.Context, *RemoveInboundRequest) (*RemoveInboundResponse, error)\n\tAlterInbound(context.Context, *AlterInboundRequest) (*AlterInboundResponse, error)\n\tAddOutbound(context.Context, *AddOutboundRequest) (*AddOutboundResponse, error)\n\tRemoveOutbound(context.Context, *RemoveOutboundRequest) (*RemoveOutboundResponse, error)\n\tAlterOutbound(context.Context, *AlterOutboundRequest) (*AlterOutboundResponse, error)\n\tmustEmbedUnimplementedHandlerServiceServer()\n}\n\n// UnimplementedHandlerServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedHandlerServiceServer struct{}\n\nfunc (UnimplementedHandlerServiceServer) AddInbound(context.Context, *AddInboundRequest) (*AddInboundResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method AddInbound not implemented\")\n}\nfunc (UnimplementedHandlerServiceServer) RemoveInbound(context.Context, *RemoveInboundRequest) (*RemoveInboundResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method RemoveInbound not implemented\")\n}\nfunc (UnimplementedHandlerServiceServer) AlterInbound(context.Context, *AlterInboundRequest) (*AlterInboundResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method AlterInbound not implemented\")\n}\nfunc (UnimplementedHandlerServiceServer) AddOutbound(context.Context, *AddOutboundRequest) (*AddOutboundResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method AddOutbound not implemented\")\n}\nfunc (UnimplementedHandlerServiceServer) RemoveOutbound(context.Context, *RemoveOutboundRequest) (*RemoveOutboundResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method RemoveOutbound not implemented\")\n}\nfunc (UnimplementedHandlerServiceServer) AlterOutbound(context.Context, *AlterOutboundRequest) (*AlterOutboundResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method AlterOutbound not implemented\")\n}\nfunc (UnimplementedHandlerServiceServer) mustEmbedUnimplementedHandlerServiceServer() {}\nfunc (UnimplementedHandlerServiceServer) testEmbeddedByValue()                        {}\n\n// UnsafeHandlerServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to HandlerServiceServer will\n// result in compilation errors.\ntype UnsafeHandlerServiceServer interface {\n\tmustEmbedUnimplementedHandlerServiceServer()\n}\n\nfunc RegisterHandlerServiceServer(s grpc.ServiceRegistrar, srv HandlerServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedHandlerServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&HandlerService_ServiceDesc, srv)\n}\n\nfunc _HandlerService_AddInbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddInboundRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HandlerServiceServer).AddInbound(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: HandlerService_AddInbound_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HandlerServiceServer).AddInbound(ctx, req.(*AddInboundRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _HandlerService_RemoveInbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(RemoveInboundRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HandlerServiceServer).RemoveInbound(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: HandlerService_RemoveInbound_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HandlerServiceServer).RemoveInbound(ctx, req.(*RemoveInboundRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _HandlerService_AlterInbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AlterInboundRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HandlerServiceServer).AlterInbound(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: HandlerService_AlterInbound_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HandlerServiceServer).AlterInbound(ctx, req.(*AlterInboundRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _HandlerService_AddOutbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddOutboundRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HandlerServiceServer).AddOutbound(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: HandlerService_AddOutbound_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HandlerServiceServer).AddOutbound(ctx, req.(*AddOutboundRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _HandlerService_RemoveOutbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(RemoveOutboundRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HandlerServiceServer).RemoveOutbound(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: HandlerService_RemoveOutbound_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HandlerServiceServer).RemoveOutbound(ctx, req.(*RemoveOutboundRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _HandlerService_AlterOutbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AlterOutboundRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(HandlerServiceServer).AlterOutbound(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: HandlerService_AlterOutbound_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(HandlerServiceServer).AlterOutbound(ctx, req.(*AlterOutboundRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// HandlerService_ServiceDesc is the grpc.ServiceDesc for HandlerService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar HandlerService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.proxyman.command.HandlerService\",\n\tHandlerType: (*HandlerServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"AddInbound\",\n\t\t\tHandler:    _HandlerService_AddInbound_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"RemoveInbound\",\n\t\t\tHandler:    _HandlerService_RemoveInbound_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"AlterInbound\",\n\t\t\tHandler:    _HandlerService_AlterInbound_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"AddOutbound\",\n\t\t\tHandler:    _HandlerService_AddOutbound_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"RemoveOutbound\",\n\t\t\tHandler:    _HandlerService_RemoveOutbound_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"AlterOutbound\",\n\t\t\tHandler:    _HandlerService_AlterOutbound_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"app/proxyman/command/command.proto\",\n}\n"
  },
  {
    "path": "app/proxyman/command/doc.go",
    "content": "package command\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/proxyman/command/errors.generated.go",
    "content": "package command\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/proxyman/config.go",
    "content": "package proxyman\n\nfunc (s *AllocationStrategy) GetConcurrencyValue() uint32 {\n\tif s == nil || s.Concurrency == nil {\n\t\treturn 3\n\t}\n\treturn s.Concurrency.Value\n}\n\nfunc (s *AllocationStrategy) GetRefreshValue() uint32 {\n\tif s == nil || s.Refresh == nil {\n\t\treturn 5\n\t}\n\treturn s.Refresh.Value\n}\n\nfunc (c *ReceiverConfig) GetEffectiveSniffingSettings() *SniffingConfig {\n\tif c.SniffingSettings != nil {\n\t\treturn c.SniffingSettings\n\t}\n\n\tif len(c.DomainOverride) > 0 {\n\t\tvar p []string\n\t\tfor _, kd := range c.DomainOverride {\n\t\t\tswitch kd {\n\t\t\tcase KnownProtocols_HTTP:\n\t\t\t\tp = append(p, \"http\")\n\t\t\tcase KnownProtocols_TLS:\n\t\t\t\tp = append(p, \"tls\")\n\t\t\t}\n\t\t}\n\t\treturn &SniffingConfig{\n\t\t\tEnabled:             true,\n\t\t\tDestinationOverride: p,\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "app/proxyman/config.pb.go",
    "content": "package proxyman\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tinternet \"github.com/v2fly/v2ray-core/v5/transport/internet\"\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\tunsafe \"unsafe\"\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 KnownProtocols int32\n\nconst (\n\tKnownProtocols_HTTP KnownProtocols = 0\n\tKnownProtocols_TLS  KnownProtocols = 1\n)\n\n// Enum value maps for KnownProtocols.\nvar (\n\tKnownProtocols_name = map[int32]string{\n\t\t0: \"HTTP\",\n\t\t1: \"TLS\",\n\t}\n\tKnownProtocols_value = map[string]int32{\n\t\t\"HTTP\": 0,\n\t\t\"TLS\":  1,\n\t}\n)\n\nfunc (x KnownProtocols) Enum() *KnownProtocols {\n\tp := new(KnownProtocols)\n\t*p = x\n\treturn p\n}\n\nfunc (x KnownProtocols) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (KnownProtocols) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_proxyman_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (KnownProtocols) Type() protoreflect.EnumType {\n\treturn &file_app_proxyman_config_proto_enumTypes[0]\n}\n\nfunc (x KnownProtocols) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use KnownProtocols.Descriptor instead.\nfunc (KnownProtocols) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype AllocationStrategy_Type int32\n\nconst (\n\t// Always allocate all connection handlers.\n\tAllocationStrategy_Always AllocationStrategy_Type = 0\n\t// Randomly allocate specific range of handlers.\n\tAllocationStrategy_Random AllocationStrategy_Type = 1\n\t// External. Not supported yet.\n\tAllocationStrategy_External AllocationStrategy_Type = 2\n)\n\n// Enum value maps for AllocationStrategy_Type.\nvar (\n\tAllocationStrategy_Type_name = map[int32]string{\n\t\t0: \"Always\",\n\t\t1: \"Random\",\n\t\t2: \"External\",\n\t}\n\tAllocationStrategy_Type_value = map[string]int32{\n\t\t\"Always\":   0,\n\t\t\"Random\":   1,\n\t\t\"External\": 2,\n\t}\n)\n\nfunc (x AllocationStrategy_Type) Enum() *AllocationStrategy_Type {\n\tp := new(AllocationStrategy_Type)\n\t*p = x\n\treturn p\n}\n\nfunc (x AllocationStrategy_Type) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (AllocationStrategy_Type) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_proxyman_config_proto_enumTypes[1].Descriptor()\n}\n\nfunc (AllocationStrategy_Type) Type() protoreflect.EnumType {\n\treturn &file_app_proxyman_config_proto_enumTypes[1]\n}\n\nfunc (x AllocationStrategy_Type) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use AllocationStrategy_Type.Descriptor instead.\nfunc (AllocationStrategy_Type) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{1, 0}\n}\n\ntype SenderConfig_DomainStrategy int32\n\nconst (\n\tSenderConfig_AS_IS   SenderConfig_DomainStrategy = 0\n\tSenderConfig_USE_IP  SenderConfig_DomainStrategy = 1\n\tSenderConfig_USE_IP4 SenderConfig_DomainStrategy = 2\n\tSenderConfig_USE_IP6 SenderConfig_DomainStrategy = 3\n)\n\n// Enum value maps for SenderConfig_DomainStrategy.\nvar (\n\tSenderConfig_DomainStrategy_name = map[int32]string{\n\t\t0: \"AS_IS\",\n\t\t1: \"USE_IP\",\n\t\t2: \"USE_IP4\",\n\t\t3: \"USE_IP6\",\n\t}\n\tSenderConfig_DomainStrategy_value = map[string]int32{\n\t\t\"AS_IS\":   0,\n\t\t\"USE_IP\":  1,\n\t\t\"USE_IP4\": 2,\n\t\t\"USE_IP6\": 3,\n\t}\n)\n\nfunc (x SenderConfig_DomainStrategy) Enum() *SenderConfig_DomainStrategy {\n\tp := new(SenderConfig_DomainStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x SenderConfig_DomainStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (SenderConfig_DomainStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_proxyman_config_proto_enumTypes[2].Descriptor()\n}\n\nfunc (SenderConfig_DomainStrategy) Type() protoreflect.EnumType {\n\treturn &file_app_proxyman_config_proto_enumTypes[2]\n}\n\nfunc (x SenderConfig_DomainStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use SenderConfig_DomainStrategy.Descriptor instead.\nfunc (SenderConfig_DomainStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{6, 0}\n}\n\ntype InboundConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *InboundConfig) Reset() {\n\t*x = InboundConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *InboundConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*InboundConfig) ProtoMessage() {}\n\nfunc (x *InboundConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[0]\n\tif 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 InboundConfig.ProtoReflect.Descriptor instead.\nfunc (*InboundConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype AllocationStrategy struct {\n\tstate protoimpl.MessageState  `protogen:\"open.v1\"`\n\tType  AllocationStrategy_Type `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.proxyman.AllocationStrategy_Type\" json:\"type,omitempty\"`\n\t// Number of handlers (ports) running in parallel.\n\t// Default value is 3 if unset.\n\tConcurrency *AllocationStrategy_AllocationStrategyConcurrency `protobuf:\"bytes,2,opt,name=concurrency,proto3\" json:\"concurrency,omitempty\"`\n\t// Number of minutes before a handler is regenerated.\n\t// Default value is 5 if unset.\n\tRefresh       *AllocationStrategy_AllocationStrategyRefresh `protobuf:\"bytes,3,opt,name=refresh,proto3\" json:\"refresh,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AllocationStrategy) Reset() {\n\t*x = AllocationStrategy{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AllocationStrategy) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AllocationStrategy) ProtoMessage() {}\n\nfunc (x *AllocationStrategy) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[1]\n\tif 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 AllocationStrategy.ProtoReflect.Descriptor instead.\nfunc (*AllocationStrategy) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *AllocationStrategy) GetType() AllocationStrategy_Type {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn AllocationStrategy_Always\n}\n\nfunc (x *AllocationStrategy) GetConcurrency() *AllocationStrategy_AllocationStrategyConcurrency {\n\tif x != nil {\n\t\treturn x.Concurrency\n\t}\n\treturn nil\n}\n\nfunc (x *AllocationStrategy) GetRefresh() *AllocationStrategy_AllocationStrategyRefresh {\n\tif x != nil {\n\t\treturn x.Refresh\n\t}\n\treturn nil\n}\n\ntype SniffingConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Whether or not to enable content sniffing on an inbound connection.\n\tEnabled bool `protobuf:\"varint,1,opt,name=enabled,proto3\" json:\"enabled,omitempty\"`\n\t// Override target destination if sniff'ed protocol is in the given list.\n\t// Supported values are \"http\", \"tls\", \"fakedns\".\n\tDestinationOverride []string `protobuf:\"bytes,2,rep,name=destination_override,json=destinationOverride,proto3\" json:\"destination_override,omitempty\"`\n\t// Whether should only try to sniff metadata without waiting for client input.\n\t// Can be used to support SMTP like protocol where server send the first message.\n\tMetadataOnly  bool `protobuf:\"varint,3,opt,name=metadata_only,json=metadataOnly,proto3\" json:\"metadata_only,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SniffingConfig) Reset() {\n\t*x = SniffingConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SniffingConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SniffingConfig) ProtoMessage() {}\n\nfunc (x *SniffingConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[2]\n\tif 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 SniffingConfig.ProtoReflect.Descriptor instead.\nfunc (*SniffingConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SniffingConfig) GetEnabled() bool {\n\tif x != nil {\n\t\treturn x.Enabled\n\t}\n\treturn false\n}\n\nfunc (x *SniffingConfig) GetDestinationOverride() []string {\n\tif x != nil {\n\t\treturn x.DestinationOverride\n\t}\n\treturn nil\n}\n\nfunc (x *SniffingConfig) GetMetadataOnly() bool {\n\tif x != nil {\n\t\treturn x.MetadataOnly\n\t}\n\treturn false\n}\n\ntype ReceiverConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// PortRange specifies the ports which the Receiver should listen on.\n\tPortRange *net.PortRange `protobuf:\"bytes,1,opt,name=port_range,json=portRange,proto3\" json:\"port_range,omitempty\"`\n\t// Listen specifies the IP address that the Receiver should listen on.\n\tListen                     *net.IPOrDomain        `protobuf:\"bytes,2,opt,name=listen,proto3\" json:\"listen,omitempty\"`\n\tAllocationStrategy         *AllocationStrategy    `protobuf:\"bytes,3,opt,name=allocation_strategy,json=allocationStrategy,proto3\" json:\"allocation_strategy,omitempty\"`\n\tStreamSettings             *internet.StreamConfig `protobuf:\"bytes,4,opt,name=stream_settings,json=streamSettings,proto3\" json:\"stream_settings,omitempty\"`\n\tReceiveOriginalDestination bool                   `protobuf:\"varint,5,opt,name=receive_original_destination,json=receiveOriginalDestination,proto3\" json:\"receive_original_destination,omitempty\"`\n\t// Override domains for the given protocol.\n\t// Deprecated. Use sniffing_settings.\n\t//\n\t// Deprecated: Marked as deprecated in app/proxyman/config.proto.\n\tDomainOverride   []KnownProtocols `protobuf:\"varint,7,rep,packed,name=domain_override,json=domainOverride,proto3,enum=v2ray.core.app.proxyman.KnownProtocols\" json:\"domain_override,omitempty\"`\n\tSniffingSettings *SniffingConfig  `protobuf:\"bytes,8,opt,name=sniffing_settings,json=sniffingSettings,proto3\" json:\"sniffing_settings,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *ReceiverConfig) Reset() {\n\t*x = ReceiverConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ReceiverConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ReceiverConfig) ProtoMessage() {}\n\nfunc (x *ReceiverConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[3]\n\tif 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 ReceiverConfig.ProtoReflect.Descriptor instead.\nfunc (*ReceiverConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *ReceiverConfig) GetPortRange() *net.PortRange {\n\tif x != nil {\n\t\treturn x.PortRange\n\t}\n\treturn nil\n}\n\nfunc (x *ReceiverConfig) GetListen() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Listen\n\t}\n\treturn nil\n}\n\nfunc (x *ReceiverConfig) GetAllocationStrategy() *AllocationStrategy {\n\tif x != nil {\n\t\treturn x.AllocationStrategy\n\t}\n\treturn nil\n}\n\nfunc (x *ReceiverConfig) GetStreamSettings() *internet.StreamConfig {\n\tif x != nil {\n\t\treturn x.StreamSettings\n\t}\n\treturn nil\n}\n\nfunc (x *ReceiverConfig) GetReceiveOriginalDestination() bool {\n\tif x != nil {\n\t\treturn x.ReceiveOriginalDestination\n\t}\n\treturn false\n}\n\n// Deprecated: Marked as deprecated in app/proxyman/config.proto.\nfunc (x *ReceiverConfig) GetDomainOverride() []KnownProtocols {\n\tif x != nil {\n\t\treturn x.DomainOverride\n\t}\n\treturn nil\n}\n\nfunc (x *ReceiverConfig) GetSniffingSettings() *SniffingConfig {\n\tif x != nil {\n\t\treturn x.SniffingSettings\n\t}\n\treturn nil\n}\n\ntype InboundHandlerConfig struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag              string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tReceiverSettings *anypb.Any             `protobuf:\"bytes,2,opt,name=receiver_settings,json=receiverSettings,proto3\" json:\"receiver_settings,omitempty\"`\n\tProxySettings    *anypb.Any             `protobuf:\"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3\" json:\"proxy_settings,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *InboundHandlerConfig) Reset() {\n\t*x = InboundHandlerConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *InboundHandlerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*InboundHandlerConfig) ProtoMessage() {}\n\nfunc (x *InboundHandlerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[4]\n\tif 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 InboundHandlerConfig.ProtoReflect.Descriptor instead.\nfunc (*InboundHandlerConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *InboundHandlerConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *InboundHandlerConfig) GetReceiverSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.ReceiverSettings\n\t}\n\treturn nil\n}\n\nfunc (x *InboundHandlerConfig) GetProxySettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.ProxySettings\n\t}\n\treturn nil\n}\n\ntype OutboundConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *OutboundConfig) Reset() {\n\t*x = OutboundConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *OutboundConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OutboundConfig) ProtoMessage() {}\n\nfunc (x *OutboundConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[5]\n\tif 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 OutboundConfig.ProtoReflect.Descriptor instead.\nfunc (*OutboundConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{5}\n}\n\ntype SenderConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Send traffic through the given IP. Only IP is allowed.\n\tVia               *net.IPOrDomain             `protobuf:\"bytes,1,opt,name=via,proto3\" json:\"via,omitempty\"`\n\tStreamSettings    *internet.StreamConfig      `protobuf:\"bytes,2,opt,name=stream_settings,json=streamSettings,proto3\" json:\"stream_settings,omitempty\"`\n\tProxySettings     *internet.ProxyConfig       `protobuf:\"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3\" json:\"proxy_settings,omitempty\"`\n\tMultiplexSettings *MultiplexingConfig         `protobuf:\"bytes,4,opt,name=multiplex_settings,json=multiplexSettings,proto3\" json:\"multiplex_settings,omitempty\"`\n\tDomainStrategy    SenderConfig_DomainStrategy `protobuf:\"varint,5,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.app.proxyman.SenderConfig_DomainStrategy\" json:\"domain_strategy,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *SenderConfig) Reset() {\n\t*x = SenderConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SenderConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SenderConfig) ProtoMessage() {}\n\nfunc (x *SenderConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[6]\n\tif 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 SenderConfig.ProtoReflect.Descriptor instead.\nfunc (*SenderConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *SenderConfig) GetVia() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Via\n\t}\n\treturn nil\n}\n\nfunc (x *SenderConfig) GetStreamSettings() *internet.StreamConfig {\n\tif x != nil {\n\t\treturn x.StreamSettings\n\t}\n\treturn nil\n}\n\nfunc (x *SenderConfig) GetProxySettings() *internet.ProxyConfig {\n\tif x != nil {\n\t\treturn x.ProxySettings\n\t}\n\treturn nil\n}\n\nfunc (x *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {\n\tif x != nil {\n\t\treturn x.MultiplexSettings\n\t}\n\treturn nil\n}\n\nfunc (x *SenderConfig) GetDomainStrategy() SenderConfig_DomainStrategy {\n\tif x != nil {\n\t\treturn x.DomainStrategy\n\t}\n\treturn SenderConfig_AS_IS\n}\n\ntype MultiplexingConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Whether or not Mux is enabled.\n\tEnabled bool `protobuf:\"varint,1,opt,name=enabled,proto3\" json:\"enabled,omitempty\"`\n\t// Max number of concurrent connections that one Mux connection can handle.\n\tConcurrency   uint32 `protobuf:\"varint,2,opt,name=concurrency,proto3\" json:\"concurrency,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *MultiplexingConfig) Reset() {\n\t*x = MultiplexingConfig{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *MultiplexingConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*MultiplexingConfig) ProtoMessage() {}\n\nfunc (x *MultiplexingConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[7]\n\tif 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 MultiplexingConfig.ProtoReflect.Descriptor instead.\nfunc (*MultiplexingConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *MultiplexingConfig) GetEnabled() bool {\n\tif x != nil {\n\t\treturn x.Enabled\n\t}\n\treturn false\n}\n\nfunc (x *MultiplexingConfig) GetConcurrency() uint32 {\n\tif x != nil {\n\t\treturn x.Concurrency\n\t}\n\treturn 0\n}\n\ntype AllocationStrategy_AllocationStrategyConcurrency struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AllocationStrategy_AllocationStrategyConcurrency) Reset() {\n\t*x = AllocationStrategy_AllocationStrategyConcurrency{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AllocationStrategy_AllocationStrategyConcurrency) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AllocationStrategy_AllocationStrategyConcurrency) ProtoMessage() {}\n\nfunc (x *AllocationStrategy_AllocationStrategyConcurrency) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[8]\n\tif 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 AllocationStrategy_AllocationStrategyConcurrency.ProtoReflect.Descriptor instead.\nfunc (*AllocationStrategy_AllocationStrategyConcurrency) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{1, 0}\n}\n\nfunc (x *AllocationStrategy_AllocationStrategyConcurrency) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\ntype AllocationStrategy_AllocationStrategyRefresh struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AllocationStrategy_AllocationStrategyRefresh) Reset() {\n\t*x = AllocationStrategy_AllocationStrategyRefresh{}\n\tmi := &file_app_proxyman_config_proto_msgTypes[9]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AllocationStrategy_AllocationStrategyRefresh) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AllocationStrategy_AllocationStrategyRefresh) ProtoMessage() {}\n\nfunc (x *AllocationStrategy_AllocationStrategyRefresh) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_proxyman_config_proto_msgTypes[9]\n\tif 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 AllocationStrategy_AllocationStrategyRefresh.ProtoReflect.Descriptor instead.\nfunc (*AllocationStrategy_AllocationStrategyRefresh) Descriptor() ([]byte, []int) {\n\treturn file_app_proxyman_config_proto_rawDescGZIP(), []int{1, 1}\n}\n\nfunc (x *AllocationStrategy_AllocationStrategyRefresh) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\nvar File_app_proxyman_config_proto protoreflect.FileDescriptor\n\nconst file_app_proxyman_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x19app/proxyman/config.proto\\x12\\x17v2ray.core.app.proxyman\\x1a\\x18common/net/address.proto\\x1a\\x15common/net/port.proto\\x1a\\x1ftransport/internet/config.proto\\x1a\\x19google/protobuf/any.proto\\\"\\x0f\\n\" +\n\t\"\\rInboundConfig\\\"\\xc0\\x03\\n\" +\n\t\"\\x12AllocationStrategy\\x12D\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e20.v2ray.core.app.proxyman.AllocationStrategy.TypeR\\x04type\\x12k\\n\" +\n\t\"\\vconcurrency\\x18\\x02 \\x01(\\v2I.v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyConcurrencyR\\vconcurrency\\x12_\\n\" +\n\t\"\\arefresh\\x18\\x03 \\x01(\\v2E.v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyRefreshR\\arefresh\\x1a5\\n\" +\n\t\"\\x1dAllocationStrategyConcurrency\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\x1a1\\n\" +\n\t\"\\x19AllocationStrategyRefresh\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\\",\\n\" +\n\t\"\\x04Type\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06Always\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06Random\\x10\\x01\\x12\\f\\n\" +\n\t\"\\bExternal\\x10\\x02\\\"\\x82\\x01\\n\" +\n\t\"\\x0eSniffingConfig\\x12\\x18\\n\" +\n\t\"\\aenabled\\x18\\x01 \\x01(\\bR\\aenabled\\x121\\n\" +\n\t\"\\x14destination_override\\x18\\x02 \\x03(\\tR\\x13destinationOverride\\x12#\\n\" +\n\t\"\\rmetadata_only\\x18\\x03 \\x01(\\bR\\fmetadataOnly\\\"\\xb4\\x04\\n\" +\n\t\"\\x0eReceiverConfig\\x12?\\n\" +\n\t\"\\n\" +\n\t\"port_range\\x18\\x01 \\x01(\\v2 .v2ray.core.common.net.PortRangeR\\tportRange\\x129\\n\" +\n\t\"\\x06listen\\x18\\x02 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\x06listen\\x12\\\\\\n\" +\n\t\"\\x13allocation_strategy\\x18\\x03 \\x01(\\v2+.v2ray.core.app.proxyman.AllocationStrategyR\\x12allocationStrategy\\x12T\\n\" +\n\t\"\\x0fstream_settings\\x18\\x04 \\x01(\\v2+.v2ray.core.transport.internet.StreamConfigR\\x0estreamSettings\\x12@\\n\" +\n\t\"\\x1creceive_original_destination\\x18\\x05 \\x01(\\bR\\x1areceiveOriginalDestination\\x12T\\n\" +\n\t\"\\x0fdomain_override\\x18\\a \\x03(\\x0e2'.v2ray.core.app.proxyman.KnownProtocolsB\\x02\\x18\\x01R\\x0edomainOverride\\x12T\\n\" +\n\t\"\\x11sniffing_settings\\x18\\b \\x01(\\v2'.v2ray.core.app.proxyman.SniffingConfigR\\x10sniffingSettingsJ\\x04\\b\\x06\\x10\\a\\\"\\xa8\\x01\\n\" +\n\t\"\\x14InboundHandlerConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12A\\n\" +\n\t\"\\x11receiver_settings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x10receiverSettings\\x12;\\n\" +\n\t\"\\x0eproxy_settings\\x18\\x03 \\x01(\\v2\\x14.google.protobuf.AnyR\\rproxySettings\\\"\\x10\\n\" +\n\t\"\\x0eOutboundConfig\\\"\\xea\\x03\\n\" +\n\t\"\\fSenderConfig\\x123\\n\" +\n\t\"\\x03via\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\x03via\\x12T\\n\" +\n\t\"\\x0fstream_settings\\x18\\x02 \\x01(\\v2+.v2ray.core.transport.internet.StreamConfigR\\x0estreamSettings\\x12Q\\n\" +\n\t\"\\x0eproxy_settings\\x18\\x03 \\x01(\\v2*.v2ray.core.transport.internet.ProxyConfigR\\rproxySettings\\x12Z\\n\" +\n\t\"\\x12multiplex_settings\\x18\\x04 \\x01(\\v2+.v2ray.core.app.proxyman.MultiplexingConfigR\\x11multiplexSettings\\x12]\\n\" +\n\t\"\\x0fdomain_strategy\\x18\\x05 \\x01(\\x0e24.v2ray.core.app.proxyman.SenderConfig.DomainStrategyR\\x0edomainStrategy\\\"A\\n\" +\n\t\"\\x0eDomainStrategy\\x12\\t\\n\" +\n\t\"\\x05AS_IS\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06USE_IP\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aUSE_IP4\\x10\\x02\\x12\\v\\n\" +\n\t\"\\aUSE_IP6\\x10\\x03\\\"P\\n\" +\n\t\"\\x12MultiplexingConfig\\x12\\x18\\n\" +\n\t\"\\aenabled\\x18\\x01 \\x01(\\bR\\aenabled\\x12 \\n\" +\n\t\"\\vconcurrency\\x18\\x02 \\x01(\\rR\\vconcurrency*#\\n\" +\n\t\"\\x0eKnownProtocols\\x12\\b\\n\" +\n\t\"\\x04HTTP\\x10\\x00\\x12\\a\\n\" +\n\t\"\\x03TLS\\x10\\x01Bf\\n\" +\n\t\"\\x1bcom.v2ray.core.app.proxymanP\\x01Z+github.com/v2fly/v2ray-core/v5/app/proxyman\\xaa\\x02\\x17V2Ray.Core.App.Proxymanb\\x06proto3\"\n\nvar (\n\tfile_app_proxyman_config_proto_rawDescOnce sync.Once\n\tfile_app_proxyman_config_proto_rawDescData []byte\n)\n\nfunc file_app_proxyman_config_proto_rawDescGZIP() []byte {\n\tfile_app_proxyman_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_proxyman_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_proxyman_config_proto_rawDesc), len(file_app_proxyman_config_proto_rawDesc)))\n\t})\n\treturn file_app_proxyman_config_proto_rawDescData\n}\n\nvar file_app_proxyman_config_proto_enumTypes = make([]protoimpl.EnumInfo, 3)\nvar file_app_proxyman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10)\nvar file_app_proxyman_config_proto_goTypes = []any{\n\t(KnownProtocols)(0),                                      // 0: v2ray.core.app.proxyman.KnownProtocols\n\t(AllocationStrategy_Type)(0),                             // 1: v2ray.core.app.proxyman.AllocationStrategy.Type\n\t(SenderConfig_DomainStrategy)(0),                         // 2: v2ray.core.app.proxyman.SenderConfig.DomainStrategy\n\t(*InboundConfig)(nil),                                    // 3: v2ray.core.app.proxyman.InboundConfig\n\t(*AllocationStrategy)(nil),                               // 4: v2ray.core.app.proxyman.AllocationStrategy\n\t(*SniffingConfig)(nil),                                   // 5: v2ray.core.app.proxyman.SniffingConfig\n\t(*ReceiverConfig)(nil),                                   // 6: v2ray.core.app.proxyman.ReceiverConfig\n\t(*InboundHandlerConfig)(nil),                             // 7: v2ray.core.app.proxyman.InboundHandlerConfig\n\t(*OutboundConfig)(nil),                                   // 8: v2ray.core.app.proxyman.OutboundConfig\n\t(*SenderConfig)(nil),                                     // 9: v2ray.core.app.proxyman.SenderConfig\n\t(*MultiplexingConfig)(nil),                               // 10: v2ray.core.app.proxyman.MultiplexingConfig\n\t(*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 11: v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency\n\t(*AllocationStrategy_AllocationStrategyRefresh)(nil),     // 12: v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyRefresh\n\t(*net.PortRange)(nil),                                    // 13: v2ray.core.common.net.PortRange\n\t(*net.IPOrDomain)(nil),                                   // 14: v2ray.core.common.net.IPOrDomain\n\t(*internet.StreamConfig)(nil),                            // 15: v2ray.core.transport.internet.StreamConfig\n\t(*anypb.Any)(nil),                                        // 16: google.protobuf.Any\n\t(*internet.ProxyConfig)(nil),                             // 17: v2ray.core.transport.internet.ProxyConfig\n}\nvar file_app_proxyman_config_proto_depIdxs = []int32{\n\t1,  // 0: v2ray.core.app.proxyman.AllocationStrategy.type:type_name -> v2ray.core.app.proxyman.AllocationStrategy.Type\n\t11, // 1: v2ray.core.app.proxyman.AllocationStrategy.concurrency:type_name -> v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency\n\t12, // 2: v2ray.core.app.proxyman.AllocationStrategy.refresh:type_name -> v2ray.core.app.proxyman.AllocationStrategy.AllocationStrategyRefresh\n\t13, // 3: v2ray.core.app.proxyman.ReceiverConfig.port_range:type_name -> v2ray.core.common.net.PortRange\n\t14, // 4: v2ray.core.app.proxyman.ReceiverConfig.listen:type_name -> v2ray.core.common.net.IPOrDomain\n\t4,  // 5: v2ray.core.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> v2ray.core.app.proxyman.AllocationStrategy\n\t15, // 6: v2ray.core.app.proxyman.ReceiverConfig.stream_settings:type_name -> v2ray.core.transport.internet.StreamConfig\n\t0,  // 7: v2ray.core.app.proxyman.ReceiverConfig.domain_override:type_name -> v2ray.core.app.proxyman.KnownProtocols\n\t5,  // 8: v2ray.core.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> v2ray.core.app.proxyman.SniffingConfig\n\t16, // 9: v2ray.core.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> google.protobuf.Any\n\t16, // 10: v2ray.core.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> google.protobuf.Any\n\t14, // 11: v2ray.core.app.proxyman.SenderConfig.via:type_name -> v2ray.core.common.net.IPOrDomain\n\t15, // 12: v2ray.core.app.proxyman.SenderConfig.stream_settings:type_name -> v2ray.core.transport.internet.StreamConfig\n\t17, // 13: v2ray.core.app.proxyman.SenderConfig.proxy_settings:type_name -> v2ray.core.transport.internet.ProxyConfig\n\t10, // 14: v2ray.core.app.proxyman.SenderConfig.multiplex_settings:type_name -> v2ray.core.app.proxyman.MultiplexingConfig\n\t2,  // 15: v2ray.core.app.proxyman.SenderConfig.domain_strategy:type_name -> v2ray.core.app.proxyman.SenderConfig.DomainStrategy\n\t16, // [16:16] is the sub-list for method output_type\n\t16, // [16:16] is the sub-list for method input_type\n\t16, // [16:16] is the sub-list for extension type_name\n\t16, // [16:16] is the sub-list for extension extendee\n\t0,  // [0:16] is the sub-list for field type_name\n}\n\nfunc init() { file_app_proxyman_config_proto_init() }\nfunc file_app_proxyman_config_proto_init() {\n\tif File_app_proxyman_config_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: unsafe.Slice(unsafe.StringData(file_app_proxyman_config_proto_rawDesc), len(file_app_proxyman_config_proto_rawDesc)),\n\t\t\tNumEnums:      3,\n\t\t\tNumMessages:   10,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_proxyman_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_proxyman_config_proto_depIdxs,\n\t\tEnumInfos:         file_app_proxyman_config_proto_enumTypes,\n\t\tMessageInfos:      file_app_proxyman_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_proxyman_config_proto = out.File\n\tfile_app_proxyman_config_proto_goTypes = nil\n\tfile_app_proxyman_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/proxyman/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.proxyman;\noption csharp_namespace = \"V2Ray.Core.App.Proxyman\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/proxyman\";\noption java_package = \"com.v2ray.core.app.proxyman\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/net/port.proto\";\nimport \"transport/internet/config.proto\";\nimport \"google/protobuf/any.proto\";\n\nmessage InboundConfig {}\n\nmessage AllocationStrategy {\n  enum Type {\n    // Always allocate all connection handlers.\n    Always = 0;\n\n    // Randomly allocate specific range of handlers.\n    Random = 1;\n\n    // External. Not supported yet.\n    External = 2;\n  }\n\n  Type type = 1;\n\n  message AllocationStrategyConcurrency {\n    uint32 value = 1;\n  }\n\n  // Number of handlers (ports) running in parallel.\n  // Default value is 3 if unset.\n  AllocationStrategyConcurrency concurrency = 2;\n\n  message AllocationStrategyRefresh {\n    uint32 value = 1;\n  }\n\n  // Number of minutes before a handler is regenerated.\n  // Default value is 5 if unset.\n  AllocationStrategyRefresh refresh = 3;\n}\n\nenum KnownProtocols {\n  HTTP = 0;\n  TLS = 1;\n}\n\nmessage SniffingConfig {\n  // Whether or not to enable content sniffing on an inbound connection.\n  bool enabled = 1;\n\n  // Override target destination if sniff'ed protocol is in the given list.\n  // Supported values are \"http\", \"tls\", \"fakedns\".\n  repeated string destination_override = 2;\n\n  // Whether should only try to sniff metadata without waiting for client input.\n  // Can be used to support SMTP like protocol where server send the first message.\n  bool metadata_only = 3;\n}\n\nmessage ReceiverConfig {\n  // PortRange specifies the ports which the Receiver should listen on.\n  v2ray.core.common.net.PortRange port_range = 1;\n  // Listen specifies the IP address that the Receiver should listen on.\n  v2ray.core.common.net.IPOrDomain listen = 2;\n  AllocationStrategy allocation_strategy = 3;\n  v2ray.core.transport.internet.StreamConfig stream_settings = 4;\n  bool receive_original_destination = 5;\n  reserved 6;\n  // Override domains for the given protocol.\n  // Deprecated. Use sniffing_settings.\n  repeated KnownProtocols domain_override = 7 [deprecated = true];\n  SniffingConfig sniffing_settings = 8;\n}\n\nmessage InboundHandlerConfig {\n  string tag = 1;\n  google.protobuf.Any receiver_settings = 2;\n  google.protobuf.Any proxy_settings = 3;\n}\n\nmessage OutboundConfig {}\n\nmessage SenderConfig {\n  enum DomainStrategy {\n    AS_IS = 0;\n    USE_IP = 1;\n    USE_IP4 = 2;\n    USE_IP6 = 3;\n  }\n\n  // Send traffic through the given IP. Only IP is allowed.\n  v2ray.core.common.net.IPOrDomain via = 1;\n  v2ray.core.transport.internet.StreamConfig stream_settings = 2;\n  v2ray.core.transport.internet.ProxyConfig proxy_settings = 3;\n  MultiplexingConfig multiplex_settings = 4;\n  DomainStrategy domain_strategy = 5;\n}\n\nmessage MultiplexingConfig {\n  // Whether or not Mux is enabled.\n  bool enabled = 1;\n  // Max number of concurrent connections that one Mux connection can handle.\n  uint32 concurrency = 2;\n}\n"
  },
  {
    "path": "app/proxyman/inbound/always.go",
    "content": "package inbound\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter) {\n\tvar uplinkCounter stats.Counter\n\tvar downlinkCounter stats.Counter\n\n\tpolicy := v.GetFeature(policy.ManagerType()).(policy.Manager)\n\tif len(tag) > 0 && policy.ForSystem().Stats.InboundUplink {\n\t\tstatsManager := v.GetFeature(stats.ManagerType()).(stats.Manager)\n\t\tname := \"inbound>>>\" + tag + \">>>traffic>>>uplink\"\n\t\tc, _ := stats.GetOrRegisterCounter(statsManager, name)\n\t\tif c != nil {\n\t\t\tuplinkCounter = c\n\t\t}\n\t}\n\tif len(tag) > 0 && policy.ForSystem().Stats.InboundDownlink {\n\t\tstatsManager := v.GetFeature(stats.ManagerType()).(stats.Manager)\n\t\tname := \"inbound>>>\" + tag + \">>>traffic>>>downlink\"\n\t\tc, _ := stats.GetOrRegisterCounter(statsManager, name)\n\t\tif c != nil {\n\t\t\tdownlinkCounter = c\n\t\t}\n\t}\n\n\treturn uplinkCounter, downlinkCounter\n}\n\ntype AlwaysOnInboundHandler struct {\n\tproxy   proxy.Inbound\n\tworkers []worker\n\tmux     *mux.Server\n\ttag     string\n}\n\nfunc NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*AlwaysOnInboundHandler, error) {\n\trawProxy, err := common.CreateObject(ctx, proxyConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tp, ok := rawProxy.(proxy.Inbound)\n\tif !ok {\n\t\treturn nil, newError(\"not an inbound proxy.\")\n\t}\n\n\th := &AlwaysOnInboundHandler{\n\t\tproxy: p,\n\t\tmux:   mux.NewServer(ctx),\n\t\ttag:   tag,\n\t}\n\n\tuplinkCounter, downlinkCounter := getStatCounter(core.MustFromContext(ctx), tag)\n\n\tnl := p.Network()\n\tpr := receiverConfig.PortRange\n\taddress := receiverConfig.Listen.AsAddress()\n\tif address == nil {\n\t\taddress = net.AnyIP\n\t}\n\n\tmss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse stream config\").Base(err).AtWarning()\n\t}\n\n\tif receiverConfig.ReceiveOriginalDestination {\n\t\tif mss.SocketSettings == nil {\n\t\t\tmss.SocketSettings = &internet.SocketConfig{}\n\t\t}\n\t\tif mss.SocketSettings.Tproxy == internet.SocketConfig_Off {\n\t\t\tmss.SocketSettings.Tproxy = internet.SocketConfig_Redirect\n\t\t}\n\t\tmss.SocketSettings.ReceiveOriginalDestAddress = true\n\t}\n\tif pr == nil {\n\t\tif net.HasNetwork(nl, net.Network_UNIX) {\n\t\t\tnewError(\"creating unix domain socket worker on \", address).AtDebug().WriteToLog()\n\n\t\t\tworker := &dsWorker{\n\t\t\t\taddress:         address,\n\t\t\t\tproxy:           p,\n\t\t\t\tstream:          mss,\n\t\t\t\ttag:             tag,\n\t\t\t\tdispatcher:      h.mux,\n\t\t\t\tsniffingConfig:  receiverConfig.GetEffectiveSniffingSettings(),\n\t\t\t\tuplinkCounter:   uplinkCounter,\n\t\t\t\tdownlinkCounter: downlinkCounter,\n\t\t\t\tctx:             ctx,\n\t\t\t}\n\t\t\th.workers = append(h.workers, worker)\n\t\t}\n\t}\n\tif pr != nil {\n\t\tfor port := pr.From; port <= pr.To; port++ {\n\t\t\tif net.HasNetwork(nl, net.Network_TCP) {\n\t\t\t\tnewError(\"creating stream worker on \", address, \":\", port).AtDebug().WriteToLog()\n\n\t\t\t\tworker := &tcpWorker{\n\t\t\t\t\taddress:         address,\n\t\t\t\t\tport:            net.Port(port),\n\t\t\t\t\tproxy:           p,\n\t\t\t\t\tstream:          mss,\n\t\t\t\t\trecvOrigDest:    receiverConfig.ReceiveOriginalDestination,\n\t\t\t\t\ttag:             tag,\n\t\t\t\t\tdispatcher:      h.mux,\n\t\t\t\t\tsniffingConfig:  receiverConfig.GetEffectiveSniffingSettings(),\n\t\t\t\t\tuplinkCounter:   uplinkCounter,\n\t\t\t\t\tdownlinkCounter: downlinkCounter,\n\t\t\t\t\tctx:             ctx,\n\t\t\t\t}\n\t\t\t\th.workers = append(h.workers, worker)\n\t\t\t}\n\n\t\t\tif net.HasNetwork(nl, net.Network_UDP) {\n\t\t\t\tworker := &udpWorker{\n\t\t\t\t\tctx:             ctx,\n\t\t\t\t\ttag:             tag,\n\t\t\t\t\tproxy:           p,\n\t\t\t\t\taddress:         address,\n\t\t\t\t\tport:            net.Port(port),\n\t\t\t\t\tdispatcher:      h.mux,\n\t\t\t\t\tsniffingConfig:  receiverConfig.GetEffectiveSniffingSettings(),\n\t\t\t\t\tuplinkCounter:   uplinkCounter,\n\t\t\t\t\tdownlinkCounter: downlinkCounter,\n\t\t\t\t\tstream:          mss,\n\t\t\t\t}\n\t\t\t\th.workers = append(h.workers, worker)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn h, nil\n}\n\n// Start implements common.Runnable.\nfunc (h *AlwaysOnInboundHandler) Start() error {\n\tfor _, worker := range h.workers {\n\t\tif err := worker.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (h *AlwaysOnInboundHandler) Close() error {\n\tvar errs []error\n\tfor _, worker := range h.workers {\n\t\terrs = append(errs, worker.Close())\n\t}\n\terrs = append(errs, h.mux.Close())\n\tif err := errors.Combine(errs...); err != nil {\n\t\treturn newError(\"failed to close all resources\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc (h *AlwaysOnInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {\n\tif len(h.workers) == 0 {\n\t\treturn nil, 0, 0\n\t}\n\tw := h.workers[dice.Roll(len(h.workers))]\n\treturn w.Proxy(), w.Port(), 9999\n}\n\nfunc (h *AlwaysOnInboundHandler) Tag() string {\n\treturn h.tag\n}\n\nfunc (h *AlwaysOnInboundHandler) GetInbound() proxy.Inbound {\n\treturn h.proxy\n}\n"
  },
  {
    "path": "app/proxyman/inbound/dynamic.go",
    "content": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype DynamicInboundHandler struct {\n\ttag            string\n\tv              *core.Instance\n\tproxyConfig    interface{}\n\treceiverConfig *proxyman.ReceiverConfig\n\tstreamSettings *internet.MemoryStreamConfig\n\tportMutex      sync.Mutex\n\tportsInUse     map[net.Port]bool\n\tworkerMutex    sync.RWMutex\n\tworker         []worker\n\tlastRefresh    time.Time\n\tmux            *mux.Server\n\ttask           *task.Periodic\n\n\tctx context.Context\n}\n\nfunc NewDynamicInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*DynamicInboundHandler, error) {\n\tv := core.MustFromContext(ctx)\n\th := &DynamicInboundHandler{\n\t\ttag:            tag,\n\t\tproxyConfig:    proxyConfig,\n\t\treceiverConfig: receiverConfig,\n\t\tportsInUse:     make(map[net.Port]bool),\n\t\tmux:            mux.NewServer(ctx),\n\t\tv:              v,\n\t\tctx:            ctx,\n\t}\n\n\tmss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse stream settings\").Base(err).AtWarning()\n\t}\n\tif receiverConfig.ReceiveOriginalDestination {\n\t\tif mss.SocketSettings == nil {\n\t\t\tmss.SocketSettings = &internet.SocketConfig{}\n\t\t}\n\t\tif mss.SocketSettings.Tproxy == internet.SocketConfig_Off {\n\t\t\tmss.SocketSettings.Tproxy = internet.SocketConfig_Redirect\n\t\t}\n\t\tmss.SocketSettings.ReceiveOriginalDestAddress = true\n\t}\n\n\th.streamSettings = mss\n\n\th.task = &task.Periodic{\n\t\tInterval: time.Minute * time.Duration(h.receiverConfig.AllocationStrategy.GetRefreshValue()),\n\t\tExecute:  h.refresh,\n\t}\n\n\treturn h, nil\n}\n\nfunc (h *DynamicInboundHandler) allocatePort() net.Port {\n\tfrom := int(h.receiverConfig.PortRange.From)\n\tdelta := int(h.receiverConfig.PortRange.To) - from + 1\n\n\th.portMutex.Lock()\n\tdefer h.portMutex.Unlock()\n\n\tfor {\n\t\tr := dice.Roll(delta)\n\t\tport := net.Port(from + r)\n\t\t_, used := h.portsInUse[port]\n\t\tif !used {\n\t\t\th.portsInUse[port] = true\n\t\t\treturn port\n\t\t}\n\t}\n}\n\nfunc (h *DynamicInboundHandler) closeWorkers(workers []worker) {\n\tports2Del := make([]net.Port, len(workers))\n\tfor idx, worker := range workers {\n\t\tports2Del[idx] = worker.Port()\n\t\tif err := worker.Close(); err != nil {\n\t\t\tnewError(\"failed to close worker\").Base(err).WriteToLog()\n\t\t}\n\t}\n\n\th.portMutex.Lock()\n\tfor _, port := range ports2Del {\n\t\tdelete(h.portsInUse, port)\n\t}\n\th.portMutex.Unlock()\n}\n\nfunc (h *DynamicInboundHandler) refresh() error {\n\th.lastRefresh = time.Now()\n\n\ttimeout := time.Minute * time.Duration(h.receiverConfig.AllocationStrategy.GetRefreshValue()) * 2\n\tconcurrency := h.receiverConfig.AllocationStrategy.GetConcurrencyValue()\n\tworkers := make([]worker, 0, concurrency)\n\n\taddress := h.receiverConfig.Listen.AsAddress()\n\tif address == nil {\n\t\taddress = net.AnyIP\n\t}\n\n\tuplinkCounter, downlinkCounter := getStatCounter(h.v, h.tag)\n\n\tfor i := uint32(0); i < concurrency; i++ {\n\t\tport := h.allocatePort()\n\t\trawProxy, err := core.CreateObject(h.v, h.proxyConfig)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to create proxy instance\").Base(err).AtWarning().WriteToLog()\n\t\t\tcontinue\n\t\t}\n\t\tp := rawProxy.(proxy.Inbound)\n\t\tnl := p.Network()\n\t\tif net.HasNetwork(nl, net.Network_TCP) {\n\t\t\tworker := &tcpWorker{\n\t\t\t\ttag:             h.tag,\n\t\t\t\taddress:         address,\n\t\t\t\tport:            port,\n\t\t\t\tproxy:           p,\n\t\t\t\tstream:          h.streamSettings,\n\t\t\t\trecvOrigDest:    h.receiverConfig.ReceiveOriginalDestination,\n\t\t\t\tdispatcher:      h.mux,\n\t\t\t\tsniffingConfig:  h.receiverConfig.GetEffectiveSniffingSettings(),\n\t\t\t\tuplinkCounter:   uplinkCounter,\n\t\t\t\tdownlinkCounter: downlinkCounter,\n\t\t\t\tctx:             h.ctx,\n\t\t\t}\n\t\t\tif err := worker.Start(); err != nil {\n\t\t\t\tnewError(\"failed to create TCP worker\").Base(err).AtWarning().WriteToLog()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tworkers = append(workers, worker)\n\t\t}\n\n\t\tif net.HasNetwork(nl, net.Network_UDP) {\n\t\t\tworker := &udpWorker{\n\t\t\t\tctx:             h.ctx,\n\t\t\t\ttag:             h.tag,\n\t\t\t\tproxy:           p,\n\t\t\t\taddress:         address,\n\t\t\t\tport:            port,\n\t\t\t\tdispatcher:      h.mux,\n\t\t\t\tsniffingConfig:  h.receiverConfig.GetEffectiveSniffingSettings(),\n\t\t\t\tuplinkCounter:   uplinkCounter,\n\t\t\t\tdownlinkCounter: downlinkCounter,\n\t\t\t\tstream:          h.streamSettings,\n\t\t\t}\n\t\t\tif err := worker.Start(); err != nil {\n\t\t\t\tnewError(\"failed to create UDP worker\").Base(err).AtWarning().WriteToLog()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tworkers = append(workers, worker)\n\t\t}\n\t}\n\n\th.workerMutex.Lock()\n\th.worker = workers\n\th.workerMutex.Unlock()\n\n\ttime.AfterFunc(timeout, func() {\n\t\th.closeWorkers(workers)\n\t})\n\n\treturn nil\n}\n\nfunc (h *DynamicInboundHandler) Start() error {\n\treturn h.task.Start()\n}\n\nfunc (h *DynamicInboundHandler) Close() error {\n\treturn h.task.Close()\n}\n\nfunc (h *DynamicInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {\n\th.workerMutex.RLock()\n\tdefer h.workerMutex.RUnlock()\n\n\tif len(h.worker) == 0 {\n\t\treturn nil, 0, 0\n\t}\n\tw := h.worker[dice.Roll(len(h.worker))]\n\texpire := h.receiverConfig.AllocationStrategy.GetRefreshValue() - uint32(time.Since(h.lastRefresh)/time.Minute)\n\treturn w.Proxy(), w.Port(), int(expire)\n}\n\nfunc (h *DynamicInboundHandler) Tag() string {\n\treturn h.tag\n}\n"
  },
  {
    "path": "app/proxyman/inbound/errors.generated.go",
    "content": "package inbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/proxyman/inbound/inbound.go",
    "content": "package inbound\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/inbound\"\n)\n\n// Manager is to manage all inbound handlers.\ntype Manager struct {\n\tctx             context.Context\n\taccess          sync.RWMutex\n\tuntaggedHandler []inbound.Handler\n\ttaggedHandlers  map[string]inbound.Handler\n\trunning         bool\n}\n\n// New returns a new Manager for inbound handlers.\nfunc New(ctx context.Context, config *proxyman.InboundConfig) (*Manager, error) {\n\tm := &Manager{\n\t\tctx:            ctx,\n\t\ttaggedHandlers: make(map[string]inbound.Handler),\n\t}\n\treturn m, nil\n}\n\n// Type implements common.HasType.\nfunc (*Manager) Type() interface{} {\n\treturn inbound.ManagerType()\n}\n\n// AddHandler implements inbound.Manager.\nfunc (m *Manager) AddHandler(ctx context.Context, handler inbound.Handler) error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\ttag := handler.Tag()\n\tif len(tag) > 0 {\n\t\tm.taggedHandlers[tag] = handler\n\t} else {\n\t\tm.untaggedHandler = append(m.untaggedHandler, handler)\n\t}\n\n\tif m.running {\n\t\treturn handler.Start()\n\t}\n\n\treturn nil\n}\n\n// GetHandler implements inbound.Manager.\nfunc (m *Manager) GetHandler(ctx context.Context, tag string) (inbound.Handler, error) {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\n\thandler, found := m.taggedHandlers[tag]\n\tif !found {\n\t\treturn nil, newError(\"handler not found: \", tag)\n\t}\n\treturn handler, nil\n}\n\n// RemoveHandler implements inbound.Manager.\nfunc (m *Manager) RemoveHandler(ctx context.Context, tag string) error {\n\tif tag == \"\" {\n\t\treturn common.ErrNoClue\n\t}\n\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tif handler, found := m.taggedHandlers[tag]; found {\n\t\tif err := handler.Close(); err != nil {\n\t\t\tnewError(\"failed to close handler \", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t\tdelete(m.taggedHandlers, tag)\n\t\treturn nil\n\t}\n\n\treturn common.ErrNoClue\n}\n\n// Start implements common.Runnable.\nfunc (m *Manager) Start() error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tm.running = true\n\n\tfor _, handler := range m.taggedHandlers {\n\t\tif err := handler.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfor _, handler := range m.untaggedHandler {\n\t\tif err := handler.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (m *Manager) Close() error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tm.running = false\n\n\tvar errors []interface{}\n\tfor _, handler := range m.taggedHandlers {\n\t\tif err := handler.Close(); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, handler := range m.untaggedHandler {\n\t\tif err := handler.Close(); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\tif len(errors) > 0 {\n\t\treturn newError(\"failed to close all handlers\").Base(newError(serial.Concat(errors...)))\n\t}\n\n\treturn nil\n}\n\n// NewHandler creates a new inbound.Handler based on the given config.\nfunc NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound.Handler, error) {\n\trawReceiverSettings, err := serial.GetInstanceOf(config.ReceiverSettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tproxySettings, err := serial.GetInstanceOf(config.ProxySettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttag := config.Tag\n\n\treceiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)\n\tif !ok {\n\t\treturn nil, newError(\"not a ReceiverConfig\").AtError()\n\t}\n\n\tstreamSettings := receiverSettings.StreamSettings\n\tif streamSettings != nil && streamSettings.SocketSettings != nil {\n\t\tctx = session.ContextWithSockopt(ctx, &session.Sockopt{\n\t\t\tMark: streamSettings.SocketSettings.Mark,\n\t\t})\n\t}\n\n\tallocStrategy := receiverSettings.AllocationStrategy\n\tif allocStrategy == nil || allocStrategy.Type == proxyman.AllocationStrategy_Always {\n\t\treturn NewAlwaysOnInboundHandler(ctx, tag, receiverSettings, proxySettings)\n\t}\n\n\tif allocStrategy.Type == proxyman.AllocationStrategy_Random {\n\t\treturn NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)\n\t}\n\treturn nil, newError(\"unknown allocation strategy: \", receiverSettings.AllocationStrategy.Type).AtError()\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*proxyman.InboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*proxyman.InboundConfig))\n\t}))\n\tcommon.Must(common.RegisterConfig((*core.InboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewHandler(ctx, config.(*core.InboundHandlerConfig))\n\t}))\n}\n"
  },
  {
    "path": "app/proxyman/inbound/worker.go",
    "content": "package inbound\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\ntype worker interface {\n\tStart() error\n\tClose() error\n\tPort() net.Port\n\tProxy() proxy.Inbound\n}\n\ntype tcpWorker struct {\n\taddress         net.Address\n\tport            net.Port\n\tproxy           proxy.Inbound\n\tstream          *internet.MemoryStreamConfig\n\trecvOrigDest    bool\n\ttag             string\n\tdispatcher      routing.Dispatcher\n\tsniffingConfig  *proxyman.SniffingConfig\n\tuplinkCounter   stats.Counter\n\tdownlinkCounter stats.Counter\n\n\thub internet.Listener\n\n\tctx context.Context\n}\n\nfunc getTProxyType(s *internet.MemoryStreamConfig) internet.SocketConfig_TProxyMode {\n\tif s == nil || s.SocketSettings == nil {\n\t\treturn internet.SocketConfig_Off\n\t}\n\treturn s.SocketSettings.Tproxy\n}\n\nfunc (w *tcpWorker) callback(conn internet.Connection) {\n\tctx, cancel := context.WithCancel(w.ctx)\n\tsid := session.NewID()\n\tctx = session.ContextWithID(ctx, sid)\n\n\tif w.recvOrigDest {\n\t\tvar dest net.Destination\n\t\tswitch getTProxyType(w.stream) {\n\t\tcase internet.SocketConfig_Redirect:\n\t\t\td, err := tcp.GetOriginalDestination(conn)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get original destination\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t} else {\n\t\t\t\tdest = d\n\t\t\t}\n\t\tcase internet.SocketConfig_TProxy:\n\t\t\tdest = net.DestinationFromAddr(conn.LocalAddr())\n\t\t}\n\t\tif dest.IsValid() {\n\t\t\tctx = session.ContextWithOutbound(ctx, &session.Outbound{\n\t\t\t\tTarget: dest,\n\t\t\t})\n\t\t}\n\t}\n\tctx = session.ContextWithInbound(ctx, &session.Inbound{\n\t\tSource:  net.DestinationFromAddr(conn.RemoteAddr()),\n\t\tGateway: net.TCPDestination(w.address, w.port),\n\t\tTag:     w.tag,\n\t})\n\tcontent := new(session.Content)\n\tif w.sniffingConfig != nil {\n\t\tcontent.SniffingRequest.Enabled = w.sniffingConfig.Enabled\n\t\tcontent.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride\n\t\tcontent.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly\n\t}\n\tctx = session.ContextWithContent(ctx, content)\n\tif w.uplinkCounter != nil || w.downlinkCounter != nil {\n\t\tconn = &internet.StatCouterConnection{\n\t\t\tConnection:   conn,\n\t\t\tReadCounter:  w.uplinkCounter,\n\t\t\tWriteCounter: w.downlinkCounter,\n\t\t}\n\t}\n\tif err := w.proxy.Process(ctx, net.Network_TCP, conn, w.dispatcher); err != nil {\n\t\tnewError(\"connection ends\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\tcancel()\n\tif err := conn.Close(); err != nil {\n\t\tnewError(\"failed to close connection\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n}\n\nfunc (w *tcpWorker) Proxy() proxy.Inbound {\n\treturn w.proxy\n}\n\nfunc (w *tcpWorker) Start() error {\n\tctx := w.ctx\n\tproxyEnvironment := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment)\n\ttransportEnvironment, err := proxyEnvironment.NarrowScopeToTransport(\"transport\")\n\tif err != nil {\n\t\treturn newError(\"unable to narrow environment to transport\").Base(err)\n\t}\n\tctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)\n\thub, err := internet.ListenTCP(ctx, w.address, w.port, w.stream, func(conn internet.Connection) {\n\t\tgo w.callback(conn)\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to listen TCP on \", w.port).AtWarning().Base(err)\n\t}\n\tw.hub = hub\n\treturn nil\n}\n\nfunc (w *tcpWorker) Close() error {\n\tvar errors []interface{}\n\tif w.hub != nil {\n\t\tif err := common.Close(w.hub); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t\tif err := common.Close(w.proxy); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif len(errors) > 0 {\n\t\treturn newError(\"failed to close all resources\").Base(newError(serial.Concat(errors...)))\n\t}\n\n\treturn nil\n}\n\nfunc (w *tcpWorker) Port() net.Port {\n\treturn w.port\n}\n\ntype udpConn struct {\n\tlastActivityTime int64 // in seconds\n\treader           buf.Reader\n\twriter           buf.Writer\n\toutput           func([]byte) (int, error)\n\tremote           net.Addr\n\tlocal            net.Addr\n\tdone             *done.Instance\n\tuplink           stats.Counter\n\tdownlink         stats.Counter\n\tinactive         bool\n}\n\nfunc (c *udpConn) setInactive() {\n\tc.inactive = true\n}\n\nfunc (c *udpConn) updateActivity() {\n\tatomic.StoreInt64(&c.lastActivityTime, time.Now().Unix())\n}\n\n// ReadMultiBuffer implements buf.Reader\nfunc (c *udpConn) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tmb, err := c.reader.ReadMultiBuffer()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.updateActivity()\n\n\tif c.uplink != nil {\n\t\tc.uplink.Add(int64(mb.Len()))\n\t}\n\n\treturn mb, nil\n}\n\nfunc (c *udpConn) Read(buf []byte) (int, error) {\n\tpanic(\"not implemented\")\n}\n\n// Write implements io.Writer.\nfunc (c *udpConn) Write(buf []byte) (int, error) {\n\tn, err := c.output(buf)\n\tif c.downlink != nil {\n\t\tc.downlink.Add(int64(n))\n\t}\n\tif err == nil {\n\t\tc.updateActivity()\n\t}\n\treturn n, err\n}\n\nfunc (c *udpConn) Close() error {\n\tcommon.Must(c.done.Close())\n\tcommon.Must(common.Close(c.writer))\n\treturn nil\n}\n\nfunc (c *udpConn) RemoteAddr() net.Addr {\n\treturn c.remote\n}\n\nfunc (c *udpConn) LocalAddr() net.Addr {\n\treturn c.local\n}\n\nfunc (*udpConn) SetDeadline(time.Time) error {\n\treturn nil\n}\n\nfunc (*udpConn) SetReadDeadline(time.Time) error {\n\treturn nil\n}\n\nfunc (*udpConn) SetWriteDeadline(time.Time) error {\n\treturn nil\n}\n\ntype connID struct {\n\tsrc  net.Destination\n\tdest net.Destination\n}\n\ntype udpWorker struct {\n\tsync.RWMutex\n\n\tproxy           proxy.Inbound\n\thub             *udp.Hub\n\taddress         net.Address\n\tport            net.Port\n\ttag             string\n\tstream          *internet.MemoryStreamConfig\n\tdispatcher      routing.Dispatcher\n\tsniffingConfig  *proxyman.SniffingConfig\n\tuplinkCounter   stats.Counter\n\tdownlinkCounter stats.Counter\n\n\tchecker    *task.Periodic\n\tactiveConn map[connID]*udpConn\n\n\tctx context.Context\n}\n\nfunc (w *udpWorker) getConnection(id connID) (*udpConn, bool) {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif conn, found := w.activeConn[id]; found && !conn.done.Done() {\n\t\treturn conn, true\n\t}\n\n\tpReader, pWriter := pipe.New(pipe.DiscardOverflow(), pipe.WithSizeLimit(16*1024))\n\tconn := &udpConn{\n\t\treader: pReader,\n\t\twriter: pWriter,\n\t\toutput: func(b []byte) (int, error) {\n\t\t\treturn w.hub.WriteTo(b, id.src)\n\t\t},\n\t\tremote: &net.UDPAddr{\n\t\t\tIP:   id.src.Address.IP(),\n\t\t\tPort: int(id.src.Port),\n\t\t},\n\t\tlocal: &net.UDPAddr{\n\t\t\tIP:   w.address.IP(),\n\t\t\tPort: int(w.port),\n\t\t},\n\t\tdone:     done.New(),\n\t\tuplink:   w.uplinkCounter,\n\t\tdownlink: w.downlinkCounter,\n\t}\n\tw.activeConn[id] = conn\n\n\tconn.updateActivity()\n\treturn conn, false\n}\n\nfunc (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest net.Destination) {\n\tid := connID{\n\t\tsrc: source,\n\t}\n\tif originalDest.IsValid() {\n\t\tid.dest = originalDest\n\t}\n\tconn, existing := w.getConnection(id)\n\n\t// payload will be discarded in pipe is full.\n\tconn.writer.WriteMultiBuffer(buf.MultiBuffer{b})\n\n\tif !existing {\n\t\tcommon.Must(w.checker.Start())\n\n\t\tgo func() {\n\t\t\tctx := w.ctx\n\t\t\tsid := session.NewID()\n\t\t\tctx = session.ContextWithID(ctx, sid)\n\n\t\t\tif originalDest.IsValid() {\n\t\t\t\tctx = session.ContextWithOutbound(ctx, &session.Outbound{\n\t\t\t\t\tTarget: originalDest,\n\t\t\t\t})\n\t\t\t}\n\t\t\tctx = session.ContextWithInbound(ctx, &session.Inbound{\n\t\t\t\tSource:  source,\n\t\t\t\tGateway: net.UDPDestination(w.address, w.port),\n\t\t\t\tTag:     w.tag,\n\t\t\t})\n\t\t\tcontent := new(session.Content)\n\t\t\tif w.sniffingConfig != nil {\n\t\t\t\tcontent.SniffingRequest.Enabled = w.sniffingConfig.Enabled\n\t\t\t\tcontent.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride\n\t\t\t\tcontent.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly\n\t\t\t}\n\t\t\tctx = session.ContextWithContent(ctx, content)\n\t\t\tif err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil {\n\t\t\t\tnewError(\"connection ends\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t}\n\t\t\tconn.Close()\n\t\t\t// conn not removed by checker TODO may be lock worker here is better\n\t\t\tif !conn.inactive {\n\t\t\t\tconn.setInactive()\n\t\t\t\tw.removeConn(id)\n\t\t\t}\n\t\t}()\n\t}\n}\n\nfunc (w *udpWorker) removeConn(id connID) {\n\tw.Lock()\n\tdelete(w.activeConn, id)\n\tw.Unlock()\n}\n\nfunc (w *udpWorker) handlePackets() {\n\treceive := w.hub.Receive()\n\tfor payload := range receive {\n\t\tw.callback(payload.Payload, payload.Source, payload.Target)\n\t}\n}\n\nfunc (w *udpWorker) clean() error {\n\tnowSec := time.Now().Unix()\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif len(w.activeConn) == 0 {\n\t\treturn newError(\"no more connections. stopping...\")\n\t}\n\n\tfor addr, conn := range w.activeConn {\n\t\tif nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 8 { // TODO Timeout too small\n\t\t\tif !conn.inactive {\n\t\t\t\tconn.setInactive()\n\t\t\t\tdelete(w.activeConn, addr)\n\t\t\t}\n\t\t\tconn.Close()\n\t\t}\n\t}\n\n\tif len(w.activeConn) == 0 {\n\t\tw.activeConn = make(map[connID]*udpConn, 16)\n\t}\n\n\treturn nil\n}\n\nfunc (w *udpWorker) Start() error {\n\tw.activeConn = make(map[connID]*udpConn, 16)\n\tctx := context.Background()\n\tproxyEnvironment := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment)\n\ttransportEnvironment, err := proxyEnvironment.NarrowScopeToTransport(\"transport\")\n\tif err != nil {\n\t\treturn newError(\"unable to narrow environment to transport\").Base(err)\n\t}\n\tctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)\n\th, err := udp.ListenUDP(ctx, w.address, w.port, w.stream, udp.HubCapacity(256))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tw.checker = &task.Periodic{\n\t\tInterval: time.Second * 16,\n\t\tExecute:  w.clean,\n\t}\n\n\tw.hub = h\n\tgo w.handlePackets()\n\treturn nil\n}\n\nfunc (w *udpWorker) Close() error {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tvar errors []interface{}\n\n\tif w.hub != nil {\n\t\tif err := w.hub.Close(); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\tif w.checker != nil {\n\t\tif err := w.checker.Close(); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\tif err := common.Close(w.proxy); err != nil {\n\t\terrors = append(errors, err)\n\t}\n\n\tif len(errors) > 0 {\n\t\treturn newError(\"failed to close all resources\").Base(newError(serial.Concat(errors...)))\n\t}\n\treturn nil\n}\n\nfunc (w *udpWorker) Port() net.Port {\n\treturn w.port\n}\n\nfunc (w *udpWorker) Proxy() proxy.Inbound {\n\treturn w.proxy\n}\n\ntype dsWorker struct {\n\taddress         net.Address\n\tproxy           proxy.Inbound\n\tstream          *internet.MemoryStreamConfig\n\ttag             string\n\tdispatcher      routing.Dispatcher\n\tsniffingConfig  *proxyman.SniffingConfig\n\tuplinkCounter   stats.Counter\n\tdownlinkCounter stats.Counter\n\n\thub internet.Listener\n\n\tctx context.Context\n}\n\nfunc (w *dsWorker) callback(conn internet.Connection) {\n\tctx, cancel := context.WithCancel(w.ctx)\n\tsid := session.NewID()\n\tctx = session.ContextWithID(ctx, sid)\n\n\tctx = session.ContextWithInbound(ctx, &session.Inbound{\n\t\tSource:  net.DestinationFromAddr(conn.RemoteAddr()),\n\t\tGateway: net.UnixDestination(w.address),\n\t\tTag:     w.tag,\n\t})\n\tcontent := new(session.Content)\n\tif w.sniffingConfig != nil {\n\t\tcontent.SniffingRequest.Enabled = w.sniffingConfig.Enabled\n\t\tcontent.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride\n\t\tcontent.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly\n\t}\n\tctx = session.ContextWithContent(ctx, content)\n\tif w.uplinkCounter != nil || w.downlinkCounter != nil {\n\t\tconn = &internet.StatCouterConnection{\n\t\t\tConnection:   conn,\n\t\t\tReadCounter:  w.uplinkCounter,\n\t\t\tWriteCounter: w.downlinkCounter,\n\t\t}\n\t}\n\tif err := w.proxy.Process(ctx, net.Network_UNIX, conn, w.dispatcher); err != nil {\n\t\tnewError(\"connection ends\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\tcancel()\n\tif err := conn.Close(); err != nil {\n\t\tnewError(\"failed to close connection\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n}\n\nfunc (w *dsWorker) Proxy() proxy.Inbound {\n\treturn w.proxy\n}\n\nfunc (w *dsWorker) Port() net.Port {\n\treturn net.Port(0)\n}\n\nfunc (w *dsWorker) Start() error {\n\tctx := context.Background()\n\tproxyEnvironment := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment)\n\ttransportEnvironment, err := proxyEnvironment.NarrowScopeToTransport(\"transport\")\n\tif err != nil {\n\t\treturn newError(\"unable to narrow environment to transport\").Base(err)\n\t}\n\tctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)\n\thub, err := internet.ListenUnix(ctx, w.address, w.stream, func(conn internet.Connection) {\n\t\tgo w.callback(conn)\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to listen Unix Domain Socket on \", w.address).AtWarning().Base(err)\n\t}\n\tw.hub = hub\n\treturn nil\n}\n\nfunc (w *dsWorker) Close() error {\n\tvar errors []interface{}\n\tif w.hub != nil {\n\t\tif err := common.Close(w.hub); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t\tif err := common.Close(w.proxy); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif len(errors) > 0 {\n\t\treturn newError(\"failed to close all resources\").Base(newError(serial.Concat(errors...)))\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "app/proxyman/outbound/errors.generated.go",
    "content": "package outbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/proxyman/outbound/handler.go",
    "content": "package outbound\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter) {\n\tvar uplinkCounter stats.Counter\n\tvar downlinkCounter stats.Counter\n\n\tpolicy := v.GetFeature(policy.ManagerType()).(policy.Manager)\n\tif len(tag) > 0 && policy.ForSystem().Stats.OutboundUplink {\n\t\tstatsManager := v.GetFeature(stats.ManagerType()).(stats.Manager)\n\t\tname := \"outbound>>>\" + tag + \">>>traffic>>>uplink\"\n\t\tc, _ := stats.GetOrRegisterCounter(statsManager, name)\n\t\tif c != nil {\n\t\t\tuplinkCounter = c\n\t\t}\n\t}\n\tif len(tag) > 0 && policy.ForSystem().Stats.OutboundDownlink {\n\t\tstatsManager := v.GetFeature(stats.ManagerType()).(stats.Manager)\n\t\tname := \"outbound>>>\" + tag + \">>>traffic>>>downlink\"\n\t\tc, _ := stats.GetOrRegisterCounter(statsManager, name)\n\t\tif c != nil {\n\t\t\tdownlinkCounter = c\n\t\t}\n\t}\n\n\treturn uplinkCounter, downlinkCounter\n}\n\n// Handler is an implements of outbound.Handler.\ntype Handler struct {\n\tctx             context.Context\n\ttag             string\n\tsenderSettings  *proxyman.SenderConfig\n\tstreamSettings  *internet.MemoryStreamConfig\n\tproxy           proxy.Outbound\n\toutboundManager outbound.Manager\n\tmux             *mux.ClientManager\n\tuplinkCounter   stats.Counter\n\tdownlinkCounter stats.Counter\n\tdns             dns.Client\n}\n\n// NewHandler create a new Handler based on the given configuration.\nfunc NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbound.Handler, error) {\n\tv := core.MustFromContext(ctx)\n\tuplinkCounter, downlinkCounter := getStatCounter(v, config.Tag)\n\th := &Handler{\n\t\tctx:             ctx,\n\t\ttag:             config.Tag,\n\t\toutboundManager: v.GetFeature(outbound.ManagerType()).(outbound.Manager),\n\t\tuplinkCounter:   uplinkCounter,\n\t\tdownlinkCounter: downlinkCounter,\n\t}\n\n\tif config.SenderSettings != nil {\n\t\tsenderSettings, err := serial.GetInstanceOf(config.SenderSettings)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch s := senderSettings.(type) {\n\t\tcase *proxyman.SenderConfig:\n\t\t\th.senderSettings = s\n\t\t\tmss, err := internet.ToMemoryStreamConfig(s.StreamSettings)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse stream settings\").Base(err).AtWarning()\n\t\t\t}\n\t\t\th.streamSettings = mss\n\t\tdefault:\n\t\t\treturn nil, newError(\"settings is not SenderConfig\")\n\t\t}\n\t}\n\n\tproxyConfig, err := serial.GetInstanceOf(config.ProxySettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trawProxyHandler, err := common.CreateObject(ctx, proxyConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tproxyHandler, ok := rawProxyHandler.(proxy.Outbound)\n\tif !ok {\n\t\treturn nil, newError(\"not an outbound handler\")\n\t}\n\n\tif h.senderSettings != nil && h.senderSettings.MultiplexSettings != nil {\n\t\tconfig := h.senderSettings.MultiplexSettings\n\t\tif config.Concurrency < 1 || config.Concurrency > 1024 {\n\t\t\treturn nil, newError(\"invalid mux concurrency: \", config.Concurrency).AtWarning()\n\t\t}\n\t\th.mux = &mux.ClientManager{\n\t\t\tEnabled: h.senderSettings.MultiplexSettings.Enabled,\n\t\t\tPicker: &mux.IncrementalWorkerPicker{\n\t\t\t\tFactory: mux.NewDialingWorkerFactory(\n\t\t\t\t\tctx,\n\t\t\t\t\tproxyHandler,\n\t\t\t\t\th,\n\t\t\t\t\tmux.ClientStrategy{\n\t\t\t\t\t\tMaxConcurrency: config.Concurrency,\n\t\t\t\t\t\tMaxConnection:  128,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t}\n\t}\n\n\tif h.senderSettings != nil && h.senderSettings.DomainStrategy != proxyman.SenderConfig_AS_IS {\n\t\terr := core.RequireFeatures(ctx, func(d dns.Client) error {\n\t\t\th.dns = d\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\th.proxy = proxyHandler\n\treturn h, nil\n}\n\n// Tag implements outbound.Handler.\nfunc (h *Handler) Tag() string {\n\treturn h.tag\n}\n\n// Dispatch implements proxy.Outbound.Dispatch.\nfunc (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {\n\tif h.senderSettings != nil && h.senderSettings.DomainStrategy != proxyman.SenderConfig_AS_IS {\n\t\toutbound := session.OutboundFromContext(ctx)\n\t\tif outbound == nil {\n\t\t\toutbound = new(session.Outbound)\n\t\t\tctx = session.ContextWithOutbound(ctx, outbound)\n\t\t}\n\t\tif outbound.Target.Address != nil && outbound.Target.Address.Family().IsDomain() {\n\t\t\tif addr := h.resolveIP(ctx, outbound.Target.Address.Domain(), h.Address()); addr != nil {\n\t\t\t\toutbound.Target.Address = addr\n\t\t\t}\n\t\t}\n\t}\n\tif h.mux != nil && (h.mux.Enabled || session.MuxPreferedFromContext(ctx)) {\n\t\tif err := h.mux.Dispatch(ctx, link); err != nil {\n\t\t\terr := newError(\"failed to process mux outbound traffic\").Base(err)\n\t\t\tsession.SubmitOutboundErrorToOriginator(ctx, err)\n\t\t\terr.WriteToLog(session.ExportIDToError(ctx))\n\t\t\tcommon.Interrupt(link.Writer)\n\t\t}\n\t} else {\n\t\tif err := h.proxy.Process(ctx, link, h); err != nil {\n\t\t\t// Ensure outbound ray is properly closed.\n\t\t\terr := newError(\"failed to process outbound traffic\").Base(err)\n\t\t\tsession.SubmitOutboundErrorToOriginator(ctx, err)\n\t\t\terr.WriteToLog(session.ExportIDToError(ctx))\n\t\t\tcommon.Interrupt(link.Writer)\n\t\t} else {\n\t\t\tcommon.Must(common.Close(link.Writer))\n\t\t}\n\t\tcommon.Interrupt(link.Reader)\n\t}\n}\n\n// Address implements internet.Dialer.\nfunc (h *Handler) Address() net.Address {\n\tif h.senderSettings == nil || h.senderSettings.Via == nil {\n\t\treturn nil\n\t}\n\treturn h.senderSettings.Via.AsAddress()\n}\n\n// Dial implements internet.Dialer.\nfunc (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Connection, error) {\n\tif h.senderSettings != nil {\n\t\tif h.senderSettings.ProxySettings.HasTag() && !h.senderSettings.ProxySettings.TransportLayerProxy {\n\t\t\ttag := h.senderSettings.ProxySettings.Tag\n\t\t\thandler := h.outboundManager.GetHandler(tag)\n\t\t\tif handler != nil {\n\t\t\t\tnewError(\"proxying to \", tag, \" for dest \", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\tctx = session.ContextWithOutbound(ctx, &session.Outbound{\n\t\t\t\t\tTarget: dest,\n\t\t\t\t})\n\n\t\t\t\topts := pipe.OptionsFromContext(ctx)\n\t\t\t\tuplinkReader, uplinkWriter := pipe.New(opts...)\n\t\t\t\tdownlinkReader, downlinkWriter := pipe.New(opts...)\n\n\t\t\t\tgo handler.Dispatch(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter})\n\t\t\t\tconn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader))\n\n\t\t\t\tsecurityEngine, err := security.CreateSecurityEngineFromSettings(ctx, h.streamSettings)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, newError(\"unable to create security engine\").Base(err)\n\t\t\t\t}\n\n\t\t\t\tif securityEngine != nil {\n\t\t\t\t\tconn, err = securityEngine.Client(conn, security.OptionWithDestination{Dest: dest})\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, newError(\"unable to create security protocol client from security engine\").Base(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn h.getStatCouterConnection(conn), nil\n\t\t\t}\n\n\t\t\tnewError(\"failed to get outbound handler with tag: \", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\n\t\tif h.senderSettings.Via != nil {\n\t\t\toutbound := session.OutboundFromContext(ctx)\n\t\t\tif outbound == nil {\n\t\t\t\toutbound = new(session.Outbound)\n\t\t\t\tctx = session.ContextWithOutbound(ctx, outbound)\n\t\t\t}\n\t\t\toutbound.Gateway = h.senderSettings.Via.AsAddress()\n\t\t}\n\n\t\tif h.senderSettings.DomainStrategy != proxyman.SenderConfig_AS_IS {\n\t\t\toutbound := session.OutboundFromContext(ctx)\n\t\t\tif outbound == nil {\n\t\t\t\toutbound = new(session.Outbound)\n\t\t\t\tctx = session.ContextWithOutbound(ctx, outbound)\n\t\t\t}\n\t\t\toutbound.Resolver = func(ctx context.Context, domain string) net.Address {\n\t\t\t\treturn h.resolveIP(ctx, domain, h.Address())\n\t\t\t}\n\t\t}\n\t}\n\n\tenablePacketAddrCapture := true\n\tif h.senderSettings != nil && h.senderSettings.ProxySettings != nil && h.senderSettings.ProxySettings.HasTag() && h.senderSettings.ProxySettings.TransportLayerProxy {\n\t\ttag := h.senderSettings.ProxySettings.Tag\n\t\tnewError(\"transport layer proxying to \", tag, \" for dest \", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\t\tctx = session.SetTransportLayerProxyTagToContext(ctx, tag)\n\t\tenablePacketAddrCapture = false\n\t}\n\n\tif isStream, err := packetaddr.GetDestinationSubsetOf(dest); err == nil && enablePacketAddrCapture {\n\t\tpacketConn, err := internet.ListenSystemPacket(ctx, &net.UDPAddr{IP: net.AnyIP.IP(), Port: 0}, h.streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to listen socket\").Base(err)\n\t\t}\n\t\tconn := packetaddr.ToPacketAddrConnWrapper(packetConn, isStream)\n\t\treturn h.getStatCouterConnection(conn), nil\n\t}\n\n\tproxyEnvironment := envctx.EnvironmentFromContext(h.ctx).(environment.ProxyEnvironment)\n\ttransportEnvironment, err := proxyEnvironment.NarrowScopeToTransport(\"transport\")\n\tif err != nil {\n\t\treturn nil, newError(\"unable to narrow environment to transport\").Base(err)\n\t}\n\tctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)\n\tconn, err := internet.Dial(ctx, dest, h.streamSettings)\n\treturn h.getStatCouterConnection(conn), err\n}\n\nfunc (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address {\n\tstrategy := h.senderSettings.DomainStrategy\n\tips, err := dns.LookupIPWithOption(h.dns, domain, dns.IPOption{\n\t\tIPv4Enable: strategy == proxyman.SenderConfig_USE_IP || strategy == proxyman.SenderConfig_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()),\n\t\tIPv6Enable: strategy == proxyman.SenderConfig_USE_IP || strategy == proxyman.SenderConfig_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()),\n\t\tFakeEnable: false,\n\t})\n\tif err != nil {\n\t\tnewError(\"failed to get IP address for domain \", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\tif len(ips) == 0 {\n\t\treturn nil\n\t}\n\treturn net.IPAddress(ips[dice.Roll(len(ips))])\n}\n\nfunc (h *Handler) getStatCouterConnection(conn internet.Connection) internet.Connection {\n\tif h.uplinkCounter != nil || h.downlinkCounter != nil {\n\t\treturn &internet.StatCouterConnection{\n\t\t\tConnection:   conn,\n\t\t\tReadCounter:  h.downlinkCounter,\n\t\t\tWriteCounter: h.uplinkCounter,\n\t\t}\n\t}\n\treturn conn\n}\n\n// GetOutbound implements proxy.GetOutbound.\nfunc (h *Handler) GetOutbound() proxy.Outbound {\n\treturn h.proxy\n}\n\n// Start implements common.Runnable.\nfunc (h *Handler) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (h *Handler) Close() error {\n\tcommon.Close(h.mux)\n\n\tif closableProxy, ok := h.proxy.(common.Closable); ok {\n\t\tif err := closableProxy.Close(); err != nil {\n\t\t\treturn newError(\"unable to close proxy\").Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "app/proxyman/outbound/handler_test.go",
    "content": "package outbound_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t_ \"unsafe\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t. \"github.com/v2fly/v2ray-core/v5/app/proxyman/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/deferredpersistentstorage\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/filesystemimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/systemnetworkimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/transientstorageimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc TestInterfaces(t *testing.T) {\n\t_ = (outbound.Handler)(new(Handler))\n\t_ = (outbound.Manager)(new(Manager))\n}\n\n//go:linkname toContext github.com/v2fly/v2ray-core/v5.toContext\nfunc toContext(ctx context.Context, v *core.Instance) context.Context\n\nfunc TestOutboundWithoutStatCounter(t *testing.T) {\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&stats.Config{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tSystem: &policy.SystemPolicy{\n\t\t\t\t\tStats: &policy.SystemPolicy_Stats{\n\t\t\t\t\t\tInboundUplink: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t}\n\n\tv, _ := core.New(config)\n\tv.AddFeature((outbound.Manager)(new(Manager)))\n\tctx := toContext(context.Background(), v)\n\tdefaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()\n\tdefaultFilesystemImpl := filesystemimpl.NewDefaultFileSystemDefaultImpl()\n\tdeferredPersistentStorageImpl := deferredpersistentstorage.NewDeferredPersistentStorage(ctx)\n\trootEnv := environment.NewRootEnvImpl(ctx,\n\t\ttransientstorageimpl.NewScopedTransientStorageImpl(), defaultNetworkImpl.Dialer(), defaultNetworkImpl.Listener(),\n\t\tdefaultFilesystemImpl, deferredPersistentStorageImpl)\n\tproxyEnvironment := rootEnv.ProxyEnvironment(\"o\")\n\tctx = envctx.ContextWithEnvironment(ctx, proxyEnvironment)\n\th, _ := NewHandler(ctx, &core.OutboundHandlerConfig{\n\t\tTag:           \"tag\",\n\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t})\n\tconn, _ := h.(*Handler).Dial(ctx, net.TCPDestination(net.DomainAddress(\"localhost\"), 13146))\n\t_, ok := conn.(*internet.StatCouterConnection)\n\tif ok {\n\t\tt.Errorf(\"Expected conn to not be StatCouterConnection\")\n\t}\n}\n\nfunc TestOutboundWithStatCounter(t *testing.T) {\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&stats.Config{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tSystem: &policy.SystemPolicy{\n\t\t\t\t\tStats: &policy.SystemPolicy_Stats{\n\t\t\t\t\t\tOutboundUplink:   true,\n\t\t\t\t\t\tOutboundDownlink: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t}\n\n\tv, _ := core.New(config)\n\tv.AddFeature((outbound.Manager)(new(Manager)))\n\tctx := toContext(context.Background(), v)\n\tdefaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()\n\tdefaultFilesystemImpl := filesystemimpl.NewDefaultFileSystemDefaultImpl()\n\tdeferredPersistentStorageImpl := deferredpersistentstorage.NewDeferredPersistentStorage(ctx)\n\trootEnv := environment.NewRootEnvImpl(ctx,\n\t\ttransientstorageimpl.NewScopedTransientStorageImpl(), defaultNetworkImpl.Dialer(), defaultNetworkImpl.Listener(),\n\t\tdefaultFilesystemImpl, deferredPersistentStorageImpl)\n\tproxyEnvironment := rootEnv.ProxyEnvironment(\"o\")\n\tctx = envctx.ContextWithEnvironment(ctx, proxyEnvironment)\n\th, _ := NewHandler(ctx, &core.OutboundHandlerConfig{\n\t\tTag:           \"tag\",\n\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t})\n\tconn, _ := h.(*Handler).Dial(ctx, net.TCPDestination(net.DomainAddress(\"localhost\"), 13146))\n\t_, ok := conn.(*internet.StatCouterConnection)\n\tif !ok {\n\t\tt.Errorf(\"Expected conn to be StatCouterConnection\")\n\t}\n}\n"
  },
  {
    "path": "app/proxyman/outbound/outbound.go",
    "content": "package outbound\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n)\n\n// Manager is to manage all outbound handlers.\ntype Manager struct {\n\taccess           sync.RWMutex\n\tdefaultHandler   outbound.Handler\n\ttaggedHandler    map[string]outbound.Handler\n\tuntaggedHandlers []outbound.Handler\n\trunning          bool\n}\n\n// New creates a new Manager.\nfunc New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {\n\tm := &Manager{\n\t\ttaggedHandler: make(map[string]outbound.Handler),\n\t}\n\treturn m, nil\n}\n\n// Type implements common.HasType.\nfunc (m *Manager) Type() interface{} {\n\treturn outbound.ManagerType()\n}\n\n// Start implements core.Feature\nfunc (m *Manager) Start() error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tm.running = true\n\n\tfor _, h := range m.taggedHandler {\n\t\tif err := h.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfor _, h := range m.untaggedHandlers {\n\t\tif err := h.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Close implements core.Feature\nfunc (m *Manager) Close() error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tm.running = false\n\n\tvar errs []error\n\tfor _, h := range m.taggedHandler {\n\t\terrs = append(errs, h.Close())\n\t}\n\n\tfor _, h := range m.untaggedHandlers {\n\t\terrs = append(errs, h.Close())\n\t}\n\n\treturn errors.Combine(errs...)\n}\n\n// GetDefaultHandler implements outbound.Manager.\nfunc (m *Manager) GetDefaultHandler() outbound.Handler {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\n\treturn m.defaultHandler\n}\n\n// GetHandler implements outbound.Manager.\nfunc (m *Manager) GetHandler(tag string) outbound.Handler {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\tif handler, found := m.taggedHandler[tag]; found {\n\t\treturn handler\n\t}\n\treturn nil\n}\n\n// AddHandler implements outbound.Manager.\nfunc (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\ttag := handler.Tag()\n\n\tif m.defaultHandler == nil ||\n\t\t(len(tag) > 0 && tag == m.defaultHandler.Tag()) {\n\t\tm.defaultHandler = handler\n\t}\n\n\tif len(tag) > 0 {\n\t\tif oldHandler, found := m.taggedHandler[tag]; found {\n\t\t\terrors.New(\"will replace the existed outbound with the tag: \" + tag).AtWarning().WriteToLog()\n\t\t\t_ = oldHandler.Close()\n\t\t}\n\t\tm.taggedHandler[tag] = handler\n\t} else {\n\t\tm.untaggedHandlers = append(m.untaggedHandlers, handler)\n\t}\n\n\tif m.running {\n\t\treturn handler.Start()\n\t}\n\n\treturn nil\n}\n\n// RemoveHandler implements outbound.Manager.\nfunc (m *Manager) RemoveHandler(ctx context.Context, tag string) error {\n\tif tag == \"\" {\n\t\treturn common.ErrNoClue\n\t}\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tif handler, found := m.taggedHandler[tag]; found {\n\t\tif err := handler.Close(); err != nil {\n\t\t\tnewError(\"failed to close handler \", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t\tdelete(m.taggedHandler, tag)\n\t\tif m.defaultHandler != nil && m.defaultHandler.Tag() == tag {\n\t\t\tm.defaultHandler = nil\n\t\t}\n\t\treturn nil\n\t}\n\n\treturn common.ErrNoClue\n}\n\n// Select implements outbound.HandlerSelector.\nfunc (m *Manager) Select(selectors []string) []string {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\n\ttags := make([]string, 0, len(selectors))\n\n\tfor tag := range m.taggedHandler {\n\t\tmatch := false\n\t\tfor _, selector := range selectors {\n\t\t\tif strings.HasPrefix(tag, selector) {\n\t\t\t\tmatch = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif match {\n\t\t\ttags = append(tags, tag)\n\t\t}\n\t}\n\n\treturn tags\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*proxyman.OutboundConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*proxyman.OutboundConfig))\n\t}))\n\tcommon.Must(common.RegisterConfig((*core.OutboundHandlerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewHandler(ctx, config.(*core.OutboundHandlerConfig))\n\t}))\n}\n"
  },
  {
    "path": "app/restfulapi/config.go",
    "content": "package restfulapi\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn newRestfulService(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/restfulapi/config.pb.go",
    "content": "package restfulapi\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tListenAddr    string                 `protobuf:\"bytes,1,opt,name=listen_addr,json=listenAddr,proto3\" json:\"listen_addr,omitempty\"`\n\tListenPort    int32                  `protobuf:\"varint,2,opt,name=listen_port,json=listenPort,proto3\" json:\"listen_port,omitempty\"`\n\tAuthToken     string                 `protobuf:\"bytes,3,opt,name=auth_token,json=authToken,proto3\" json:\"auth_token,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_restfulapi_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_restfulapi_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_restfulapi_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetListenAddr() string {\n\tif x != nil {\n\t\treturn x.ListenAddr\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetListenPort() int32 {\n\tif x != nil {\n\t\treturn x.ListenPort\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetAuthToken() string {\n\tif x != nil {\n\t\treturn x.AuthToken\n\t}\n\treturn \"\"\n}\n\nvar File_app_restfulapi_config_proto protoreflect.FileDescriptor\n\nconst file_app_restfulapi_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1bapp/restfulapi/config.proto\\x12\\x14v2ray.app.restfulapi\\x1a common/protoext/extensions.proto\\\"\\x84\\x01\\n\" +\n\t\"\\x06Config\\x12\\x1f\\n\" +\n\t\"\\vlisten_addr\\x18\\x01 \\x01(\\tR\\n\" +\n\t\"listenAddr\\x12\\x1f\\n\" +\n\t\"\\vlisten_port\\x18\\x02 \\x01(\\x05R\\n\" +\n\t\"listenPort\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"auth_token\\x18\\x03 \\x01(\\tR\\tauthToken:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\aservice\\x12\\n\" +\n\t\"restfulapiBa\\n\" +\n\t\"\\x1acom.v2ray.core.app.restapiP\\x01Z-github.com/v2fly/v2ray-core/v5/app/restfulapi\\xaa\\x02\\x11V2Ray.App.Restapib\\x06proto3\"\n\nvar (\n\tfile_app_restfulapi_config_proto_rawDescOnce sync.Once\n\tfile_app_restfulapi_config_proto_rawDescData []byte\n)\n\nfunc file_app_restfulapi_config_proto_rawDescGZIP() []byte {\n\tfile_app_restfulapi_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_restfulapi_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_restfulapi_config_proto_rawDesc), len(file_app_restfulapi_config_proto_rawDesc)))\n\t})\n\treturn file_app_restfulapi_config_proto_rawDescData\n}\n\nvar file_app_restfulapi_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_restfulapi_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.app.restfulapi.Config\n}\nvar file_app_restfulapi_config_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_app_restfulapi_config_proto_init() }\nfunc file_app_restfulapi_config_proto_init() {\n\tif File_app_restfulapi_config_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: unsafe.Slice(unsafe.StringData(file_app_restfulapi_config_proto_rawDesc), len(file_app_restfulapi_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_restfulapi_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_restfulapi_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_restfulapi_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_restfulapi_config_proto = out.File\n\tfile_app_restfulapi_config_proto_goTypes = nil\n\tfile_app_restfulapi_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/restfulapi/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.app.restfulapi;\noption csharp_namespace = \"V2Ray.App.Restapi\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/restfulapi\";\noption java_package = \"com.v2ray.core.app.restapi\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config{\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"restfulapi\";\n\n  string listen_addr = 1;\n  int32 listen_port = 2;\n  string auth_token = 3;\n}\n"
  },
  {
    "path": "app/restfulapi/errors.generated.go",
    "content": "package restfulapi\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/restfulapi/restful_api.go",
    "content": "package restfulapi\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/go-chi/chi/v5/middleware\"\n\t\"github.com/go-chi/render\"\n\t\"github.com/go-playground/validator/v10\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nvar validate *validator.Validate\n\ntype StatsBound struct { // Better name?\n\tUplink   int64 `json:\"uplink\"`\n\tDownlink int64 `json:\"downlink\"`\n}\n\nfunc (rs *restfulService) tagStats(w http.ResponseWriter, r *http.Request) {\n\tboundType := chi.URLParam(r, \"bound_type\")\n\ttag := chi.URLParam(r, \"tag\")\n\n\tif validate.Var(boundType, \"required,oneof=inbounds outbounds\") != nil ||\n\t\tvalidate.Var(tag, \"required,min=1,max=255\") != nil {\n\t\trender.Status(r, http.StatusUnprocessableEntity)\n\t\trender.JSON(w, r, render.M{})\n\t\treturn\n\t}\n\n\tbound := boundType[:len(boundType)-1]\n\tupCounter := rs.stats.GetCounter(bound + \">>>\" + tag + \">>>traffic>>>uplink\")\n\tdownCounter := rs.stats.GetCounter(bound + \">>>\" + tag + \">>>traffic>>>downlink\")\n\tif upCounter == nil || downCounter == nil {\n\t\trender.Status(r, http.StatusNotFound)\n\t\trender.JSON(w, r, render.M{})\n\t\treturn\n\t}\n\n\trender.JSON(w, r, &StatsBound{\n\t\tUplink:   upCounter.Value(),\n\t\tDownlink: downCounter.Value(),\n\t})\n}\n\nfunc (rs *restfulService) version(w http.ResponseWriter, r *http.Request) {\n\trender.JSON(w, r, render.M{\"version\": core.Version()})\n}\n\nfunc (rs *restfulService) TokenAuthMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\theader := r.Header.Get(\"Authorization\")\n\t\ttext := strings.SplitN(header, \" \", 2)\n\n\t\thasInvalidHeader := text[0] != \"Bearer\"\n\t\thasInvalidSecret := len(text) != 2 || text[1] != rs.config.AuthToken\n\t\tif hasInvalidHeader || hasInvalidSecret {\n\t\t\trender.Status(r, http.StatusUnauthorized)\n\t\t\trender.JSON(w, r, render.M{})\n\t\t\treturn\n\t\t}\n\n\t\tnext.ServeHTTP(w, r)\n\t})\n}\n\nfunc (rs *restfulService) start() error {\n\tr := chi.NewRouter()\n\tr.Use(middleware.Heartbeat(\"/ping\"))\n\n\tvalidate = validator.New()\n\tr.Route(\"/v1\", func(r chi.Router) {\n\t\tr.Get(\"/{bound_type}/{tag}/stats\", rs.tagStats)\n\t})\n\tr.Get(\"/version\", rs.version)\n\n\tvar listener net.Listener\n\tvar err error\n\taddress := net.ParseAddress(rs.config.ListenAddr)\n\n\tswitch {\n\tcase address.Family().IsIP():\n\t\tlistener, err = internet.ListenSystem(rs.ctx, &net.TCPAddr{IP: address.IP(), Port: int(rs.config.ListenPort)}, nil)\n\tcase strings.EqualFold(address.Domain(), \"localhost\"):\n\t\tlistener, err = internet.ListenSystem(rs.ctx, &net.TCPAddr{IP: net.IP{127, 0, 0, 1}, Port: int(rs.config.ListenPort)}, nil)\n\tdefault:\n\t\treturn newError(\"restful api cannot listen on the address: \", address)\n\t}\n\tif err != nil {\n\t\treturn newError(\"restful api cannot listen on the port \", rs.config.ListenPort).Base(err)\n\t}\n\n\tgo func() {\n\t\terr := http.Serve(listener, r)\n\t\tif err != nil {\n\t\t\tnewError(\"unable to serve restful api\").WriteToLog()\n\t\t}\n\t}()\n\treturn nil\n}\n"
  },
  {
    "path": "app/restfulapi/service.go",
    "content": "package restfulapi\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"sync\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\tfeature_stats \"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype restfulService struct {\n\tlistener net.Listener\n\tconfig   *Config\n\taccess   sync.Mutex\n\n\tstats feature_stats.Manager\n\n\tctx context.Context\n}\n\nfunc (rs *restfulService) Type() interface{} {\n\treturn (*struct{})(nil)\n}\n\nfunc (rs *restfulService) Start() error {\n\tdefer rs.access.Unlock()\n\trs.access.Lock()\n\treturn rs.start()\n}\n\nfunc (rs *restfulService) Close() error {\n\tdefer rs.access.Unlock()\n\trs.access.Lock()\n\tif rs.listener != nil {\n\t\treturn rs.listener.Close()\n\t}\n\treturn nil\n}\n\nfunc (rs *restfulService) init(config *Config, stats feature_stats.Manager) {\n\trs.stats = stats\n\trs.config = config\n}\n\nfunc newRestfulService(ctx context.Context, config *Config) (features.Feature, error) {\n\tr := new(restfulService)\n\tr.ctx = ctx\n\tif err := core.RequireFeatures(ctx, func(stats feature_stats.Manager) {\n\t\tr.init(config, stats)\n\t}); err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n"
  },
  {
    "path": "app/restfulapi/service_test.go",
    "content": "package restfulapi\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestTypeReturnAnonymousType(t *testing.T) {\n\tservice := restfulService{}\n\tserviceType := service.Type()\n\tassert.Empty(t, reflect.TypeOf(serviceType).Name(), \"must return anonymous type\")\n}\n"
  },
  {
    "path": "app/reverse/bridge.go",
    "content": "package reverse\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\n// Bridge is a component in reverse proxy, that relays connections from Portal to local address.\ntype Bridge struct {\n\tctx         context.Context\n\tdispatcher  routing.Dispatcher\n\ttag         string\n\tdomain      string\n\tworkers     []*BridgeWorker\n\tmonitorTask *task.Periodic\n}\n\n// NewBridge creates a new Bridge instance.\nfunc NewBridge(ctx context.Context, config *BridgeConfig, dispatcher routing.Dispatcher) (*Bridge, error) {\n\tif config.Tag == \"\" {\n\t\treturn nil, newError(\"bridge tag is empty\")\n\t}\n\tif config.Domain == \"\" {\n\t\treturn nil, newError(\"bridge domain is empty\")\n\t}\n\n\tb := &Bridge{\n\t\tctx:        ctx,\n\t\tdispatcher: dispatcher,\n\t\ttag:        config.Tag,\n\t\tdomain:     config.Domain,\n\t}\n\tb.monitorTask = &task.Periodic{\n\t\tExecute:  b.monitor,\n\t\tInterval: time.Second * 2,\n\t}\n\treturn b, nil\n}\n\nfunc (b *Bridge) cleanup() {\n\tvar activeWorkers []*BridgeWorker\n\n\tfor _, w := range b.workers {\n\t\tif w.IsActive() {\n\t\t\tactiveWorkers = append(activeWorkers, w)\n\t\t}\n\t}\n\n\tif len(activeWorkers) != len(b.workers) {\n\t\tb.workers = activeWorkers\n\t}\n}\n\nfunc (b *Bridge) monitor() error {\n\tb.cleanup()\n\n\tvar numConnections uint32\n\tvar numWorker uint32\n\n\tfor _, w := range b.workers {\n\t\tif w.IsActive() {\n\t\t\tnumConnections += w.Connections()\n\t\t\tnumWorker++\n\t\t}\n\t}\n\n\tif numWorker == 0 || numConnections/numWorker > 16 {\n\t\tworker, err := NewBridgeWorker(b.ctx, b.domain, b.tag, b.dispatcher)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to create bridge worker\").Base(err).AtWarning().WriteToLog()\n\t\t\treturn nil\n\t\t}\n\t\tb.workers = append(b.workers, worker)\n\t}\n\n\treturn nil\n}\n\nfunc (b *Bridge) Start() error {\n\treturn b.monitorTask.Start()\n}\n\nfunc (b *Bridge) Close() error {\n\treturn b.monitorTask.Close()\n}\n\ntype BridgeWorker struct {\n\ttag        string\n\tworker     *mux.ServerWorker\n\tdispatcher routing.Dispatcher\n\tstate      Control_State\n}\n\nfunc NewBridgeWorker(ctx context.Context, domain string, tag string, d routing.Dispatcher) (*BridgeWorker, error) {\n\tbridgeCtx := session.ContextWithInbound(ctx, &session.Inbound{\n\t\tTag: tag,\n\t})\n\tlink, err := d.Dispatch(bridgeCtx, net.Destination{\n\t\tNetwork: net.Network_TCP,\n\t\tAddress: net.DomainAddress(domain),\n\t\tPort:    0,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tw := &BridgeWorker{\n\t\tdispatcher: d,\n\t\ttag:        tag,\n\t}\n\n\tworker, err := mux.NewServerWorker(ctx, w, link)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tw.worker = worker\n\n\treturn w, nil\n}\n\nfunc (w *BridgeWorker) Type() interface{} {\n\treturn routing.DispatcherType()\n}\n\nfunc (w *BridgeWorker) Start() error {\n\treturn nil\n}\n\nfunc (w *BridgeWorker) Close() error {\n\treturn nil\n}\n\nfunc (w *BridgeWorker) IsActive() bool {\n\treturn w.state == Control_ACTIVE && !w.worker.Closed()\n}\n\nfunc (w *BridgeWorker) Connections() uint32 {\n\treturn w.worker.ActiveConnections()\n}\n\nfunc (w *BridgeWorker) handleInternalConn(link transport.Link) {\n\tgo func() {\n\t\treader := link.Reader\n\t\tfor {\n\t\t\tmb, err := reader.ReadMultiBuffer()\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tfor _, b := range mb {\n\t\t\t\tvar ctl Control\n\t\t\t\tif err := proto.Unmarshal(b.Bytes(), &ctl); err != nil {\n\t\t\t\t\tnewError(\"failed to parse proto message\").Base(err).WriteToLog()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif ctl.State != w.state {\n\t\t\t\t\tw.state = ctl.State\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc (w *BridgeWorker) Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error) {\n\tif !isInternalDomain(dest) {\n\t\tctx = session.ContextWithInbound(ctx, &session.Inbound{\n\t\t\tTag: w.tag,\n\t\t})\n\t\treturn w.dispatcher.Dispatch(ctx, dest)\n\t}\n\n\topt := []pipe.Option{pipe.WithSizeLimit(16 * 1024)}\n\tuplinkReader, uplinkWriter := pipe.New(opt...)\n\tdownlinkReader, downlinkWriter := pipe.New(opt...)\n\n\tw.handleInternalConn(transport.Link{\n\t\tReader: downlinkReader,\n\t\tWriter: uplinkWriter,\n\t})\n\n\treturn &transport.Link{\n\t\tReader: uplinkReader,\n\t\tWriter: downlinkWriter,\n\t}, nil\n}\n"
  },
  {
    "path": "app/reverse/config.go",
    "content": "package reverse\n\nimport (\n\t\"crypto/rand\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\nfunc (c *Control) FillInRandom() {\n\trandomLength := dice.Roll(64)\n\tc.Random = make([]byte, randomLength)\n\tio.ReadFull(rand.Reader, c.Random)\n}\n"
  },
  {
    "path": "app/reverse/config.pb.go",
    "content": "package reverse\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Control_State int32\n\nconst (\n\tControl_ACTIVE Control_State = 0\n\tControl_DRAIN  Control_State = 1\n)\n\n// Enum value maps for Control_State.\nvar (\n\tControl_State_name = map[int32]string{\n\t\t0: \"ACTIVE\",\n\t\t1: \"DRAIN\",\n\t}\n\tControl_State_value = map[string]int32{\n\t\t\"ACTIVE\": 0,\n\t\t\"DRAIN\":  1,\n\t}\n)\n\nfunc (x Control_State) Enum() *Control_State {\n\tp := new(Control_State)\n\t*p = x\n\treturn p\n}\n\nfunc (x Control_State) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Control_State) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_reverse_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Control_State) Type() protoreflect.EnumType {\n\treturn &file_app_reverse_config_proto_enumTypes[0]\n}\n\nfunc (x Control_State) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Control_State.Descriptor instead.\nfunc (Control_State) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_reverse_config_proto_rawDescGZIP(), []int{0, 0}\n}\n\ntype Control struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tState         Control_State          `protobuf:\"varint,1,opt,name=state,proto3,enum=v2ray.core.app.reverse.Control_State\" json:\"state,omitempty\"`\n\tRandom        []byte                 `protobuf:\"bytes,99,opt,name=random,proto3\" json:\"random,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Control) Reset() {\n\t*x = Control{}\n\tmi := &file_app_reverse_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Control) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Control) ProtoMessage() {}\n\nfunc (x *Control) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_reverse_config_proto_msgTypes[0]\n\tif 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 Control.ProtoReflect.Descriptor instead.\nfunc (*Control) Descriptor() ([]byte, []int) {\n\treturn file_app_reverse_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Control) GetState() Control_State {\n\tif x != nil {\n\t\treturn x.State\n\t}\n\treturn Control_ACTIVE\n}\n\nfunc (x *Control) GetRandom() []byte {\n\tif x != nil {\n\t\treturn x.Random\n\t}\n\treturn nil\n}\n\ntype BridgeConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tDomain        string                 `protobuf:\"bytes,2,opt,name=domain,proto3\" json:\"domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *BridgeConfig) Reset() {\n\t*x = BridgeConfig{}\n\tmi := &file_app_reverse_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *BridgeConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BridgeConfig) ProtoMessage() {}\n\nfunc (x *BridgeConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_reverse_config_proto_msgTypes[1]\n\tif 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 BridgeConfig.ProtoReflect.Descriptor instead.\nfunc (*BridgeConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_reverse_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *BridgeConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *BridgeConfig) GetDomain() string {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn \"\"\n}\n\ntype PortalConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tDomain        string                 `protobuf:\"bytes,2,opt,name=domain,proto3\" json:\"domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PortalConfig) Reset() {\n\t*x = PortalConfig{}\n\tmi := &file_app_reverse_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PortalConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PortalConfig) ProtoMessage() {}\n\nfunc (x *PortalConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_reverse_config_proto_msgTypes[2]\n\tif 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 PortalConfig.ProtoReflect.Descriptor instead.\nfunc (*PortalConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_reverse_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *PortalConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *PortalConfig) GetDomain() string {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tBridgeConfig  []*BridgeConfig        `protobuf:\"bytes,1,rep,name=bridge_config,json=bridgeConfig,proto3\" json:\"bridge_config,omitempty\"`\n\tPortalConfig  []*PortalConfig        `protobuf:\"bytes,2,rep,name=portal_config,json=portalConfig,proto3\" json:\"portal_config,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_reverse_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_reverse_config_proto_msgTypes[3]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_reverse_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Config) GetBridgeConfig() []*BridgeConfig {\n\tif x != nil {\n\t\treturn x.BridgeConfig\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetPortalConfig() []*PortalConfig {\n\tif x != nil {\n\t\treturn x.PortalConfig\n\t}\n\treturn nil\n}\n\nvar File_app_reverse_config_proto protoreflect.FileDescriptor\n\nconst file_app_reverse_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x18app/reverse/config.proto\\x12\\x16v2ray.core.app.reverse\\x1a common/protoext/extensions.proto\\\"~\\n\" +\n\t\"\\aControl\\x12;\\n\" +\n\t\"\\x05state\\x18\\x01 \\x01(\\x0e2%.v2ray.core.app.reverse.Control.StateR\\x05state\\x12\\x16\\n\" +\n\t\"\\x06random\\x18c \\x01(\\fR\\x06random\\\"\\x1e\\n\" +\n\t\"\\x05State\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06ACTIVE\\x10\\x00\\x12\\t\\n\" +\n\t\"\\x05DRAIN\\x10\\x01\\\"8\\n\" +\n\t\"\\fBridgeConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12\\x16\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tR\\x06domain\\\"8\\n\" +\n\t\"\\fPortalConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12\\x16\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tR\\x06domain\\\"\\xb6\\x01\\n\" +\n\t\"\\x06Config\\x12I\\n\" +\n\t\"\\rbridge_config\\x18\\x01 \\x03(\\v2$.v2ray.core.app.reverse.BridgeConfigR\\fbridgeConfig\\x12I\\n\" +\n\t\"\\rportal_config\\x18\\x02 \\x03(\\v2$.v2ray.core.app.reverse.PortalConfigR\\fportalConfig:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\aservice\\x12\\areverseBg\\n\" +\n\t\"\\x1ccom.v2ray.core.proxy.reverseP\\x01Z*github.com/v2fly/v2ray-core/v5/app/reverse\\xaa\\x02\\x18V2Ray.Core.Proxy.Reverseb\\x06proto3\"\n\nvar (\n\tfile_app_reverse_config_proto_rawDescOnce sync.Once\n\tfile_app_reverse_config_proto_rawDescData []byte\n)\n\nfunc file_app_reverse_config_proto_rawDescGZIP() []byte {\n\tfile_app_reverse_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_reverse_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_reverse_config_proto_rawDesc), len(file_app_reverse_config_proto_rawDesc)))\n\t})\n\treturn file_app_reverse_config_proto_rawDescData\n}\n\nvar file_app_reverse_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_app_reverse_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_app_reverse_config_proto_goTypes = []any{\n\t(Control_State)(0),   // 0: v2ray.core.app.reverse.Control.State\n\t(*Control)(nil),      // 1: v2ray.core.app.reverse.Control\n\t(*BridgeConfig)(nil), // 2: v2ray.core.app.reverse.BridgeConfig\n\t(*PortalConfig)(nil), // 3: v2ray.core.app.reverse.PortalConfig\n\t(*Config)(nil),       // 4: v2ray.core.app.reverse.Config\n}\nvar file_app_reverse_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.reverse.Control.state:type_name -> v2ray.core.app.reverse.Control.State\n\t2, // 1: v2ray.core.app.reverse.Config.bridge_config:type_name -> v2ray.core.app.reverse.BridgeConfig\n\t3, // 2: v2ray.core.app.reverse.Config.portal_config:type_name -> v2ray.core.app.reverse.PortalConfig\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_app_reverse_config_proto_init() }\nfunc file_app_reverse_config_proto_init() {\n\tif File_app_reverse_config_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: unsafe.Slice(unsafe.StringData(file_app_reverse_config_proto_rawDesc), len(file_app_reverse_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   4,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_reverse_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_reverse_config_proto_depIdxs,\n\t\tEnumInfos:         file_app_reverse_config_proto_enumTypes,\n\t\tMessageInfos:      file_app_reverse_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_reverse_config_proto = out.File\n\tfile_app_reverse_config_proto_goTypes = nil\n\tfile_app_reverse_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/reverse/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.reverse;\noption csharp_namespace = \"V2Ray.Core.Proxy.Reverse\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/reverse\";\noption java_package = \"com.v2ray.core.proxy.reverse\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Control {\n  enum State {\n    ACTIVE = 0;\n    DRAIN = 1;\n  }\n\n  State state = 1;\n  bytes random = 99;\n}\n\nmessage BridgeConfig {\n  string tag = 1;\n  string domain = 2;\n}\n\nmessage PortalConfig {\n  string tag = 1;\n  string domain = 2;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"reverse\";\n\n  repeated BridgeConfig bridge_config = 1;\n  repeated PortalConfig portal_config = 2;\n}\n"
  },
  {
    "path": "app/reverse/errors.generated.go",
    "content": "package reverse\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/reverse/portal.go",
    "content": "package reverse\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\ntype Portal struct {\n\tctx    context.Context\n\tohm    outbound.Manager\n\ttag    string\n\tdomain string\n\tpicker *StaticMuxPicker\n\tclient *mux.ClientManager\n}\n\nfunc NewPortal(ctx context.Context, config *PortalConfig, ohm outbound.Manager) (*Portal, error) {\n\tif config.Tag == \"\" {\n\t\treturn nil, newError(\"portal tag is empty\")\n\t}\n\n\tif config.Domain == \"\" {\n\t\treturn nil, newError(\"portal domain is empty\")\n\t}\n\n\tpicker, err := NewStaticMuxPicker()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Portal{\n\t\tctx:    ctx,\n\t\tohm:    ohm,\n\t\ttag:    config.Tag,\n\t\tdomain: config.Domain,\n\t\tpicker: picker,\n\t\tclient: &mux.ClientManager{\n\t\t\tPicker: picker,\n\t\t},\n\t}, nil\n}\n\nfunc (p *Portal) Start() error {\n\treturn p.ohm.AddHandler(p.ctx, &Outbound{\n\t\tportal: p,\n\t\ttag:    p.tag,\n\t})\n}\n\nfunc (p *Portal) Close() error {\n\treturn p.ohm.RemoveHandler(p.ctx, p.tag)\n}\n\nfunc (p *Portal) HandleConnection(ctx context.Context, link *transport.Link) error {\n\toutboundMeta := session.OutboundFromContext(ctx)\n\tif outboundMeta == nil {\n\t\treturn newError(\"outbound metadata not found\").AtError()\n\t}\n\n\tif isDomain(outboundMeta.Target, p.domain) {\n\t\tmuxClient, err := mux.NewClientWorker(*link, mux.ClientStrategy{})\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create mux client worker\").Base(err).AtWarning()\n\t\t}\n\n\t\tworker, err := NewPortalWorker(ctx, muxClient)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create portal worker\").Base(err)\n\t\t}\n\n\t\tp.picker.AddWorker(worker)\n\t\treturn nil\n\t}\n\n\treturn p.client.Dispatch(ctx, link)\n}\n\ntype Outbound struct {\n\tportal *Portal\n\ttag    string\n}\n\nfunc (o *Outbound) Tag() string {\n\treturn o.tag\n}\n\nfunc (o *Outbound) Dispatch(ctx context.Context, link *transport.Link) {\n\tif err := o.portal.HandleConnection(ctx, link); err != nil {\n\t\tnewError(\"failed to process reverse connection\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\tcommon.Interrupt(link.Writer)\n\t}\n}\n\nfunc (o *Outbound) Start() error {\n\treturn nil\n}\n\nfunc (o *Outbound) Close() error {\n\treturn nil\n}\n\ntype StaticMuxPicker struct {\n\taccess  sync.Mutex\n\tworkers []*PortalWorker\n\tcTask   *task.Periodic\n}\n\nfunc NewStaticMuxPicker() (*StaticMuxPicker, error) {\n\tp := &StaticMuxPicker{}\n\tp.cTask = &task.Periodic{\n\t\tExecute:  p.cleanup,\n\t\tInterval: time.Second * 30,\n\t}\n\tp.cTask.Start()\n\treturn p, nil\n}\n\nfunc (p *StaticMuxPicker) cleanup() error {\n\tp.access.Lock()\n\tdefer p.access.Unlock()\n\n\tvar activeWorkers []*PortalWorker\n\tfor _, w := range p.workers {\n\t\tif !w.Closed() {\n\t\t\tactiveWorkers = append(activeWorkers, w)\n\t\t}\n\t}\n\n\tif len(activeWorkers) != len(p.workers) {\n\t\tp.workers = activeWorkers\n\t}\n\n\treturn nil\n}\n\nfunc (p *StaticMuxPicker) PickAvailable() (*mux.ClientWorker, error) {\n\tp.access.Lock()\n\tdefer p.access.Unlock()\n\n\tif len(p.workers) == 0 {\n\t\treturn nil, newError(\"empty worker list\")\n\t}\n\n\tminIdx := -1\n\tvar minConn uint32 = 9999\n\tfor i, w := range p.workers {\n\t\tif w.draining {\n\t\t\tcontinue\n\t\t}\n\t\tif w.client.Closed() {\n\t\t\tcontinue\n\t\t}\n\t\tif w.client.ActiveConnections() < minConn {\n\t\t\tminConn = w.client.ActiveConnections()\n\t\t\tminIdx = i\n\t\t}\n\t}\n\n\tif minIdx == -1 {\n\t\tfor i, w := range p.workers {\n\t\t\tif w.IsFull() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif w.client.ActiveConnections() < minConn {\n\t\t\t\tminConn = w.client.ActiveConnections()\n\t\t\t\tminIdx = i\n\t\t\t}\n\t\t}\n\t}\n\n\tif minIdx != -1 {\n\t\treturn p.workers[minIdx].client, nil\n\t}\n\n\treturn nil, newError(\"no mux client worker available\")\n}\n\nfunc (p *StaticMuxPicker) AddWorker(worker *PortalWorker) {\n\tp.access.Lock()\n\tdefer p.access.Unlock()\n\n\tp.workers = append(p.workers, worker)\n}\n\ntype PortalWorker struct {\n\tclient   *mux.ClientWorker\n\tcontrol  *task.Periodic\n\twriter   buf.Writer\n\treader   buf.Reader\n\tdraining bool\n}\n\nfunc NewPortalWorker(ctx context.Context, client *mux.ClientWorker) (*PortalWorker, error) {\n\topt := []pipe.Option{pipe.WithSizeLimit(16 * 1024)}\n\tuplinkReader, uplinkWriter := pipe.New(opt...)\n\tdownlinkReader, downlinkWriter := pipe.New(opt...)\n\n\tctx = session.ContextWithOutbound(ctx, &session.Outbound{\n\t\tTarget: net.UDPDestination(net.DomainAddress(internalDomain), 0),\n\t})\n\tf := client.Dispatch(ctx, &transport.Link{\n\t\tReader: uplinkReader,\n\t\tWriter: downlinkWriter,\n\t})\n\tif !f {\n\t\treturn nil, newError(\"unable to dispatch control connection\")\n\t}\n\tw := &PortalWorker{\n\t\tclient: client,\n\t\treader: downlinkReader,\n\t\twriter: uplinkWriter,\n\t}\n\tw.control = &task.Periodic{\n\t\tExecute:  w.heartbeat,\n\t\tInterval: time.Second * 2,\n\t}\n\tw.control.Start()\n\treturn w, nil\n}\n\nfunc (w *PortalWorker) heartbeat() error {\n\tif w.client.Closed() {\n\t\treturn newError(\"client worker stopped\")\n\t}\n\n\tif w.draining || w.writer == nil {\n\t\treturn newError(\"already disposed\")\n\t}\n\n\tmsg := &Control{}\n\tmsg.FillInRandom()\n\n\tif w.client.TotalConnections() > 256 {\n\t\tw.draining = true\n\t\tmsg.State = Control_DRAIN\n\n\t\tdefer func() {\n\t\t\tcommon.Close(w.writer)\n\t\t\tcommon.Interrupt(w.reader)\n\t\t\tw.writer = nil\n\t\t}()\n\t}\n\n\tb, err := proto.Marshal(msg)\n\tcommon.Must(err)\n\tmb := buf.MergeBytes(nil, b)\n\treturn w.writer.WriteMultiBuffer(mb)\n}\n\nfunc (w *PortalWorker) IsFull() bool {\n\treturn w.client.IsFull()\n}\n\nfunc (w *PortalWorker) Closed() bool {\n\treturn w.client.Closed()\n}\n"
  },
  {
    "path": "app/reverse/portal_test.go",
    "content": "package reverse_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/reverse\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc TestStaticPickerEmpty(t *testing.T) {\n\tpicker, err := reverse.NewStaticMuxPicker()\n\tcommon.Must(err)\n\tworker, err := picker.PickAvailable()\n\tif err == nil {\n\t\tt.Error(\"expected error, but nil\")\n\t}\n\tif worker != nil {\n\t\tt.Error(\"expected nil worker, but not nil\")\n\t}\n}\n"
  },
  {
    "path": "app/reverse/reverse.go",
    "content": "package reverse\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\nconst (\n\tinternalDomain = \"reverse.internal.v2fly.org\"\n)\n\nfunc isDomain(dest net.Destination, domain string) bool {\n\treturn dest.Address.Family().IsDomain() && dest.Address.Domain() == domain\n}\n\nfunc isInternalDomain(dest net.Destination) bool {\n\treturn isDomain(dest, internalDomain)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tr := new(Reverse)\n\t\tif err := core.RequireFeatures(ctx, func(d routing.Dispatcher, om outbound.Manager) error {\n\t\t\treturn r.Init(ctx, config.(*Config), d, om)\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn r, nil\n\t}))\n}\n\ntype Reverse struct {\n\tbridges []*Bridge\n\tportals []*Portal\n}\n\nfunc (r *Reverse) Init(ctx context.Context, config *Config, d routing.Dispatcher, ohm outbound.Manager) error {\n\tfor _, bConfig := range config.BridgeConfig {\n\t\tb, err := NewBridge(ctx, bConfig, d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.bridges = append(r.bridges, b)\n\t}\n\n\tfor _, pConfig := range config.PortalConfig {\n\t\tp, err := NewPortal(ctx, pConfig, ohm)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.portals = append(r.portals, p)\n\t}\n\n\treturn nil\n}\n\nfunc (r *Reverse) Type() interface{} {\n\treturn (*Reverse)(nil)\n}\n\nfunc (r *Reverse) Start() error {\n\tfor _, b := range r.bridges {\n\t\tif err := b.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfor _, p := range r.portals {\n\t\tif err := p.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (r *Reverse) Close() error {\n\tvar errs []error\n\tfor _, b := range r.bridges {\n\t\terrs = append(errs, b.Close())\n\t}\n\n\tfor _, p := range r.portals {\n\t\terrs = append(errs, p.Close())\n\t}\n\n\treturn errors.Combine(errs...)\n}\n"
  },
  {
    "path": "app/router/balancing.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage router\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n)\n\ntype BalancingStrategy interface {\n\tPickOutbound([]string) string\n}\n\ntype BalancingPrincipleTarget interface {\n\tGetPrincipleTarget([]string) []string\n}\n\ntype Balancer struct {\n\tselectors   []string\n\tstrategy    BalancingStrategy\n\tohm         outbound.Manager\n\tfallbackTag string\n\n\toverride override\n}\n\n// PickOutbound picks the tag of an outbound\nfunc (b *Balancer) PickOutbound() (string, error) {\n\tcandidates, err := b.SelectOutbounds()\n\tif err != nil {\n\t\tif b.fallbackTag != \"\" {\n\t\t\tnewError(\"fallback to [\", b.fallbackTag, \"], due to error: \", err).AtInfo().WriteToLog()\n\t\t\treturn b.fallbackTag, nil\n\t\t}\n\t\treturn \"\", err\n\t}\n\tvar tag string\n\tif o := b.override.Get(); o != \"\" {\n\t\ttag = o\n\t} else {\n\t\ttag = b.strategy.PickOutbound(candidates)\n\t}\n\tif tag == \"\" {\n\t\tif b.fallbackTag != \"\" {\n\t\t\tnewError(\"fallback to [\", b.fallbackTag, \"], due to empty tag returned\").AtInfo().WriteToLog()\n\t\t\treturn b.fallbackTag, nil\n\t\t}\n\t\t// will use default handler\n\t\treturn \"\", newError(\"balancing strategy returns empty tag\")\n\t}\n\treturn tag, nil\n}\n\nfunc (b *Balancer) InjectContext(ctx context.Context) {\n\tif contextReceiver, ok := b.strategy.(extension.ContextReceiver); ok {\n\t\tcontextReceiver.InjectContext(ctx)\n\t}\n}\n\n// SelectOutbounds select outbounds with selectors of the Balancer\nfunc (b *Balancer) SelectOutbounds() ([]string, error) {\n\ths, ok := b.ohm.(outbound.HandlerSelector)\n\tif !ok {\n\t\treturn nil, newError(\"outbound.Manager is not a HandlerSelector\")\n\t}\n\ttags := hs.Select(b.selectors)\n\treturn tags, nil\n}\n\n// GetPrincipleTarget implements routing.BalancerPrincipleTarget\nfunc (r *Router) GetPrincipleTarget(tag string) ([]string, error) {\n\tif b, ok := r.balancers[tag]; ok {\n\t\tif s, ok := b.strategy.(BalancingPrincipleTarget); ok {\n\t\t\tcandidates, err := b.SelectOutbounds()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"unable to select outbounds\").Base(err)\n\t\t\t}\n\t\t\treturn s.GetPrincipleTarget(candidates), nil\n\t\t}\n\t\treturn nil, newError(\"unsupported GetPrincipleTarget\")\n\t}\n\treturn nil, newError(\"cannot find tag\")\n}\n\n// SetOverrideTarget implements routing.BalancerOverrider\nfunc (r *Router) SetOverrideTarget(tag, target string) error {\n\tif b, ok := r.balancers[tag]; ok {\n\t\tb.override.Put(target)\n\t\treturn nil\n\t}\n\treturn newError(\"cannot find tag\")\n}\n\n// GetOverrideTarget implements routing.BalancerOverrider\nfunc (r *Router) GetOverrideTarget(tag string) (string, error) {\n\tif b, ok := r.balancers[tag]; ok {\n\t\treturn b.override.Get(), nil\n\t}\n\treturn \"\", newError(\"cannot find tag\")\n}\n"
  },
  {
    "path": "app/router/balancing_override.go",
    "content": "package router\n\nimport (\n\tsync \"sync\"\n)\n\nfunc (r *Router) OverrideBalancer(balancer string, target string) error {\n\tvar b *Balancer\n\tfor tag, bl := range r.balancers {\n\t\tif tag == balancer {\n\t\t\tb = bl\n\t\t\tbreak\n\t\t}\n\t}\n\tif b == nil {\n\t\treturn newError(\"balancer '\", balancer, \"' not found\")\n\t}\n\tb.override.Put(target)\n\treturn nil\n}\n\ntype overrideSettings struct {\n\ttarget string\n}\n\ntype override struct {\n\taccess   sync.RWMutex\n\tsettings overrideSettings\n}\n\n// Get gets the override settings\nfunc (o *override) Get() string {\n\to.access.RLock()\n\tdefer o.access.RUnlock()\n\treturn o.settings.target\n}\n\n// Put updates the override settings\nfunc (o *override) Put(target string) {\n\to.access.Lock()\n\tdefer o.access.Unlock()\n\to.settings.target = target\n}\n\n// Clear clears the override settings\nfunc (o *override) Clear() {\n\to.access.Lock()\n\tdefer o.access.Unlock()\n\to.settings.target = \"\"\n}\n"
  },
  {
    "path": "app/router/command/command.go",
    "content": "package command\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\n// routingServer is an implementation of RoutingService.\ntype routingServer struct {\n\trouter       routing.Router\n\troutingStats stats.Channel\n}\n\nfunc (s *routingServer) GetBalancerInfo(ctx context.Context, request *GetBalancerInfoRequest) (*GetBalancerInfoResponse, error) {\n\tvar ret GetBalancerInfoResponse\n\tret.Balancer = &BalancerMsg{}\n\tif bo, ok := s.router.(routing.BalancerOverrider); ok {\n\t\t{\n\t\t\tres, err := bo.GetOverrideTarget(request.GetTag())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tret.Balancer.Override = &OverrideInfo{\n\t\t\t\tTarget: res,\n\t\t\t}\n\t\t}\n\t}\n\n\tif pt, ok := s.router.(routing.BalancerPrincipleTarget); ok {\n\t\t{\n\t\t\tres, err := pt.GetPrincipleTarget(request.GetTag())\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"unable to obtain principle target\").Base(err).AtInfo().WriteToLog()\n\t\t\t} else {\n\t\t\t\tret.Balancer.PrincipleTarget = &PrincipleTargetInfo{Tag: res}\n\t\t\t}\n\t\t}\n\t}\n\treturn &ret, nil\n}\n\nfunc (s *routingServer) OverrideBalancerTarget(ctx context.Context, request *OverrideBalancerTargetRequest) (*OverrideBalancerTargetResponse, error) {\n\tif bo, ok := s.router.(routing.BalancerOverrider); ok {\n\t\treturn &OverrideBalancerTargetResponse{}, bo.SetOverrideTarget(request.BalancerTag, request.Target)\n\t}\n\treturn nil, newError(\"unsupported router implementation\")\n}\n\n// NewRoutingServer creates a statistics service with statistics manager.\nfunc NewRoutingServer(router routing.Router, routingStats stats.Channel) RoutingServiceServer {\n\treturn &routingServer{\n\t\trouter:       router,\n\t\troutingStats: routingStats,\n\t}\n}\n\nfunc (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest) (*RoutingContext, error) {\n\tif request.RoutingContext == nil {\n\t\treturn nil, newError(\"Invalid routing request.\")\n\t}\n\troute, err := s.router.PickRoute(AsRoutingContext(request.RoutingContext))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif request.PublishResult && s.routingStats != nil {\n\t\tctx, _ := context.WithTimeout(context.Background(), 4*time.Second) // nolint: govet\n\t\ts.routingStats.Publish(ctx, route)\n\t}\n\treturn AsProtobufMessage(request.FieldSelectors)(route), nil\n}\n\nfunc (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error {\n\tif s.routingStats == nil {\n\t\treturn newError(\"Routing statistics not enabled.\")\n\t}\n\tgenMessage := AsProtobufMessage(request.FieldSelectors)\n\tsubscriber, err := stats.SubscribeRunnableChannel(s.routingStats)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer stats.UnsubscribeClosableChannel(s.routingStats, subscriber)\n\tfor {\n\t\tselect {\n\t\tcase value, ok := <-subscriber:\n\t\t\tif !ok {\n\t\t\t\treturn newError(\"Upstream closed the subscriber channel.\")\n\t\t\t}\n\t\t\troute, ok := value.(routing.Route)\n\t\t\tif !ok {\n\t\t\t\treturn newError(\"Upstream sent malformed statistics.\")\n\t\t\t}\n\t\t\terr := stream.Send(genMessage(route))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase <-stream.Context().Done():\n\t\t\treturn stream.Context().Err()\n\t\t}\n\t}\n}\n\nfunc (s *routingServer) mustEmbedUnimplementedRoutingServiceServer() {}\n\ntype service struct {\n\tv *core.Instance\n}\n\nfunc (s *service) Register(server *grpc.Server) {\n\tcommon.Must(s.v.RequireFeatures(func(router routing.Router, stats stats.Manager) {\n\t\tRegisterRoutingServiceServer(server, NewRoutingServer(router, nil))\n\t}))\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\ts := core.MustFromContext(ctx)\n\t\treturn &service{v: s}, nil\n\t}))\n}\n"
  },
  {
    "path": "app/router/command/command.pb.go",
    "content": "package command\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// RoutingContext is the context with information relative to routing process.\n// It conforms to the structure of v2ray.core.features.routing.Context and\n// v2ray.core.features.routing.Route.\ntype RoutingContext struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tInboundTag        string                 `protobuf:\"bytes,1,opt,name=InboundTag,proto3\" json:\"InboundTag,omitempty\"`\n\tNetwork           net.Network            `protobuf:\"varint,2,opt,name=Network,proto3,enum=v2ray.core.common.net.Network\" json:\"Network,omitempty\"`\n\tSourceIPs         [][]byte               `protobuf:\"bytes,3,rep,name=SourceIPs,proto3\" json:\"SourceIPs,omitempty\"`\n\tTargetIPs         [][]byte               `protobuf:\"bytes,4,rep,name=TargetIPs,proto3\" json:\"TargetIPs,omitempty\"`\n\tSourcePort        uint32                 `protobuf:\"varint,5,opt,name=SourcePort,proto3\" json:\"SourcePort,omitempty\"`\n\tTargetPort        uint32                 `protobuf:\"varint,6,opt,name=TargetPort,proto3\" json:\"TargetPort,omitempty\"`\n\tTargetDomain      string                 `protobuf:\"bytes,7,opt,name=TargetDomain,proto3\" json:\"TargetDomain,omitempty\"`\n\tProtocol          string                 `protobuf:\"bytes,8,opt,name=Protocol,proto3\" json:\"Protocol,omitempty\"`\n\tUser              string                 `protobuf:\"bytes,9,opt,name=User,proto3\" json:\"User,omitempty\"`\n\tAttributes        map[string]string      `protobuf:\"bytes,10,rep,name=Attributes,proto3\" json:\"Attributes,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tOutboundGroupTags []string               `protobuf:\"bytes,11,rep,name=OutboundGroupTags,proto3\" json:\"OutboundGroupTags,omitempty\"`\n\tOutboundTag       string                 `protobuf:\"bytes,12,opt,name=OutboundTag,proto3\" json:\"OutboundTag,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *RoutingContext) Reset() {\n\t*x = RoutingContext{}\n\tmi := &file_app_router_command_command_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RoutingContext) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RoutingContext) ProtoMessage() {}\n\nfunc (x *RoutingContext) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[0]\n\tif 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 RoutingContext.ProtoReflect.Descriptor instead.\nfunc (*RoutingContext) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *RoutingContext) GetInboundTag() string {\n\tif x != nil {\n\t\treturn x.InboundTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingContext) GetNetwork() net.Network {\n\tif x != nil {\n\t\treturn x.Network\n\t}\n\treturn net.Network(0)\n}\n\nfunc (x *RoutingContext) GetSourceIPs() [][]byte {\n\tif x != nil {\n\t\treturn x.SourceIPs\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingContext) GetTargetIPs() [][]byte {\n\tif x != nil {\n\t\treturn x.TargetIPs\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingContext) GetSourcePort() uint32 {\n\tif x != nil {\n\t\treturn x.SourcePort\n\t}\n\treturn 0\n}\n\nfunc (x *RoutingContext) GetTargetPort() uint32 {\n\tif x != nil {\n\t\treturn x.TargetPort\n\t}\n\treturn 0\n}\n\nfunc (x *RoutingContext) GetTargetDomain() string {\n\tif x != nil {\n\t\treturn x.TargetDomain\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingContext) GetProtocol() string {\n\tif x != nil {\n\t\treturn x.Protocol\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingContext) GetUser() string {\n\tif x != nil {\n\t\treturn x.User\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingContext) GetAttributes() map[string]string {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingContext) GetOutboundGroupTags() []string {\n\tif x != nil {\n\t\treturn x.OutboundGroupTags\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingContext) GetOutboundTag() string {\n\tif x != nil {\n\t\treturn x.OutboundTag\n\t}\n\treturn \"\"\n}\n\n// SubscribeRoutingStatsRequest subscribes to routing statistics channel if\n// opened by v2ray-core.\n// * FieldSelectors selects a subset of fields in routing statistics to return.\n// Valid selectors:\n//   - inbound: Selects connection's inbound tag.\n//   - network: Selects connection's network.\n//   - ip: Equivalent as \"ip_source\" and \"ip_target\", selects both source and\n//     target IP.\n//   - port: Equivalent as \"port_source\" and \"port_target\", selects both source\n//     and target port.\n//   - domain: Selects target domain.\n//   - protocol: Select connection's protocol.\n//   - user: Select connection's inbound user email.\n//   - attributes: Select connection's additional attributes.\n//   - outbound: Equivalent as \"outbound\" and \"outbound_group\", select both\n//     outbound tag and outbound group tags.\n//\n// * If FieldSelectors is left empty, all fields will be returned.\ntype SubscribeRoutingStatsRequest struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tFieldSelectors []string               `protobuf:\"bytes,1,rep,name=FieldSelectors,proto3\" json:\"FieldSelectors,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *SubscribeRoutingStatsRequest) Reset() {\n\t*x = SubscribeRoutingStatsRequest{}\n\tmi := &file_app_router_command_command_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SubscribeRoutingStatsRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SubscribeRoutingStatsRequest) ProtoMessage() {}\n\nfunc (x *SubscribeRoutingStatsRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[1]\n\tif 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 SubscribeRoutingStatsRequest.ProtoReflect.Descriptor instead.\nfunc (*SubscribeRoutingStatsRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SubscribeRoutingStatsRequest) GetFieldSelectors() []string {\n\tif x != nil {\n\t\treturn x.FieldSelectors\n\t}\n\treturn nil\n}\n\n// TestRouteRequest manually tests a routing result according to the routing\n// context message.\n// * RoutingContext is the routing message without outbound information.\n// * FieldSelectors selects the fields to return in the routing result. All\n// fields are returned if left empty.\n// * PublishResult broadcasts the routing result to routing statistics channel\n// if set true.\ntype TestRouteRequest struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tRoutingContext *RoutingContext        `protobuf:\"bytes,1,opt,name=RoutingContext,proto3\" json:\"RoutingContext,omitempty\"`\n\tFieldSelectors []string               `protobuf:\"bytes,2,rep,name=FieldSelectors,proto3\" json:\"FieldSelectors,omitempty\"`\n\tPublishResult  bool                   `protobuf:\"varint,3,opt,name=PublishResult,proto3\" json:\"PublishResult,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *TestRouteRequest) Reset() {\n\t*x = TestRouteRequest{}\n\tmi := &file_app_router_command_command_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TestRouteRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TestRouteRequest) ProtoMessage() {}\n\nfunc (x *TestRouteRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[2]\n\tif 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 TestRouteRequest.ProtoReflect.Descriptor instead.\nfunc (*TestRouteRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *TestRouteRequest) GetRoutingContext() *RoutingContext {\n\tif x != nil {\n\t\treturn x.RoutingContext\n\t}\n\treturn nil\n}\n\nfunc (x *TestRouteRequest) GetFieldSelectors() []string {\n\tif x != nil {\n\t\treturn x.FieldSelectors\n\t}\n\treturn nil\n}\n\nfunc (x *TestRouteRequest) GetPublishResult() bool {\n\tif x != nil {\n\t\treturn x.PublishResult\n\t}\n\treturn false\n}\n\ntype PrincipleTargetInfo struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           []string               `protobuf:\"bytes,1,rep,name=tag,proto3\" json:\"tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PrincipleTargetInfo) Reset() {\n\t*x = PrincipleTargetInfo{}\n\tmi := &file_app_router_command_command_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PrincipleTargetInfo) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PrincipleTargetInfo) ProtoMessage() {}\n\nfunc (x *PrincipleTargetInfo) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[3]\n\tif 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 PrincipleTargetInfo.ProtoReflect.Descriptor instead.\nfunc (*PrincipleTargetInfo) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *PrincipleTargetInfo) GetTag() []string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn nil\n}\n\ntype OverrideInfo struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTarget        string                 `protobuf:\"bytes,2,opt,name=target,proto3\" json:\"target,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *OverrideInfo) Reset() {\n\t*x = OverrideInfo{}\n\tmi := &file_app_router_command_command_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *OverrideInfo) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OverrideInfo) ProtoMessage() {}\n\nfunc (x *OverrideInfo) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[4]\n\tif 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 OverrideInfo.ProtoReflect.Descriptor instead.\nfunc (*OverrideInfo) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *OverrideInfo) GetTarget() string {\n\tif x != nil {\n\t\treturn x.Target\n\t}\n\treturn \"\"\n}\n\ntype BalancerMsg struct {\n\tstate           protoimpl.MessageState `protogen:\"open.v1\"`\n\tOverride        *OverrideInfo          `protobuf:\"bytes,5,opt,name=override,proto3\" json:\"override,omitempty\"`\n\tPrincipleTarget *PrincipleTargetInfo   `protobuf:\"bytes,6,opt,name=principle_target,json=principleTarget,proto3\" json:\"principle_target,omitempty\"`\n\tunknownFields   protoimpl.UnknownFields\n\tsizeCache       protoimpl.SizeCache\n}\n\nfunc (x *BalancerMsg) Reset() {\n\t*x = BalancerMsg{}\n\tmi := &file_app_router_command_command_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *BalancerMsg) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BalancerMsg) ProtoMessage() {}\n\nfunc (x *BalancerMsg) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[5]\n\tif 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 BalancerMsg.ProtoReflect.Descriptor instead.\nfunc (*BalancerMsg) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *BalancerMsg) GetOverride() *OverrideInfo {\n\tif x != nil {\n\t\treturn x.Override\n\t}\n\treturn nil\n}\n\nfunc (x *BalancerMsg) GetPrincipleTarget() *PrincipleTargetInfo {\n\tif x != nil {\n\t\treturn x.PrincipleTarget\n\t}\n\treturn nil\n}\n\ntype GetBalancerInfoRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag           string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetBalancerInfoRequest) Reset() {\n\t*x = GetBalancerInfoRequest{}\n\tmi := &file_app_router_command_command_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetBalancerInfoRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetBalancerInfoRequest) ProtoMessage() {}\n\nfunc (x *GetBalancerInfoRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[6]\n\tif 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 GetBalancerInfoRequest.ProtoReflect.Descriptor instead.\nfunc (*GetBalancerInfoRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *GetBalancerInfoRequest) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\ntype GetBalancerInfoResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tBalancer      *BalancerMsg           `protobuf:\"bytes,1,opt,name=balancer,proto3\" json:\"balancer,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetBalancerInfoResponse) Reset() {\n\t*x = GetBalancerInfoResponse{}\n\tmi := &file_app_router_command_command_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetBalancerInfoResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetBalancerInfoResponse) ProtoMessage() {}\n\nfunc (x *GetBalancerInfoResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[7]\n\tif 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 GetBalancerInfoResponse.ProtoReflect.Descriptor instead.\nfunc (*GetBalancerInfoResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *GetBalancerInfoResponse) GetBalancer() *BalancerMsg {\n\tif x != nil {\n\t\treturn x.Balancer\n\t}\n\treturn nil\n}\n\ntype OverrideBalancerTargetRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tBalancerTag   string                 `protobuf:\"bytes,1,opt,name=balancerTag,proto3\" json:\"balancerTag,omitempty\"`\n\tTarget        string                 `protobuf:\"bytes,2,opt,name=target,proto3\" json:\"target,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *OverrideBalancerTargetRequest) Reset() {\n\t*x = OverrideBalancerTargetRequest{}\n\tmi := &file_app_router_command_command_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *OverrideBalancerTargetRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OverrideBalancerTargetRequest) ProtoMessage() {}\n\nfunc (x *OverrideBalancerTargetRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[8]\n\tif 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 OverrideBalancerTargetRequest.ProtoReflect.Descriptor instead.\nfunc (*OverrideBalancerTargetRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *OverrideBalancerTargetRequest) GetBalancerTag() string {\n\tif x != nil {\n\t\treturn x.BalancerTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *OverrideBalancerTargetRequest) GetTarget() string {\n\tif x != nil {\n\t\treturn x.Target\n\t}\n\treturn \"\"\n}\n\ntype OverrideBalancerTargetResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *OverrideBalancerTargetResponse) Reset() {\n\t*x = OverrideBalancerTargetResponse{}\n\tmi := &file_app_router_command_command_proto_msgTypes[9]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *OverrideBalancerTargetResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OverrideBalancerTargetResponse) ProtoMessage() {}\n\nfunc (x *OverrideBalancerTargetResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[9]\n\tif 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 OverrideBalancerTargetResponse.ProtoReflect.Descriptor instead.\nfunc (*OverrideBalancerTargetResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{9}\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_router_command_command_proto_msgTypes[10]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_command_command_proto_msgTypes[10]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_router_command_command_proto_rawDescGZIP(), []int{10}\n}\n\nvar File_app_router_command_command_proto protoreflect.FileDescriptor\n\nconst file_app_router_command_command_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\" app/router/command/command.proto\\x12\\x1dv2ray.core.app.router.command\\x1a common/protoext/extensions.proto\\x1a\\x18common/net/network.proto\\\"\\xa8\\x04\\n\" +\n\t\"\\x0eRoutingContext\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"InboundTag\\x18\\x01 \\x01(\\tR\\n\" +\n\t\"InboundTag\\x128\\n\" +\n\t\"\\aNetwork\\x18\\x02 \\x01(\\x0e2\\x1e.v2ray.core.common.net.NetworkR\\aNetwork\\x12\\x1c\\n\" +\n\t\"\\tSourceIPs\\x18\\x03 \\x03(\\fR\\tSourceIPs\\x12\\x1c\\n\" +\n\t\"\\tTargetIPs\\x18\\x04 \\x03(\\fR\\tTargetIPs\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"SourcePort\\x18\\x05 \\x01(\\rR\\n\" +\n\t\"SourcePort\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"TargetPort\\x18\\x06 \\x01(\\rR\\n\" +\n\t\"TargetPort\\x12\\\"\\n\" +\n\t\"\\fTargetDomain\\x18\\a \\x01(\\tR\\fTargetDomain\\x12\\x1a\\n\" +\n\t\"\\bProtocol\\x18\\b \\x01(\\tR\\bProtocol\\x12\\x12\\n\" +\n\t\"\\x04User\\x18\\t \\x01(\\tR\\x04User\\x12]\\n\" +\n\t\"\\n\" +\n\t\"Attributes\\x18\\n\" +\n\t\" \\x03(\\v2=.v2ray.core.app.router.command.RoutingContext.AttributesEntryR\\n\" +\n\t\"Attributes\\x12,\\n\" +\n\t\"\\x11OutboundGroupTags\\x18\\v \\x03(\\tR\\x11OutboundGroupTags\\x12 \\n\" +\n\t\"\\vOutboundTag\\x18\\f \\x01(\\tR\\vOutboundTag\\x1a=\\n\" +\n\t\"\\x0fAttributesEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01\\\"F\\n\" +\n\t\"\\x1cSubscribeRoutingStatsRequest\\x12&\\n\" +\n\t\"\\x0eFieldSelectors\\x18\\x01 \\x03(\\tR\\x0eFieldSelectors\\\"\\xb7\\x01\\n\" +\n\t\"\\x10TestRouteRequest\\x12U\\n\" +\n\t\"\\x0eRoutingContext\\x18\\x01 \\x01(\\v2-.v2ray.core.app.router.command.RoutingContextR\\x0eRoutingContext\\x12&\\n\" +\n\t\"\\x0eFieldSelectors\\x18\\x02 \\x03(\\tR\\x0eFieldSelectors\\x12$\\n\" +\n\t\"\\rPublishResult\\x18\\x03 \\x01(\\bR\\rPublishResult\\\"'\\n\" +\n\t\"\\x13PrincipleTargetInfo\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x03(\\tR\\x03tag\\\"&\\n\" +\n\t\"\\fOverrideInfo\\x12\\x16\\n\" +\n\t\"\\x06target\\x18\\x02 \\x01(\\tR\\x06target\\\"\\xb5\\x01\\n\" +\n\t\"\\vBalancerMsg\\x12G\\n\" +\n\t\"\\boverride\\x18\\x05 \\x01(\\v2+.v2ray.core.app.router.command.OverrideInfoR\\boverride\\x12]\\n\" +\n\t\"\\x10principle_target\\x18\\x06 \\x01(\\v22.v2ray.core.app.router.command.PrincipleTargetInfoR\\x0fprincipleTarget\\\"*\\n\" +\n\t\"\\x16GetBalancerInfoRequest\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\\"a\\n\" +\n\t\"\\x17GetBalancerInfoResponse\\x12F\\n\" +\n\t\"\\bbalancer\\x18\\x01 \\x01(\\v2*.v2ray.core.app.router.command.BalancerMsgR\\bbalancer\\\"Y\\n\" +\n\t\"\\x1dOverrideBalancerTargetRequest\\x12 \\n\" +\n\t\"\\vbalancerTag\\x18\\x01 \\x01(\\tR\\vbalancerTag\\x12\\x16\\n\" +\n\t\"\\x06target\\x18\\x02 \\x01(\\tR\\x06target\\\" \\n\" +\n\t\"\\x1eOverrideBalancerTargetResponse\\\"#\\n\" +\n\t\"\\x06Config:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\vgrpcservice\\x12\\x06router2\\xa8\\x04\\n\" +\n\t\"\\x0eRoutingService\\x12\\x87\\x01\\n\" +\n\t\"\\x15SubscribeRoutingStats\\x12;.v2ray.core.app.router.command.SubscribeRoutingStatsRequest\\x1a-.v2ray.core.app.router.command.RoutingContext\\\"\\x000\\x01\\x12m\\n\" +\n\t\"\\tTestRoute\\x12/.v2ray.core.app.router.command.TestRouteRequest\\x1a-.v2ray.core.app.router.command.RoutingContext\\\"\\x00\\x12\\x82\\x01\\n\" +\n\t\"\\x0fGetBalancerInfo\\x125.v2ray.core.app.router.command.GetBalancerInfoRequest\\x1a6.v2ray.core.app.router.command.GetBalancerInfoResponse\\\"\\x00\\x12\\x97\\x01\\n\" +\n\t\"\\x16OverrideBalancerTarget\\x12<.v2ray.core.app.router.command.OverrideBalancerTargetRequest\\x1a=.v2ray.core.app.router.command.OverrideBalancerTargetResponse\\\"\\x00Bx\\n\" +\n\t\"!com.v2ray.core.app.router.commandP\\x01Z1github.com/v2fly/v2ray-core/v5/app/router/command\\xaa\\x02\\x1dV2Ray.Core.App.Router.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_router_command_command_proto_rawDescOnce sync.Once\n\tfile_app_router_command_command_proto_rawDescData []byte\n)\n\nfunc file_app_router_command_command_proto_rawDescGZIP() []byte {\n\tfile_app_router_command_command_proto_rawDescOnce.Do(func() {\n\t\tfile_app_router_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_router_command_command_proto_rawDesc), len(file_app_router_command_command_proto_rawDesc)))\n\t})\n\treturn file_app_router_command_command_proto_rawDescData\n}\n\nvar file_app_router_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 12)\nvar file_app_router_command_command_proto_goTypes = []any{\n\t(*RoutingContext)(nil),                 // 0: v2ray.core.app.router.command.RoutingContext\n\t(*SubscribeRoutingStatsRequest)(nil),   // 1: v2ray.core.app.router.command.SubscribeRoutingStatsRequest\n\t(*TestRouteRequest)(nil),               // 2: v2ray.core.app.router.command.TestRouteRequest\n\t(*PrincipleTargetInfo)(nil),            // 3: v2ray.core.app.router.command.PrincipleTargetInfo\n\t(*OverrideInfo)(nil),                   // 4: v2ray.core.app.router.command.OverrideInfo\n\t(*BalancerMsg)(nil),                    // 5: v2ray.core.app.router.command.BalancerMsg\n\t(*GetBalancerInfoRequest)(nil),         // 6: v2ray.core.app.router.command.GetBalancerInfoRequest\n\t(*GetBalancerInfoResponse)(nil),        // 7: v2ray.core.app.router.command.GetBalancerInfoResponse\n\t(*OverrideBalancerTargetRequest)(nil),  // 8: v2ray.core.app.router.command.OverrideBalancerTargetRequest\n\t(*OverrideBalancerTargetResponse)(nil), // 9: v2ray.core.app.router.command.OverrideBalancerTargetResponse\n\t(*Config)(nil),                         // 10: v2ray.core.app.router.command.Config\n\tnil,                                    // 11: v2ray.core.app.router.command.RoutingContext.AttributesEntry\n\t(net.Network)(0),                       // 12: v2ray.core.common.net.Network\n}\nvar file_app_router_command_command_proto_depIdxs = []int32{\n\t12, // 0: v2ray.core.app.router.command.RoutingContext.Network:type_name -> v2ray.core.common.net.Network\n\t11, // 1: v2ray.core.app.router.command.RoutingContext.Attributes:type_name -> v2ray.core.app.router.command.RoutingContext.AttributesEntry\n\t0,  // 2: v2ray.core.app.router.command.TestRouteRequest.RoutingContext:type_name -> v2ray.core.app.router.command.RoutingContext\n\t4,  // 3: v2ray.core.app.router.command.BalancerMsg.override:type_name -> v2ray.core.app.router.command.OverrideInfo\n\t3,  // 4: v2ray.core.app.router.command.BalancerMsg.principle_target:type_name -> v2ray.core.app.router.command.PrincipleTargetInfo\n\t5,  // 5: v2ray.core.app.router.command.GetBalancerInfoResponse.balancer:type_name -> v2ray.core.app.router.command.BalancerMsg\n\t1,  // 6: v2ray.core.app.router.command.RoutingService.SubscribeRoutingStats:input_type -> v2ray.core.app.router.command.SubscribeRoutingStatsRequest\n\t2,  // 7: v2ray.core.app.router.command.RoutingService.TestRoute:input_type -> v2ray.core.app.router.command.TestRouteRequest\n\t6,  // 8: v2ray.core.app.router.command.RoutingService.GetBalancerInfo:input_type -> v2ray.core.app.router.command.GetBalancerInfoRequest\n\t8,  // 9: v2ray.core.app.router.command.RoutingService.OverrideBalancerTarget:input_type -> v2ray.core.app.router.command.OverrideBalancerTargetRequest\n\t0,  // 10: v2ray.core.app.router.command.RoutingService.SubscribeRoutingStats:output_type -> v2ray.core.app.router.command.RoutingContext\n\t0,  // 11: v2ray.core.app.router.command.RoutingService.TestRoute:output_type -> v2ray.core.app.router.command.RoutingContext\n\t7,  // 12: v2ray.core.app.router.command.RoutingService.GetBalancerInfo:output_type -> v2ray.core.app.router.command.GetBalancerInfoResponse\n\t9,  // 13: v2ray.core.app.router.command.RoutingService.OverrideBalancerTarget:output_type -> v2ray.core.app.router.command.OverrideBalancerTargetResponse\n\t10, // [10:14] is the sub-list for method output_type\n\t6,  // [6:10] is the sub-list for method input_type\n\t6,  // [6:6] is the sub-list for extension type_name\n\t6,  // [6:6] is the sub-list for extension extendee\n\t0,  // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_app_router_command_command_proto_init() }\nfunc file_app_router_command_command_proto_init() {\n\tif File_app_router_command_command_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: unsafe.Slice(unsafe.StringData(file_app_router_command_command_proto_rawDesc), len(file_app_router_command_command_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   12,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_router_command_command_proto_goTypes,\n\t\tDependencyIndexes: file_app_router_command_command_proto_depIdxs,\n\t\tMessageInfos:      file_app_router_command_command_proto_msgTypes,\n\t}.Build()\n\tFile_app_router_command_command_proto = out.File\n\tfile_app_router_command_command_proto_goTypes = nil\n\tfile_app_router_command_command_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/router/command/command.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.router.command;\noption csharp_namespace = \"V2Ray.Core.App.Router.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/router/command\";\noption java_package = \"com.v2ray.core.app.router.command\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"common/net/network.proto\";\n\n// RoutingContext is the context with information relative to routing process.\n// It conforms to the structure of v2ray.core.features.routing.Context and\n// v2ray.core.features.routing.Route.\nmessage RoutingContext {\n  string InboundTag = 1;\n  v2ray.core.common.net.Network Network = 2;\n  repeated bytes SourceIPs = 3;\n  repeated bytes TargetIPs = 4;\n  uint32 SourcePort = 5;\n  uint32 TargetPort = 6;\n  string TargetDomain = 7;\n  string Protocol = 8;\n  string User = 9;\n  map<string, string> Attributes = 10;\n  repeated string OutboundGroupTags = 11;\n  string OutboundTag = 12;\n}\n\n// SubscribeRoutingStatsRequest subscribes to routing statistics channel if\n// opened by v2ray-core.\n// * FieldSelectors selects a subset of fields in routing statistics to return.\n// Valid selectors:\n//  - inbound: Selects connection's inbound tag.\n//  - network: Selects connection's network.\n//  - ip: Equivalent as \"ip_source\" and \"ip_target\", selects both source and\n//  target IP.\n//  - port: Equivalent as \"port_source\" and \"port_target\", selects both source\n//  and target port.\n//  - domain: Selects target domain.\n//  - protocol: Select connection's protocol.\n//  - user: Select connection's inbound user email.\n//  - attributes: Select connection's additional attributes.\n//  - outbound: Equivalent as \"outbound\" and \"outbound_group\", select both\n//  outbound tag and outbound group tags.\n// * If FieldSelectors is left empty, all fields will be returned.\nmessage SubscribeRoutingStatsRequest {\n  repeated string FieldSelectors = 1;\n}\n\n// TestRouteRequest manually tests a routing result according to the routing\n// context message.\n// * RoutingContext is the routing message without outbound information.\n// * FieldSelectors selects the fields to return in the routing result. All\n// fields are returned if left empty.\n// * PublishResult broadcasts the routing result to routing statistics channel\n// if set true.\nmessage TestRouteRequest {\n  RoutingContext RoutingContext = 1;\n  repeated string FieldSelectors = 2;\n  bool PublishResult = 3;\n}\n\nmessage PrincipleTargetInfo {\n  repeated string tag = 1;\n}\n\nmessage OverrideInfo {\n  string target = 2;\n}\n\nmessage BalancerMsg {\n  OverrideInfo override = 5;\n  PrincipleTargetInfo principle_target = 6;\n}\n\nmessage GetBalancerInfoRequest {\n  string tag = 1;\n}\n\nmessage GetBalancerInfoResponse {\n  BalancerMsg balancer = 1;\n}\n\nmessage OverrideBalancerTargetRequest {\n  string balancerTag = 1;\n  string target = 2;\n}\n\nmessage OverrideBalancerTargetResponse {}\n\nservice RoutingService {\n  rpc SubscribeRoutingStats(SubscribeRoutingStatsRequest)\n      returns (stream RoutingContext) {}\n  rpc TestRoute(TestRouteRequest) returns (RoutingContext) {}\n\n  rpc GetBalancerInfo(GetBalancerInfoRequest) returns (GetBalancerInfoResponse){}\n  rpc OverrideBalancerTarget(OverrideBalancerTargetRequest) returns (OverrideBalancerTargetResponse) {}\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"router\";\n}\n"
  },
  {
    "path": "app/router/command/command_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tRoutingService_SubscribeRoutingStats_FullMethodName  = \"/v2ray.core.app.router.command.RoutingService/SubscribeRoutingStats\"\n\tRoutingService_TestRoute_FullMethodName              = \"/v2ray.core.app.router.command.RoutingService/TestRoute\"\n\tRoutingService_GetBalancerInfo_FullMethodName        = \"/v2ray.core.app.router.command.RoutingService/GetBalancerInfo\"\n\tRoutingService_OverrideBalancerTarget_FullMethodName = \"/v2ray.core.app.router.command.RoutingService/OverrideBalancerTarget\"\n)\n\n// RoutingServiceClient is the client API for RoutingService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype RoutingServiceClient interface {\n\tSubscribeRoutingStats(ctx context.Context, in *SubscribeRoutingStatsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[RoutingContext], error)\n\tTestRoute(ctx context.Context, in *TestRouteRequest, opts ...grpc.CallOption) (*RoutingContext, error)\n\tGetBalancerInfo(ctx context.Context, in *GetBalancerInfoRequest, opts ...grpc.CallOption) (*GetBalancerInfoResponse, error)\n\tOverrideBalancerTarget(ctx context.Context, in *OverrideBalancerTargetRequest, opts ...grpc.CallOption) (*OverrideBalancerTargetResponse, error)\n}\n\ntype routingServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewRoutingServiceClient(cc grpc.ClientConnInterface) RoutingServiceClient {\n\treturn &routingServiceClient{cc}\n}\n\nfunc (c *routingServiceClient) SubscribeRoutingStats(ctx context.Context, in *SubscribeRoutingStatsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[RoutingContext], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &RoutingService_ServiceDesc.Streams[0], RoutingService_SubscribeRoutingStats_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[SubscribeRoutingStatsRequest, RoutingContext]{ClientStream: stream}\n\tif err := x.ClientStream.SendMsg(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := x.ClientStream.CloseSend(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype RoutingService_SubscribeRoutingStatsClient = grpc.ServerStreamingClient[RoutingContext]\n\nfunc (c *routingServiceClient) TestRoute(ctx context.Context, in *TestRouteRequest, opts ...grpc.CallOption) (*RoutingContext, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(RoutingContext)\n\terr := c.cc.Invoke(ctx, RoutingService_TestRoute_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *routingServiceClient) GetBalancerInfo(ctx context.Context, in *GetBalancerInfoRequest, opts ...grpc.CallOption) (*GetBalancerInfoResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(GetBalancerInfoResponse)\n\terr := c.cc.Invoke(ctx, RoutingService_GetBalancerInfo_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *routingServiceClient) OverrideBalancerTarget(ctx context.Context, in *OverrideBalancerTargetRequest, opts ...grpc.CallOption) (*OverrideBalancerTargetResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(OverrideBalancerTargetResponse)\n\terr := c.cc.Invoke(ctx, RoutingService_OverrideBalancerTarget_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// RoutingServiceServer is the server API for RoutingService service.\n// All implementations must embed UnimplementedRoutingServiceServer\n// for forward compatibility.\ntype RoutingServiceServer interface {\n\tSubscribeRoutingStats(*SubscribeRoutingStatsRequest, grpc.ServerStreamingServer[RoutingContext]) error\n\tTestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error)\n\tGetBalancerInfo(context.Context, *GetBalancerInfoRequest) (*GetBalancerInfoResponse, error)\n\tOverrideBalancerTarget(context.Context, *OverrideBalancerTargetRequest) (*OverrideBalancerTargetResponse, error)\n\tmustEmbedUnimplementedRoutingServiceServer()\n}\n\n// UnimplementedRoutingServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedRoutingServiceServer struct{}\n\nfunc (UnimplementedRoutingServiceServer) SubscribeRoutingStats(*SubscribeRoutingStatsRequest, grpc.ServerStreamingServer[RoutingContext]) error {\n\treturn status.Errorf(codes.Unimplemented, \"method SubscribeRoutingStats not implemented\")\n}\nfunc (UnimplementedRoutingServiceServer) TestRoute(context.Context, *TestRouteRequest) (*RoutingContext, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method TestRoute not implemented\")\n}\nfunc (UnimplementedRoutingServiceServer) GetBalancerInfo(context.Context, *GetBalancerInfoRequest) (*GetBalancerInfoResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method GetBalancerInfo not implemented\")\n}\nfunc (UnimplementedRoutingServiceServer) OverrideBalancerTarget(context.Context, *OverrideBalancerTargetRequest) (*OverrideBalancerTargetResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method OverrideBalancerTarget not implemented\")\n}\nfunc (UnimplementedRoutingServiceServer) mustEmbedUnimplementedRoutingServiceServer() {}\nfunc (UnimplementedRoutingServiceServer) testEmbeddedByValue()                        {}\n\n// UnsafeRoutingServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to RoutingServiceServer will\n// result in compilation errors.\ntype UnsafeRoutingServiceServer interface {\n\tmustEmbedUnimplementedRoutingServiceServer()\n}\n\nfunc RegisterRoutingServiceServer(s grpc.ServiceRegistrar, srv RoutingServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedRoutingServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&RoutingService_ServiceDesc, srv)\n}\n\nfunc _RoutingService_SubscribeRoutingStats_Handler(srv interface{}, stream grpc.ServerStream) error {\n\tm := new(SubscribeRoutingStatsRequest)\n\tif err := stream.RecvMsg(m); err != nil {\n\t\treturn err\n\t}\n\treturn srv.(RoutingServiceServer).SubscribeRoutingStats(m, &grpc.GenericServerStream[SubscribeRoutingStatsRequest, RoutingContext]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype RoutingService_SubscribeRoutingStatsServer = grpc.ServerStreamingServer[RoutingContext]\n\nfunc _RoutingService_TestRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(TestRouteRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RoutingServiceServer).TestRoute(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: RoutingService_TestRoute_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RoutingServiceServer).TestRoute(ctx, req.(*TestRouteRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _RoutingService_GetBalancerInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetBalancerInfoRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RoutingServiceServer).GetBalancerInfo(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: RoutingService_GetBalancerInfo_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RoutingServiceServer).GetBalancerInfo(ctx, req.(*GetBalancerInfoRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _RoutingService_OverrideBalancerTarget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(OverrideBalancerTargetRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RoutingServiceServer).OverrideBalancerTarget(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: RoutingService_OverrideBalancerTarget_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RoutingServiceServer).OverrideBalancerTarget(ctx, req.(*OverrideBalancerTargetRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// RoutingService_ServiceDesc is the grpc.ServiceDesc for RoutingService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar RoutingService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.router.command.RoutingService\",\n\tHandlerType: (*RoutingServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"TestRoute\",\n\t\t\tHandler:    _RoutingService_TestRoute_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetBalancerInfo\",\n\t\t\tHandler:    _RoutingService_GetBalancerInfo_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"OverrideBalancerTarget\",\n\t\t\tHandler:    _RoutingService_OverrideBalancerTarget_Handler,\n\t\t},\n\t},\n\tStreams: []grpc.StreamDesc{\n\t\t{\n\t\t\tStreamName:    \"SubscribeRoutingStats\",\n\t\t\tHandler:       _RoutingService_SubscribeRoutingStats_Handler,\n\t\t\tServerStreams: true,\n\t\t},\n\t},\n\tMetadata: \"app/router/command/command.proto\",\n}\n"
  },
  {
    "path": "app/router/command/command_test.go",
    "content": "package command_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/mock/gomock\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/test/bufconn\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t. \"github.com/v2fly/v2ray-core/v5/app/router/command\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/mocks\"\n)\n\nfunc TestServiceSubscribeRoutingStats(t *testing.T) {\n\tc := stats.NewChannel(&stats.ChannelConfig{\n\t\tSubscriberLimit: 1,\n\t\tBufferSize:      0,\n\t\tBlocking:        true,\n\t})\n\tcommon.Must(c.Start())\n\tdefer c.Close()\n\n\tlis := bufconn.Listen(1024 * 1024)\n\tbufDialer := func(context.Context, string) (net.Conn, error) {\n\t\treturn lis.Dial()\n\t}\n\n\ttestCases := []*RoutingContext{\n\t\t{InboundTag: \"in\", OutboundTag: \"out\"},\n\t\t{TargetIPs: [][]byte{{1, 2, 3, 4}}, TargetPort: 8080, OutboundTag: \"out\"},\n\t\t{TargetDomain: \"example.com\", TargetPort: 443, OutboundTag: \"out\"},\n\t\t{SourcePort: 9999, TargetPort: 9999, OutboundTag: \"out\"},\n\t\t{Network: net.Network_UDP, OutboundGroupTags: []string{\"outergroup\", \"innergroup\"}, OutboundTag: \"out\"},\n\t\t{Protocol: \"bittorrent\", OutboundTag: \"blocked\"},\n\t\t{User: \"example@v2fly.org\", OutboundTag: \"out\"},\n\t\t{SourceIPs: [][]byte{{127, 0, 0, 1}}, Attributes: map[string]string{\"attr\": \"value\"}, OutboundTag: \"out\"},\n\t}\n\terrCh := make(chan error)\n\tnextPub := make(chan struct{})\n\n\t// Server goroutine\n\tgo func() {\n\t\tserver := grpc.NewServer()\n\t\tRegisterRoutingServiceServer(server, NewRoutingServer(nil, c))\n\t\terrCh <- server.Serve(lis)\n\t}()\n\n\t// Publisher goroutine\n\tgo func() {\n\t\tpublishTestCases := func() error {\n\t\t\tctx, cancel := context.WithTimeout(context.Background(), time.Second)\n\t\t\tdefer cancel()\n\t\t\tfor { // Wait until there's one subscriber in routing stats channel\n\t\t\t\tif len(c.Subscribers()) > 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif ctx.Err() != nil {\n\t\t\t\t\treturn ctx.Err()\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor _, tc := range testCases {\n\t\t\t\tc.Publish(context.Background(), AsRoutingRoute(tc))\n\t\t\t\ttime.Sleep(time.Millisecond)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := publishTestCases(); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\n\t\t// Wait for next round of publishing\n\t\t<-nextPub\n\n\t\tif err := publishTestCases(); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t}()\n\n\t// Client goroutine\n\tgo func() {\n\t\tdefer lis.Close()\n\t\tconn, err := grpc.DialContext(\n\t\t\tcontext.Background(),\n\t\t\t\"bufnet\",\n\t\t\tgrpc.WithContextDialer(bufDialer),\n\t\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t\t)\n\t\tif err != nil {\n\t\t\terrCh <- err\n\t\t\treturn\n\t\t}\n\t\tdefer conn.Close()\n\t\tclient := NewRoutingServiceClient(conn)\n\n\t\t// Test retrieving all fields\n\t\ttestRetrievingAllFields := func() error {\n\t\t\tstreamCtx, streamClose := context.WithCancel(context.Background())\n\n\t\t\t// Test the unsubscription of stream works well\n\t\t\tdefer func() {\n\t\t\t\tstreamClose()\n\t\t\t\ttimeOutCtx, timeout := context.WithTimeout(context.Background(), time.Second)\n\t\t\t\tdefer timeout()\n\t\t\t\tfor { // Wait until there's no subscriber in routing stats channel\n\t\t\t\t\tif len(c.Subscribers()) == 0 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif timeOutCtx.Err() != nil {\n\t\t\t\t\t\tt.Error(\"unexpected subscribers not decreased in channel\", timeOutCtx.Err())\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tstream, err := client.SubscribeRoutingStats(streamCtx, &SubscribeRoutingStatsRequest{})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tfor _, tc := range testCases {\n\t\t\t\tmsg, err := stream.Recv()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif r := cmp.Diff(msg, tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != \"\" {\n\t\t\t\t\tt.Error(r)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Test that double subscription will fail\n\t\t\terrStream, err := client.SubscribeRoutingStats(context.Background(), &SubscribeRoutingStatsRequest{\n\t\t\t\tFieldSelectors: []string{\"ip\", \"port\", \"domain\", \"outbound\"},\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 := errStream.Recv(); err == nil {\n\t\t\t\tt.Error(\"unexpected successful subscription\")\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\n\t\t// Test retrieving only a subset of fields\n\t\ttestRetrievingSubsetOfFields := func() error {\n\t\t\tstreamCtx, streamClose := context.WithCancel(context.Background())\n\t\t\tdefer streamClose()\n\t\t\tstream, err := client.SubscribeRoutingStats(streamCtx, &SubscribeRoutingStatsRequest{\n\t\t\t\tFieldSelectors: []string{\"ip\", \"port\", \"domain\", \"outbound\"},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Send nextPub signal to start next round of publishing\n\t\t\tclose(nextPub)\n\n\t\t\tfor _, tc := range testCases {\n\t\t\t\tmsg, err := stream.Recv()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tstat := &RoutingContext{ // Only a subset of stats is retrieved\n\t\t\t\t\tSourceIPs:         tc.SourceIPs,\n\t\t\t\t\tTargetIPs:         tc.TargetIPs,\n\t\t\t\t\tSourcePort:        tc.SourcePort,\n\t\t\t\t\tTargetPort:        tc.TargetPort,\n\t\t\t\t\tTargetDomain:      tc.TargetDomain,\n\t\t\t\t\tOutboundGroupTags: tc.OutboundGroupTags,\n\t\t\t\t\tOutboundTag:       tc.OutboundTag,\n\t\t\t\t}\n\t\t\t\tif r := cmp.Diff(msg, stat, cmpopts.IgnoreUnexported(RoutingContext{})); r != \"\" {\n\t\t\t\t\tt.Error(r)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := testRetrievingAllFields(); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t\tif err := testRetrievingSubsetOfFields(); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t\terrCh <- nil // Client passed all tests successfully\n\t}()\n\n\t// Wait for goroutines to complete\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tt.Fatal(\"Test timeout after 2s\")\n\tcase err := <-errCh:\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc TestSerivceTestRoute(t *testing.T) {\n\tc := stats.NewChannel(&stats.ChannelConfig{\n\t\tSubscriberLimit: 1,\n\t\tBufferSize:      16,\n\t\tBlocking:        true,\n\t})\n\tcommon.Must(c.Start())\n\tdefer c.Close()\n\n\tr := new(router.Router)\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\tcommon.Must(r.Init(context.TODO(), &router.Config{\n\t\tRule: []*router.RoutingRule{\n\t\t\t{\n\t\t\t\tInboundTag: []string{\"in\"},\n\t\t\t\tTargetTag:  &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tProtocol:  []string{\"bittorrent\"},\n\t\t\t\tTargetTag: &router.RoutingRule_Tag{Tag: \"blocked\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tPortList:  &net.PortList{Range: []*net.PortRange{{From: 8080, To: 8080}}},\n\t\t\t\tTargetTag: &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tSourcePortList: &net.PortList{Range: []*net.PortRange{{From: 9999, To: 9999}}},\n\t\t\t\tTargetTag:      &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tDomain:    []*routercommon.Domain{{Type: routercommon.Domain_RootDomain, Value: \"com\"}},\n\t\t\t\tTargetTag: &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tSourceGeoip: []*routercommon.GeoIP{{CountryCode: \"private\", Cidr: []*routercommon.CIDR{{Ip: []byte{127, 0, 0, 0}, Prefix: 8}}}},\n\t\t\t\tTargetTag:   &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tUserEmail: []string{\"example@v2fly.org\"},\n\t\t\t\tTargetTag: &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tNetworks:  []net.Network{net.Network_UDP, net.Network_TCP},\n\t\t\t\tTargetTag: &router.RoutingRule_Tag{Tag: \"out\"},\n\t\t\t},\n\t\t},\n\t}, mocks.NewDNSClient(mockCtl), mocks.NewOutboundManager(mockCtl), nil))\n\n\tlis := bufconn.Listen(1024 * 1024)\n\tbufDialer := func(context.Context, string) (net.Conn, error) {\n\t\treturn lis.Dial()\n\t}\n\n\terrCh := make(chan error)\n\n\t// Server goroutine\n\tgo func() {\n\t\tserver := grpc.NewServer()\n\t\tRegisterRoutingServiceServer(server, NewRoutingServer(r, c))\n\t\terrCh <- server.Serve(lis)\n\t}()\n\n\t// Client goroutine\n\tgo func() {\n\t\tdefer lis.Close()\n\t\tconn, err := grpc.DialContext(\n\t\t\tcontext.Background(),\n\t\t\t\"bufnet\", grpc.WithContextDialer(bufDialer),\n\t\t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),\n\t\t)\n\t\tif err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t\tdefer conn.Close()\n\t\tclient := NewRoutingServiceClient(conn)\n\n\t\ttestCases := []*RoutingContext{\n\t\t\t{InboundTag: \"in\", OutboundTag: \"out\"},\n\t\t\t{TargetIPs: [][]byte{{1, 2, 3, 4}}, TargetPort: 8080, OutboundTag: \"out\"},\n\t\t\t{TargetDomain: \"example.com\", TargetPort: 443, OutboundTag: \"out\"},\n\t\t\t{SourcePort: 9999, TargetPort: 9999, OutboundTag: \"out\"},\n\t\t\t{Network: net.Network_UDP, Protocol: \"bittorrent\", OutboundTag: \"blocked\"},\n\t\t\t{User: \"example@v2fly.org\", OutboundTag: \"out\"},\n\t\t\t{SourceIPs: [][]byte{{127, 0, 0, 1}}, Attributes: map[string]string{\"attr\": \"value\"}, OutboundTag: \"out\"},\n\t\t}\n\n\t\t// Test simple TestRoute\n\t\ttestSimple := func() error {\n\t\t\tfor _, tc := range testCases {\n\t\t\t\troute, err := client.TestRoute(context.Background(), &TestRouteRequest{RoutingContext: tc})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif r := cmp.Diff(route, tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != \"\" {\n\t\t\t\t\tt.Error(r)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\t// Test TestRoute with special options\n\t\ttestOptions := func() error {\n\t\t\tsub, err := c.Subscribe()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfor _, tc := range testCases {\n\t\t\t\troute, err := client.TestRoute(context.Background(), &TestRouteRequest{\n\t\t\t\t\tRoutingContext: tc,\n\t\t\t\t\tFieldSelectors: []string{\"ip\", \"port\", \"domain\", \"outbound\"},\n\t\t\t\t\tPublishResult:  true,\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tstat := &RoutingContext{ // Only a subset of stats is retrieved\n\t\t\t\t\tSourceIPs:         tc.SourceIPs,\n\t\t\t\t\tTargetIPs:         tc.TargetIPs,\n\t\t\t\t\tSourcePort:        tc.SourcePort,\n\t\t\t\t\tTargetPort:        tc.TargetPort,\n\t\t\t\t\tTargetDomain:      tc.TargetDomain,\n\t\t\t\t\tOutboundGroupTags: tc.OutboundGroupTags,\n\t\t\t\t\tOutboundTag:       tc.OutboundTag,\n\t\t\t\t}\n\t\t\t\tif r := cmp.Diff(route, stat, cmpopts.IgnoreUnexported(RoutingContext{})); r != \"\" {\n\t\t\t\t\tt.Error(r)\n\t\t\t\t}\n\t\t\t\tselect { // Check that routing result has been published to statistics channel\n\t\t\t\tcase msg, received := <-sub:\n\t\t\t\t\tif route, ok := msg.(routing.Route); received && ok {\n\t\t\t\t\t\tif r := cmp.Diff(AsProtobufMessage(nil)(route), tc, cmpopts.IgnoreUnexported(RoutingContext{})); r != \"\" {\n\t\t\t\t\t\t\tt.Error(r)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tt.Error(\"unexpected failure in receiving published routing result for testcase\", tc)\n\t\t\t\t\t}\n\t\t\t\tcase <-time.After(100 * time.Millisecond):\n\t\t\t\t\tt.Error(\"unexpected failure in receiving published routing result\", tc)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := testSimple(); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t\tif err := testOptions(); err != nil {\n\t\t\terrCh <- err\n\t\t}\n\t\terrCh <- nil // Client passed all tests successfully\n\t}()\n\n\t// Wait for goroutines to complete\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tt.Fatal(\"Test timeout after 2s\")\n\tcase err := <-errCh:\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/router/command/config.go",
    "content": "package command\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\n// routingContext is an wrapper of protobuf RoutingContext as implementation of routing.Context and routing.Route.\ntype routingContext struct {\n\t*RoutingContext\n}\n\nfunc (c routingContext) GetSourceIPs() []net.IP {\n\treturn mapBytesToIPs(c.RoutingContext.GetSourceIPs())\n}\n\nfunc (c routingContext) GetSourcePort() net.Port {\n\treturn net.Port(c.RoutingContext.GetSourcePort())\n}\n\nfunc (c routingContext) GetTargetIPs() []net.IP {\n\treturn mapBytesToIPs(c.RoutingContext.GetTargetIPs())\n}\n\nfunc (c routingContext) GetTargetPort() net.Port {\n\treturn net.Port(c.RoutingContext.GetTargetPort())\n}\n\n// GetSkipDNSResolve is a mock implementation here to match the interface,\n// SkipDNSResolve is set from dns module, no use if coming from a protobuf object?\n// TODO: please confirm @Vigilans\nfunc (c routingContext) GetSkipDNSResolve() bool {\n\treturn false\n}\n\n// AsRoutingContext converts a protobuf RoutingContext into an implementation of routing.Context.\nfunc AsRoutingContext(r *RoutingContext) routing.Context {\n\treturn routingContext{r}\n}\n\n// AsRoutingRoute converts a protobuf RoutingContext into an implementation of routing.Route.\nfunc AsRoutingRoute(r *RoutingContext) routing.Route {\n\treturn routingContext{r}\n}\n\nvar fieldMap = map[string]func(*RoutingContext, routing.Route){\n\t\"inbound\":        func(s *RoutingContext, r routing.Route) { s.InboundTag = r.GetInboundTag() },\n\t\"network\":        func(s *RoutingContext, r routing.Route) { s.Network = r.GetNetwork() },\n\t\"ip_source\":      func(s *RoutingContext, r routing.Route) { s.SourceIPs = mapIPsToBytes(r.GetSourceIPs()) },\n\t\"ip_target\":      func(s *RoutingContext, r routing.Route) { s.TargetIPs = mapIPsToBytes(r.GetTargetIPs()) },\n\t\"port_source\":    func(s *RoutingContext, r routing.Route) { s.SourcePort = uint32(r.GetSourcePort()) },\n\t\"port_target\":    func(s *RoutingContext, r routing.Route) { s.TargetPort = uint32(r.GetTargetPort()) },\n\t\"domain\":         func(s *RoutingContext, r routing.Route) { s.TargetDomain = r.GetTargetDomain() },\n\t\"protocol\":       func(s *RoutingContext, r routing.Route) { s.Protocol = r.GetProtocol() },\n\t\"user\":           func(s *RoutingContext, r routing.Route) { s.User = r.GetUser() },\n\t\"attributes\":     func(s *RoutingContext, r routing.Route) { s.Attributes = r.GetAttributes() },\n\t\"outbound_group\": func(s *RoutingContext, r routing.Route) { s.OutboundGroupTags = r.GetOutboundGroupTags() },\n\t\"outbound\":       func(s *RoutingContext, r routing.Route) { s.OutboundTag = r.GetOutboundTag() },\n}\n\n// AsProtobufMessage takes selectors of fields and returns a function to convert routing.Route to protobuf RoutingContext.\nfunc AsProtobufMessage(fieldSelectors []string) func(routing.Route) *RoutingContext {\n\tinitializers := []func(*RoutingContext, routing.Route){}\n\tfor field, init := range fieldMap {\n\t\tif len(fieldSelectors) == 0 { // If selectors not set, retrieve all fields\n\t\t\tinitializers = append(initializers, init)\n\t\t\tcontinue\n\t\t}\n\t\tfor _, selector := range fieldSelectors {\n\t\t\tif strings.HasPrefix(field, selector) {\n\t\t\t\tinitializers = append(initializers, init)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn func(ctx routing.Route) *RoutingContext {\n\t\tmessage := new(RoutingContext)\n\t\tfor _, init := range initializers {\n\t\t\tinit(message, ctx)\n\t\t}\n\t\treturn message\n\t}\n}\n\nfunc mapBytesToIPs(bytes [][]byte) []net.IP {\n\tvar ips []net.IP\n\tfor _, rawIP := range bytes {\n\t\tips = append(ips, net.IP(rawIP))\n\t}\n\treturn ips\n}\n\nfunc mapIPsToBytes(ips []net.IP) [][]byte {\n\tvar bytes [][]byte\n\tfor _, ip := range ips {\n\t\tbytes = append(bytes, []byte(ip))\n\t}\n\treturn bytes\n}\n"
  },
  {
    "path": "app/router/command/errors.generated.go",
    "content": "package command\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/router/condition.go",
    "content": "package router\n\nimport (\n\t\"strings\"\n\n\t\"go.starlark.net/starlark\"\n\t\"go.starlark.net/syntax\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\ntype Condition interface {\n\tApply(ctx routing.Context) bool\n}\n\ntype ConditionChan []Condition\n\nfunc NewConditionChan() *ConditionChan {\n\tvar condChan ConditionChan = make([]Condition, 0, 8)\n\treturn &condChan\n}\n\nfunc (v *ConditionChan) Add(cond Condition) *ConditionChan {\n\t*v = append(*v, cond)\n\treturn v\n}\n\n// Apply applies all conditions registered in this chan.\nfunc (v *ConditionChan) Apply(ctx routing.Context) bool {\n\tfor _, cond := range *v {\n\t\tif !cond.Apply(ctx) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (v *ConditionChan) Len() int {\n\treturn len(*v)\n}\n\nvar matcherTypeMap = map[routercommon.Domain_Type]strmatcher.Type{\n\troutercommon.Domain_Plain:      strmatcher.Substr,\n\troutercommon.Domain_Regex:      strmatcher.Regex,\n\troutercommon.Domain_RootDomain: strmatcher.Domain,\n\troutercommon.Domain_Full:       strmatcher.Full,\n}\n\nfunc domainToMatcher(domain *routercommon.Domain) (strmatcher.Matcher, error) {\n\tmatcherType, f := matcherTypeMap[domain.Type]\n\tif !f {\n\t\treturn nil, newError(\"unsupported domain type\", domain.Type)\n\t}\n\n\tmatcher, err := matcherType.New(domain.Value)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create domain matcher\").Base(err)\n\t}\n\n\treturn matcher, nil\n}\n\ntype DomainMatcher struct {\n\tmatcher strmatcher.IndexMatcher\n}\n\nfunc NewDomainMatcher(matcherType string, domains []*routercommon.Domain) (*DomainMatcher, error) {\n\tvar indexMatcher strmatcher.IndexMatcher\n\tswitch matcherType {\n\tcase \"mph\", \"hybrid\":\n\t\tindexMatcher = strmatcher.NewMphIndexMatcher()\n\tcase \"linear\":\n\t\tindexMatcher = strmatcher.NewLinearIndexMatcher()\n\tdefault:\n\t\tindexMatcher = strmatcher.NewLinearIndexMatcher()\n\t}\n\tfor _, domain := range domains {\n\t\tmatcher, err := domainToMatcher(domain)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tindexMatcher.Add(matcher)\n\t}\n\tif err := indexMatcher.Build(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DomainMatcher{matcher: indexMatcher}, nil\n}\n\nfunc (m *DomainMatcher) Match(domain string) bool {\n\treturn m.matcher.MatchAny(domain)\n}\n\n// Apply implements Condition.\nfunc (m *DomainMatcher) Apply(ctx routing.Context) bool {\n\tdomain := ctx.GetTargetDomain()\n\tif len(domain) == 0 {\n\t\treturn false\n\t}\n\treturn m.Match(domain)\n}\n\ntype MultiGeoIPMatcher struct {\n\tmatchers []*GeoIPMatcher\n\tonSource bool\n}\n\nfunc NewMultiGeoIPMatcher(geoips []*routercommon.GeoIP, onSource bool) (*MultiGeoIPMatcher, error) {\n\tvar matchers []*GeoIPMatcher\n\tfor _, geoip := range geoips {\n\t\tmatcher, err := globalGeoIPContainer.Add(geoip)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmatchers = append(matchers, matcher)\n\t}\n\n\tmatcher := &MultiGeoIPMatcher{\n\t\tmatchers: matchers,\n\t\tonSource: onSource,\n\t}\n\n\treturn matcher, nil\n}\n\n// Apply implements Condition.\nfunc (m *MultiGeoIPMatcher) Apply(ctx routing.Context) bool {\n\tvar ips []net.IP\n\tif m.onSource {\n\t\tips = ctx.GetSourceIPs()\n\t} else {\n\t\tips = ctx.GetTargetIPs()\n\t}\n\tfor _, ip := range ips {\n\t\tfor _, matcher := range m.matchers {\n\t\t\tif matcher.Match(ip) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\ntype PortMatcher struct {\n\tport     net.MemoryPortList\n\tonSource bool\n}\n\n// NewPortMatcher creates a new port matcher that can match source or destination port\nfunc NewPortMatcher(list *net.PortList, onSource bool) *PortMatcher {\n\treturn &PortMatcher{\n\t\tport:     net.PortListFromProto(list),\n\t\tonSource: onSource,\n\t}\n}\n\n// Apply implements Condition.\nfunc (v *PortMatcher) Apply(ctx routing.Context) bool {\n\tif v.onSource {\n\t\treturn v.port.Contains(ctx.GetSourcePort())\n\t}\n\treturn v.port.Contains(ctx.GetTargetPort())\n}\n\ntype NetworkMatcher struct {\n\tlist [8]bool\n}\n\nfunc NewNetworkMatcher(network []net.Network) NetworkMatcher {\n\tvar matcher NetworkMatcher\n\tfor _, n := range network {\n\t\tmatcher.list[int(n)] = true\n\t}\n\treturn matcher\n}\n\n// Apply implements Condition.\nfunc (v NetworkMatcher) Apply(ctx routing.Context) bool {\n\treturn v.list[int(ctx.GetNetwork())]\n}\n\ntype UserMatcher struct {\n\tuser []string\n}\n\nfunc NewUserMatcher(users []string) *UserMatcher {\n\tusersCopy := make([]string, 0, len(users))\n\tfor _, user := range users {\n\t\tif len(user) > 0 {\n\t\t\tusersCopy = append(usersCopy, user)\n\t\t}\n\t}\n\treturn &UserMatcher{\n\t\tuser: usersCopy,\n\t}\n}\n\n// Apply implements Condition.\nfunc (v *UserMatcher) Apply(ctx routing.Context) bool {\n\tuser := ctx.GetUser()\n\tif len(user) == 0 {\n\t\treturn false\n\t}\n\tfor _, u := range v.user {\n\t\tif u == user {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype InboundTagMatcher struct {\n\ttags []string\n}\n\nfunc NewInboundTagMatcher(tags []string) *InboundTagMatcher {\n\ttagsCopy := make([]string, 0, len(tags))\n\tfor _, tag := range tags {\n\t\tif len(tag) > 0 {\n\t\t\ttagsCopy = append(tagsCopy, tag)\n\t\t}\n\t}\n\treturn &InboundTagMatcher{\n\t\ttags: tagsCopy,\n\t}\n}\n\n// Apply implements Condition.\nfunc (v *InboundTagMatcher) Apply(ctx routing.Context) bool {\n\ttag := ctx.GetInboundTag()\n\tif len(tag) == 0 {\n\t\treturn false\n\t}\n\tfor _, t := range v.tags {\n\t\tif t == tag {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype ProtocolMatcher struct {\n\tprotocols []string\n}\n\nfunc NewProtocolMatcher(protocols []string) *ProtocolMatcher {\n\tpCopy := make([]string, 0, len(protocols))\n\n\tfor _, p := range protocols {\n\t\tif len(p) > 0 {\n\t\t\tpCopy = append(pCopy, p)\n\t\t}\n\t}\n\n\treturn &ProtocolMatcher{\n\t\tprotocols: pCopy,\n\t}\n}\n\n// Apply implements Condition.\nfunc (m *ProtocolMatcher) Apply(ctx routing.Context) bool {\n\tprotocol := ctx.GetProtocol()\n\tif len(protocol) == 0 {\n\t\treturn false\n\t}\n\tfor _, p := range m.protocols {\n\t\tif strings.HasPrefix(protocol, p) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype AttributeMatcher struct {\n\tprogram *starlark.Program\n}\n\nfunc NewAttributeMatcher(code string) (*AttributeMatcher, error) {\n\tstarFile, err := syntax.Parse(\"attr.star\", \"satisfied=(\"+code+\")\", 0)\n\tif err != nil {\n\t\treturn nil, newError(\"attr rule\").Base(err)\n\t}\n\tp, err := starlark.FileProgram(starFile, func(name string) bool {\n\t\treturn name == \"attrs\"\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &AttributeMatcher{\n\t\tprogram: p,\n\t}, nil\n}\n\n// Match implements attributes matching.\nfunc (m *AttributeMatcher) Match(attrs map[string]string) bool {\n\tattrsDict := new(starlark.Dict)\n\tfor key, value := range attrs {\n\t\tattrsDict.SetKey(starlark.String(key), starlark.String(value))\n\t}\n\n\tpredefined := make(starlark.StringDict)\n\tpredefined[\"attrs\"] = attrsDict\n\n\tthread := &starlark.Thread{\n\t\tName: \"matcher\",\n\t}\n\tresults, err := m.program.Init(thread, predefined)\n\tif err != nil {\n\t\tnewError(\"attr matcher\").Base(err).WriteToLog()\n\t}\n\tsatisfied := results[\"satisfied\"]\n\treturn satisfied != nil && bool(satisfied.Truth())\n}\n\n// Apply implements Condition.\nfunc (m *AttributeMatcher) Apply(ctx routing.Context) bool {\n\tattributes := ctx.GetAttributes()\n\tif attributes == nil {\n\t\treturn false\n\t}\n\treturn m.Match(attributes)\n}\n"
  },
  {
    "path": "app/router/condition_geoip.go",
    "content": "package router\n\nimport (\n\t\"net/netip\"\n\n\t\"go4.org/netipx\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype GeoIPMatcher struct {\n\tcountryCode  string\n\treverseMatch bool\n\tip4          *netipx.IPSet\n\tip6          *netipx.IPSet\n}\n\nfunc (m *GeoIPMatcher) Init(cidrs []*routercommon.CIDR) error {\n\tvar builder4, builder6 netipx.IPSetBuilder\n\tfor _, cidr := range cidrs {\n\t\tnetaddrIP, ok := netip.AddrFromSlice(cidr.GetIp())\n\t\tif !ok {\n\t\t\treturn newError(\"invalid IP address \", cidr)\n\t\t}\n\t\tnetaddrIP = netaddrIP.Unmap()\n\t\tipPrefix := netip.PrefixFrom(netaddrIP, int(cidr.GetPrefix()))\n\n\t\tswitch {\n\t\tcase netaddrIP.Is4():\n\t\t\tbuilder4.AddPrefix(ipPrefix)\n\t\tcase netaddrIP.Is6():\n\t\t\tbuilder6.AddPrefix(ipPrefix)\n\t\t}\n\t}\n\n\tvar err error\n\tm.ip4, err = builder4.IPSet()\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.ip6, err = builder6.IPSet()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (m *GeoIPMatcher) SetReverseMatch(isReverseMatch bool) {\n\tm.reverseMatch = isReverseMatch\n}\n\nfunc (m *GeoIPMatcher) match4(ip net.IP) bool {\n\tnip, ok := netipx.FromStdIP(ip)\n\tif !ok {\n\t\treturn false\n\t}\n\treturn m.ip4.Contains(nip)\n}\n\nfunc (m *GeoIPMatcher) match6(ip net.IP) bool {\n\tnip, ok := netipx.FromStdIP(ip)\n\tif !ok {\n\t\treturn false\n\t}\n\treturn m.ip6.Contains(nip)\n}\n\n// Match returns true if the given ip is included by the GeoIP.\nfunc (m *GeoIPMatcher) Match(ip net.IP) bool {\n\tisMatched := false\n\tswitch len(ip) {\n\tcase net.IPv4len:\n\t\tisMatched = m.match4(ip)\n\tcase net.IPv6len:\n\t\tisMatched = m.match6(ip)\n\t}\n\tif m.reverseMatch {\n\t\treturn !isMatched\n\t}\n\treturn isMatched\n}\n\n// GeoIPMatcherContainer is a container for GeoIPMatchers. It keeps unique copies of GeoIPMatcher by country code.\ntype GeoIPMatcherContainer struct {\n\tmatchers []*GeoIPMatcher\n}\n\n// Add adds a new GeoIP set into the container.\n// If the country code of GeoIP is not empty, GeoIPMatcherContainer will try to find an existing one, instead of adding a new one.\nfunc (c *GeoIPMatcherContainer) Add(geoip *routercommon.GeoIP) (*GeoIPMatcher, error) {\n\tif geoip.CountryCode != \"\" {\n\t\tfor _, m := range c.matchers {\n\t\t\tif m.countryCode == geoip.CountryCode && m.reverseMatch == geoip.InverseMatch {\n\t\t\t\treturn m, nil\n\t\t\t}\n\t\t}\n\t}\n\n\tm := &GeoIPMatcher{\n\t\tcountryCode:  geoip.CountryCode,\n\t\treverseMatch: geoip.InverseMatch,\n\t}\n\tif err := m.Init(geoip.Cidr); err != nil {\n\t\treturn nil, err\n\t}\n\tif geoip.CountryCode != \"\" {\n\t\tc.matchers = append(c.matchers, m)\n\t}\n\treturn m, nil\n}\n\nvar globalGeoIPContainer GeoIPMatcherContainer\n"
  },
  {
    "path": "app/router/condition_geoip_test.go",
    "content": "package router_test\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n)\n\nfunc init() {\n\tconst geoipURL = \"https://github.com/v2fly/geoip/releases/download/202507050144/geoip.dat\"\n\n\twd, err := os.Getwd()\n\tcommon.Must(err)\n\n\ttempPath := filepath.Join(wd, \"..\", \"..\", \"testing\", \"temp\")\n\tgeoipPath := filepath.Join(tempPath, \"geoip-202507050144.dat\")\n\n\tos.Setenv(\"v2ray.location.asset\", tempPath)\n\n\tif _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeoipBytes, err := common.FetchHTTPContent(geoipURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geoipPath, geoipBytes))\n\t}\n}\n\nfunc TestGeoIPMatcherContainer(t *testing.T) {\n\tcontainer := &router.GeoIPMatcherContainer{}\n\n\tm1, err := container.Add(&routercommon.GeoIP{\n\t\tCountryCode: \"CN\",\n\t})\n\tcommon.Must(err)\n\n\tm2, err := container.Add(&routercommon.GeoIP{\n\t\tCountryCode: \"US\",\n\t})\n\tcommon.Must(err)\n\n\tm3, err := container.Add(&routercommon.GeoIP{\n\t\tCountryCode: \"CN\",\n\t})\n\tcommon.Must(err)\n\n\tif m1 != m3 {\n\t\tt.Error(\"expect same matcher for same geoip, but not\")\n\t}\n\n\tif m1 == m2 {\n\t\tt.Error(\"expect different matcher for different geoip, but actually same\")\n\t}\n}\n\nfunc TestGeoIPMatcher(t *testing.T) {\n\tcidrList := []*routercommon.CIDR{\n\t\t{Ip: []byte{0, 0, 0, 0}, Prefix: 8},\n\t\t{Ip: []byte{10, 0, 0, 0}, Prefix: 8},\n\t\t{Ip: []byte{100, 64, 0, 0}, Prefix: 10},\n\t\t{Ip: []byte{127, 0, 0, 0}, Prefix: 8},\n\t\t{Ip: []byte{169, 254, 0, 0}, Prefix: 16},\n\t\t{Ip: []byte{172, 16, 0, 0}, Prefix: 12},\n\t\t{Ip: []byte{192, 0, 0, 0}, Prefix: 24},\n\t\t{Ip: []byte{192, 0, 2, 0}, Prefix: 24},\n\t\t{Ip: []byte{192, 168, 0, 0}, Prefix: 16},\n\t\t{Ip: []byte{192, 18, 0, 0}, Prefix: 15},\n\t\t{Ip: []byte{198, 51, 100, 0}, Prefix: 24},\n\t\t{Ip: []byte{203, 0, 113, 0}, Prefix: 24},\n\t\t{Ip: []byte{8, 8, 8, 8}, Prefix: 32},\n\t\t{Ip: []byte{91, 108, 4, 0}, Prefix: 16},\n\t}\n\n\tmatcher := &router.GeoIPMatcher{}\n\tcommon.Must(matcher.Init(cidrList))\n\n\ttestCases := []struct {\n\t\tInput  string\n\t\tOutput bool\n\t}{\n\t\t{\n\t\t\tInput:  \"192.168.1.1\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tInput:  \"192.0.0.0\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tInput:  \"192.0.1.0\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tInput:  \"0.1.0.0\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tInput:  \"1.0.0.1\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tInput:  \"8.8.8.7\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tInput:  \"8.8.8.8\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tInput:  \"2001:cdba::3257:9652\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tInput:  \"91.108.255.254\",\n\t\t\tOutput: true,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tip := net.ParseAddress(testCase.Input).IP()\n\t\tactual := matcher.Match(ip)\n\t\tif actual != testCase.Output {\n\t\t\tt.Error(\"expect input\", testCase.Input, \"to be\", testCase.Output, \", but actually\", actual)\n\t\t}\n\t}\n}\n\nfunc TestGeoIPReverseMatcher(t *testing.T) {\n\tcidrList := []*routercommon.CIDR{\n\t\t{Ip: []byte{8, 8, 8, 8}, Prefix: 32},\n\t\t{Ip: []byte{91, 108, 4, 0}, Prefix: 16},\n\t}\n\tmatcher := &router.GeoIPMatcher{}\n\tmatcher.SetReverseMatch(true) // Reverse match\n\tcommon.Must(matcher.Init(cidrList))\n\n\ttestCases := []struct {\n\t\tInput  string\n\t\tOutput bool\n\t}{\n\t\t{\n\t\t\tInput:  \"8.8.8.8\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tInput:  \"2001:cdba::3257:9652\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tInput:  \"91.108.255.254\",\n\t\t\tOutput: false,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tip := net.ParseAddress(testCase.Input).IP()\n\t\tactual := matcher.Match(ip)\n\t\tif actual != testCase.Output {\n\t\t\tt.Error(\"expect input\", testCase.Input, \"to be\", testCase.Output, \", but actually\", actual)\n\t\t}\n\t}\n}\n\nfunc TestGeoIPMatcher4CN(t *testing.T) {\n\tips, err := loadGeoIP(\"CN\")\n\tcommon.Must(err)\n\n\tmatcher := &router.GeoIPMatcher{}\n\tcommon.Must(matcher.Init(ips))\n\n\tif matcher.Match([]byte{8, 8, 8, 8}) {\n\t\tt.Error(\"expect CN geoip doesn't contain 8.8.8.8, but actually does\")\n\t}\n}\n\nfunc TestGeoIPMatcher6US(t *testing.T) {\n\tips, err := loadGeoIP(\"US\")\n\tcommon.Must(err)\n\n\tmatcher := &router.GeoIPMatcher{}\n\tcommon.Must(matcher.Init(ips))\n\n\tif !matcher.Match(net.ParseAddress(\"2001:4860:4860::8888\").IP()) {\n\t\tt.Error(\"expect US geoip contain 2001:4860:4860::8888, but actually not\")\n\t}\n}\n\nfunc loadGeoIP(country string) ([]*routercommon.CIDR, error) {\n\tgeoipBytes, err := filesystem.ReadAsset(\"geoip-202507050144.dat\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar geoipList routercommon.GeoIPList\n\tif err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, geoip := range geoipList.Entry {\n\t\tif strings.EqualFold(geoip.CountryCode, country) {\n\t\t\treturn geoip.Cidr, nil\n\t\t}\n\t}\n\n\tpanic(\"country not found: \" + country)\n}\n\nfunc BenchmarkGeoIPMatcher4CN(b *testing.B) {\n\tips, err := loadGeoIP(\"CN\")\n\tcommon.Must(err)\n\n\tmatcher := &router.GeoIPMatcher{}\n\tcommon.Must(matcher.Init(ips))\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = matcher.Match([]byte{8, 8, 8, 8})\n\t}\n}\n\nfunc BenchmarkGeoIPMatcher6US(b *testing.B) {\n\tips, err := loadGeoIP(\"US\")\n\tcommon.Must(err)\n\n\tmatcher := &router.GeoIPMatcher{}\n\tcommon.Must(matcher.Init(ips))\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = matcher.Match(net.ParseAddress(\"2001:4860:4860::8888\").IP())\n\t}\n}\n"
  },
  {
    "path": "app/router/condition_test.go",
    "content": "package router_test\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\trouting_session \"github.com/v2fly/v2ray-core/v5/features/routing/session\"\n)\n\nfunc init() {\n\tconst (\n\t\tgeoipURL   = \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat\"\n\t\tgeositeURL = \"https://raw.githubusercontent.com/v2fly/domain-list-community/release/dlc.dat\"\n\t)\n\n\twd, err := os.Getwd()\n\tcommon.Must(err)\n\n\ttempPath := filepath.Join(wd, \"..\", \"..\", \"testing\", \"temp\")\n\tgeoipPath := filepath.Join(tempPath, \"geoip.dat\")\n\tgeositePath := filepath.Join(tempPath, \"geosite.dat\")\n\n\tos.Setenv(\"v2ray.location.asset\", tempPath)\n\n\tif _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeoipBytes, err := common.FetchHTTPContent(geoipURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geoipPath, geoipBytes))\n\t}\n\tif _, err := os.Stat(geositePath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeositeBytes, err := common.FetchHTTPContent(geositeURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geositePath, geositeBytes))\n\t}\n}\n\nfunc withBackground() routing.Context {\n\treturn &routing_session.Context{}\n}\n\nfunc withOutbound(outbound *session.Outbound) routing.Context {\n\treturn &routing_session.Context{Outbound: outbound}\n}\n\nfunc withInbound(inbound *session.Inbound) routing.Context {\n\treturn &routing_session.Context{Inbound: inbound}\n}\n\nfunc withContent(content *session.Content) routing.Context {\n\treturn &routing_session.Context{Content: content}\n}\n\nfunc TestRoutingRule(t *testing.T) {\n\ttype ruleTest struct {\n\t\tinput  routing.Context\n\t\toutput bool\n\t}\n\n\tcases := []struct {\n\t\trule *router.RoutingRule\n\t\ttest []ruleTest\n\t}{\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t{\n\t\t\t\t\t\tValue: \"v2fly.org\",\n\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tValue: \"google.com\",\n\t\t\t\t\t\tType:  routercommon.Domain_RootDomain,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tValue: \"^facebook\\\\.com$\",\n\t\t\t\t\t\tType:  routercommon.Domain_Regex,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"www.v2fly.org.www\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2ray.co\"), 80)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"www.google.com\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"facebook.com\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"www.facebook.com\"), 80)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withBackground(),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     []byte{8, 8, 8, 8},\n\t\t\t\t\t\tPrefix: 32,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     []byte{8, 8, 8, 8},\n\t\t\t\t\t\tPrefix: 32,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     net.ParseAddress(\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\").IP(),\n\t\t\t\t\t\tPrefix: 128,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"8.8.8.8\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"8.8.4.4\"), 80)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withBackground(),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t{\n\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tIp:     []byte{8, 8, 8, 8},\n\t\t\t\t\t\t\t\tPrefix: 32,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tIp:     []byte{8, 8, 8, 8},\n\t\t\t\t\t\t\t\tPrefix: 32,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tIp:     net.ParseAddress(\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\").IP(),\n\t\t\t\t\t\t\t\tPrefix: 128,\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\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"8.8.8.8\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"8.8.4.4\"), 80)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withBackground(),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tSourceCidr: []*routercommon.CIDR{\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     []byte{192, 168, 0, 0},\n\t\t\t\t\t\tPrefix: 16,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Source: net.TCPDestination(net.ParseAddress(\"192.168.0.1\"), 80)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Source: net.TCPDestination(net.ParseAddress(\"10.0.0.1\"), 80)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tUserEmail: []string{\n\t\t\t\t\t\"admin@v2fly.org\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{User: &protocol.MemoryUser{Email: \"admin@v2fly.org\"}}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{User: &protocol.MemoryUser{Email: \"love@v2fly.org\"}}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withBackground(),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tProtocol: []string{\"http\"},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withContent(&session.Content{Protocol: (&http.SniffHeader{}).Protocol()}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tInboundTag: []string{\"test\", \"test1\"},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Tag: \"test\"}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Tag: \"test2\"}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tPortList: &net.PortList{\n\t\t\t\t\tRange: []*net.PortRange{\n\t\t\t\t\t\t{From: 443, To: 443},\n\t\t\t\t\t\t{From: 1000, To: 1100},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 443)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 1100)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 1005)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withOutbound(&session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 53)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tSourcePortList: &net.PortList{\n\t\t\t\t\tRange: []*net.PortRange{\n\t\t\t\t\t\t{From: 123, To: 123},\n\t\t\t\t\t\t{From: 9993, To: 9999},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 123)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 9999)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 9994)}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tinput:  withInbound(&session.Inbound{Source: net.UDPDestination(net.LocalHostIP, 53)}),\n\t\t\t\t\toutput: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\trule: &router.RoutingRule{\n\t\t\t\tProtocol:   []string{\"http\"},\n\t\t\t\tAttributes: \"attrs[':path'].startswith('/test')\",\n\t\t\t},\n\t\t\ttest: []ruleTest{\n\t\t\t\t{\n\t\t\t\t\tinput:  withContent(&session.Content{Protocol: \"http/1.1\", Attributes: map[string]string{\":path\": \"/test/1\"}}),\n\t\t\t\t\toutput: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range cases {\n\t\tcond, err := test.rule.BuildCondition()\n\t\tcommon.Must(err)\n\n\t\tfor _, subtest := range test.test {\n\t\t\tactual := cond.Apply(subtest.input)\n\t\t\tif actual != subtest.output {\n\t\t\t\tt.Error(\"test case failed: \", subtest.input, \" expected \", subtest.output, \" but got \", actual)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc loadGeoSite(country string) ([]*routercommon.Domain, error) {\n\tgeositeBytes, err := filesystem.ReadAsset(\"geosite.dat\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar geositeList routercommon.GeoSiteList\n\tif err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, site := range geositeList.Entry {\n\t\tif strings.EqualFold(site.CountryCode, country) {\n\t\t\treturn site.Domain, nil\n\t\t}\n\t}\n\n\treturn nil, errors.New(\"country not found: \" + country)\n}\n\nfunc TestChinaSites(t *testing.T) {\n\tdomains, err := loadGeoSite(\"CN\")\n\tcommon.Must(err)\n\n\tmatcher, err := router.NewDomainMatcher(\"linear\", domains)\n\tcommon.Must(err)\n\tmphMatcher, err := router.NewDomainMatcher(\"mph\", domains)\n\tcommon.Must(err)\n\n\ttype TestCase struct {\n\t\tDomain string\n\t\tOutput bool\n\t}\n\ttestCases := []TestCase{\n\t\t{\n\t\t\tDomain: \"163.com\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tDomain: \"163.com\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tDomain: \"164.com\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tDomain: \"164.com\",\n\t\t\tOutput: false,\n\t\t},\n\t}\n\n\tfor i := 0; i < 1024; i++ {\n\t\ttestCases = append(testCases, TestCase{Domain: strconv.Itoa(i) + \".not-exists.com\", Output: false})\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tr1 := matcher.Match(testCase.Domain)\n\t\tr2 := mphMatcher.Match(testCase.Domain)\n\t\tif r1 != testCase.Output {\n\t\t\tt.Error(\"DomainMatcher expected output \", testCase.Output, \" for domain \", testCase.Domain, \" but got \", r1)\n\t\t} else if r2 != testCase.Output {\n\t\t\tt.Error(\"ACDomainMatcher expected output \", testCase.Output, \" for domain \", testCase.Domain, \" but got \", r2)\n\t\t}\n\t}\n}\n\nfunc BenchmarkMphDomainMatcher(b *testing.B) {\n\tdomains, err := loadGeoSite(\"CN\")\n\tcommon.Must(err)\n\n\tmatcher, err := router.NewDomainMatcher(\"mph\", domains)\n\tcommon.Must(err)\n\n\ttype TestCase struct {\n\t\tDomain string\n\t\tOutput bool\n\t}\n\ttestCases := []TestCase{\n\t\t{\n\t\t\tDomain: \"163.com\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tDomain: \"163.com\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tDomain: \"164.com\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tDomain: \"164.com\",\n\t\t\tOutput: false,\n\t\t},\n\t}\n\n\tfor i := 0; i < 1024; i++ {\n\t\ttestCases = append(testCases, TestCase{Domain: strconv.Itoa(i) + \".not-exists.com\", Output: false})\n\t}\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tfor _, testCase := range testCases {\n\t\t\t_ = matcher.Match(testCase.Domain)\n\t\t}\n\t}\n}\n\nfunc BenchmarkDomainMatcher(b *testing.B) {\n\tdomains, err := loadGeoSite(\"CN\")\n\tcommon.Must(err)\n\n\tmatcher, err := router.NewDomainMatcher(\"linear\", domains)\n\tcommon.Must(err)\n\n\ttype TestCase struct {\n\t\tDomain string\n\t\tOutput bool\n\t}\n\ttestCases := []TestCase{\n\t\t{\n\t\t\tDomain: \"163.com\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tDomain: \"163.com\",\n\t\t\tOutput: true,\n\t\t},\n\t\t{\n\t\t\tDomain: \"164.com\",\n\t\t\tOutput: false,\n\t\t},\n\t\t{\n\t\t\tDomain: \"164.com\",\n\t\t\tOutput: false,\n\t\t},\n\t}\n\n\tfor i := 0; i < 1024; i++ {\n\t\ttestCases = append(testCases, TestCase{Domain: strconv.Itoa(i) + \".not-exists.com\", Output: false})\n\t}\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tfor _, testCase := range testCases {\n\t\t\t_ = matcher.Match(testCase.Domain)\n\t\t}\n\t}\n}\n\nfunc BenchmarkMultiGeoIPMatcher(b *testing.B) {\n\tvar geoips []*routercommon.GeoIP\n\n\t{\n\t\tips, err := loadGeoIP(\"CN\")\n\t\tcommon.Must(err)\n\t\tgeoips = append(geoips, &routercommon.GeoIP{\n\t\t\tCountryCode: \"CN\",\n\t\t\tCidr:        ips,\n\t\t})\n\t}\n\n\t{\n\t\tips, err := loadGeoIP(\"JP\")\n\t\tcommon.Must(err)\n\t\tgeoips = append(geoips, &routercommon.GeoIP{\n\t\t\tCountryCode: \"JP\",\n\t\t\tCidr:        ips,\n\t\t})\n\t}\n\n\t{\n\t\tips, err := loadGeoIP(\"CA\")\n\t\tcommon.Must(err)\n\t\tgeoips = append(geoips, &routercommon.GeoIP{\n\t\t\tCountryCode: \"CA\",\n\t\t\tCidr:        ips,\n\t\t})\n\t}\n\n\t{\n\t\tips, err := loadGeoIP(\"US\")\n\t\tcommon.Must(err)\n\t\tgeoips = append(geoips, &routercommon.GeoIP{\n\t\t\tCountryCode: \"US\",\n\t\t\tCidr:        ips,\n\t\t})\n\t}\n\n\tmatcher, err := router.NewMultiGeoIPMatcher(geoips, false)\n\tcommon.Must(err)\n\n\tctx := withOutbound(&session.Outbound{Target: net.TCPDestination(net.ParseAddress(\"8.8.8.8\"), 80)})\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = matcher.Apply(ctx)\n\t}\n}\n"
  },
  {
    "path": "app/router/config.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage router\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/v5cfg\"\n)\n\ntype Rule struct {\n\tTag       string\n\tBalancer  *Balancer\n\tCondition Condition\n}\n\nfunc (r *Rule) GetTag() (string, error) {\n\tif r.Balancer != nil {\n\t\treturn r.Balancer.PickOutbound()\n\t}\n\treturn r.Tag, nil\n}\n\n// Apply checks rule matching of current routing context.\nfunc (r *Rule) Apply(ctx routing.Context) bool {\n\treturn r.Condition.Apply(ctx)\n}\n\nfunc (rr *RoutingRule) BuildCondition() (Condition, error) {\n\tconds := NewConditionChan()\n\n\tif len(rr.Domain) > 0 {\n\t\tcond, err := NewDomainMatcher(rr.DomainMatcher, rr.Domain)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build domain condition\").Base(err)\n\t\t}\n\t\tconds.Add(cond)\n\t}\n\n\tvar geoDomains []*routercommon.Domain\n\tfor _, geo := range rr.GeoDomain {\n\t\tgeoDomains = append(geoDomains, geo.Domain...)\n\t}\n\tif len(geoDomains) > 0 {\n\t\tcond, err := NewDomainMatcher(rr.DomainMatcher, geoDomains)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build geo domain condition\").Base(err)\n\t\t}\n\t\tconds.Add(cond)\n\t}\n\n\tif len(rr.UserEmail) > 0 {\n\t\tconds.Add(NewUserMatcher(rr.UserEmail))\n\t}\n\n\tif len(rr.InboundTag) > 0 {\n\t\tconds.Add(NewInboundTagMatcher(rr.InboundTag))\n\t}\n\n\tif rr.PortList != nil {\n\t\tconds.Add(NewPortMatcher(rr.PortList, false))\n\t} else if rr.PortRange != nil {\n\t\tconds.Add(NewPortMatcher(&net.PortList{Range: []*net.PortRange{rr.PortRange}}, false))\n\t}\n\n\tif rr.SourcePortList != nil {\n\t\tconds.Add(NewPortMatcher(rr.SourcePortList, true))\n\t}\n\n\tif len(rr.Networks) > 0 {\n\t\tconds.Add(NewNetworkMatcher(rr.Networks))\n\t} else if rr.NetworkList != nil {\n\t\tconds.Add(NewNetworkMatcher(rr.NetworkList.Network))\n\t}\n\n\tif len(rr.Geoip) > 0 {\n\t\tcond, err := NewMultiGeoIPMatcher(rr.Geoip, false)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconds.Add(cond)\n\t} else if len(rr.Cidr) > 0 {\n\t\tcond, err := NewMultiGeoIPMatcher([]*routercommon.GeoIP{{Cidr: rr.Cidr}}, false)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconds.Add(cond)\n\t}\n\n\tif len(rr.SourceGeoip) > 0 {\n\t\tcond, err := NewMultiGeoIPMatcher(rr.SourceGeoip, true)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconds.Add(cond)\n\t} else if len(rr.SourceCidr) > 0 {\n\t\tcond, err := NewMultiGeoIPMatcher([]*routercommon.GeoIP{{Cidr: rr.SourceCidr}}, true)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconds.Add(cond)\n\t}\n\n\tif len(rr.Protocol) > 0 {\n\t\tconds.Add(NewProtocolMatcher(rr.Protocol))\n\t}\n\n\tif len(rr.Attributes) > 0 {\n\t\tcond, err := NewAttributeMatcher(rr.Attributes)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconds.Add(cond)\n\t}\n\n\tif conds.Len() == 0 {\n\t\treturn nil, newError(\"this rule has no effective fields\").AtWarning()\n\t}\n\n\treturn conds, nil\n}\n\n// Build builds the balancing rule\nfunc (br *BalancingRule) Build(ohm outbound.Manager, dispatcher routing.Dispatcher) (*Balancer, error) {\n\tswitch br.Strategy {\n\tcase \"leastping\":\n\t\ti, err := serial.GetInstanceOf(br.StrategySettings)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts, ok := i.(*StrategyLeastPingConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a StrategyLeastPingConfig\").AtError()\n\t\t}\n\t\treturn &Balancer{\n\t\t\tselectors: br.OutboundSelector,\n\t\t\tstrategy:  &LeastPingStrategy{config: s},\n\t\t\tohm:       ohm, fallbackTag: br.FallbackTag,\n\t\t}, nil\n\tcase \"leastload\":\n\t\ti, err := serial.GetInstanceOf(br.StrategySettings)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts, ok := i.(*StrategyLeastLoadConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a StrategyLeastLoadConfig\").AtError()\n\t\t}\n\t\tleastLoadStrategy := NewLeastLoadStrategy(s)\n\t\treturn &Balancer{\n\t\t\tselectors: br.OutboundSelector,\n\t\t\tohm:       ohm, fallbackTag: br.FallbackTag,\n\t\t\tstrategy: leastLoadStrategy,\n\t\t}, nil\n\tcase \"random\":\n\t\tfallthrough\n\tcase \"\":\n\t\tvar randomStrategy *RandomStrategy\n\t\tif br.StrategySettings != nil {\n\t\t\ti, err := serial.GetInstanceOf(br.StrategySettings)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\ts, ok := i.(*StrategyRandomConfig)\n\t\t\tif !ok {\n\t\t\t\treturn nil, newError(\"not a StrategyRandomConfig\").AtError()\n\t\t\t}\n\t\t\trandomStrategy = NewRandomStrategy(s)\n\t\t}\n\t\treturn &Balancer{\n\t\t\tselectors: br.OutboundSelector,\n\t\t\tohm:       ohm, fallbackTag: br.FallbackTag,\n\t\t\tstrategy: randomStrategy,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, newError(\"unrecognized balancer type\")\n\t}\n}\n\nfunc (br *BalancingRule) UnmarshalJSONPB(unmarshaler *jsonpb.Unmarshaler, bytes []byte) error {\n\ttype BalancingRuleStub struct {\n\t\tTag              string          `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\t\tOutboundSelector []string        `protobuf:\"bytes,2,rep,name=outbound_selector,json=outboundSelector,proto3\" json:\"outbound_selector,omitempty\"`\n\t\tStrategy         string          `protobuf:\"bytes,3,opt,name=strategy,proto3\" json:\"strategy,omitempty\"`\n\t\tStrategySettings json.RawMessage `protobuf:\"bytes,4,opt,name=strategy_settings,json=strategySettings,proto3\" json:\"strategy_settings,omitempty\"`\n\t\tFallbackTag      string          `protobuf:\"bytes,5,opt,name=fallback_tag,json=fallbackTag,proto3\" json:\"fallback_tag,omitempty\"`\n\t}\n\n\tvar stub BalancingRuleStub\n\tif err := json.Unmarshal(bytes, &stub); err != nil {\n\t\treturn err\n\t}\n\tif stub.Strategy == \"\" {\n\t\tstub.Strategy = \"random\"\n\t}\n\tsettingsPack, err := v5cfg.LoadHeterogeneousConfigFromRawJSON(context.TODO(), \"balancer\", stub.Strategy, stub.StrategySettings)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbr.StrategySettings = serial.ToTypedMessage(settingsPack)\n\n\tbr.Tag = stub.Tag\n\tbr.Strategy = stub.Strategy\n\tbr.OutboundSelector = stub.OutboundSelector\n\tbr.FallbackTag = stub.FallbackTag\n\n\treturn nil\n}\n"
  },
  {
    "path": "app/router/config.pb.go",
    "content": "package router\n\nimport (\n\troutercommon \"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 DomainStrategy int32\n\nconst (\n\t// Use domain as is.\n\tDomainStrategy_AsIs DomainStrategy = 0\n\t// Always resolve IP for domains.\n\tDomainStrategy_UseIp DomainStrategy = 1\n\t// Resolve to IP if the domain doesn't match any rules.\n\tDomainStrategy_IpIfNonMatch DomainStrategy = 2\n\t// Resolve to IP if any rule requires IP matching.\n\tDomainStrategy_IpOnDemand DomainStrategy = 3\n)\n\n// Enum value maps for DomainStrategy.\nvar (\n\tDomainStrategy_name = map[int32]string{\n\t\t0: \"AsIs\",\n\t\t1: \"UseIp\",\n\t\t2: \"IpIfNonMatch\",\n\t\t3: \"IpOnDemand\",\n\t}\n\tDomainStrategy_value = map[string]int32{\n\t\t\"AsIs\":         0,\n\t\t\"UseIp\":        1,\n\t\t\"IpIfNonMatch\": 2,\n\t\t\"IpOnDemand\":   3,\n\t}\n)\n\nfunc (x DomainStrategy) Enum() *DomainStrategy {\n\tp := new(DomainStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x DomainStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (DomainStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_router_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (DomainStrategy) Type() protoreflect.EnumType {\n\treturn &file_app_router_config_proto_enumTypes[0]\n}\n\nfunc (x DomainStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use DomainStrategy.Descriptor instead.\nfunc (DomainStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype RoutingRule struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Types that are valid to be assigned to TargetTag:\n\t//\n\t//\t*RoutingRule_Tag\n\t//\t*RoutingRule_BalancingTag\n\tTargetTag isRoutingRule_TargetTag `protobuf_oneof:\"target_tag\"`\n\t// List of domains for target domain matching.\n\tDomain []*routercommon.Domain `protobuf:\"bytes,2,rep,name=domain,proto3\" json:\"domain,omitempty\"`\n\t// List of CIDRs for target IP address matching.\n\t// Deprecated. Use geoip below.\n\t//\n\t// Deprecated: Marked as deprecated in app/router/config.proto.\n\tCidr []*routercommon.CIDR `protobuf:\"bytes,3,rep,name=cidr,proto3\" json:\"cidr,omitempty\"`\n\t// List of GeoIPs for target IP address matching. If this entry exists, the\n\t// cidr above will have no effect. GeoIP fields with the same country code are\n\t// supposed to contain exactly same content. They will be merged during\n\t// runtime. For customized GeoIPs, please leave country code empty.\n\tGeoip []*routercommon.GeoIP `protobuf:\"bytes,10,rep,name=geoip,proto3\" json:\"geoip,omitempty\"`\n\t// A range of port [from, to]. If the destination port is in this range, this\n\t// rule takes effect. Deprecated. Use port_list.\n\t//\n\t// Deprecated: Marked as deprecated in app/router/config.proto.\n\tPortRange *net.PortRange `protobuf:\"bytes,4,opt,name=port_range,json=portRange,proto3\" json:\"port_range,omitempty\"`\n\t// List of ports.\n\tPortList *net.PortList `protobuf:\"bytes,14,opt,name=port_list,json=portList,proto3\" json:\"port_list,omitempty\"`\n\t// List of networks. Deprecated. Use networks.\n\t//\n\t// Deprecated: Marked as deprecated in app/router/config.proto.\n\tNetworkList *net.NetworkList `protobuf:\"bytes,5,opt,name=network_list,json=networkList,proto3\" json:\"network_list,omitempty\"`\n\t// List of networks for matching.\n\tNetworks []net.Network `protobuf:\"varint,13,rep,packed,name=networks,proto3,enum=v2ray.core.common.net.Network\" json:\"networks,omitempty\"`\n\t// List of CIDRs for source IP address matching.\n\t//\n\t// Deprecated: Marked as deprecated in app/router/config.proto.\n\tSourceCidr []*routercommon.CIDR `protobuf:\"bytes,6,rep,name=source_cidr,json=sourceCidr,proto3\" json:\"source_cidr,omitempty\"`\n\t// List of GeoIPs for source IP address matching. If this entry exists, the\n\t// source_cidr above will have no effect.\n\tSourceGeoip []*routercommon.GeoIP `protobuf:\"bytes,11,rep,name=source_geoip,json=sourceGeoip,proto3\" json:\"source_geoip,omitempty\"`\n\t// List of ports for source port matching.\n\tSourcePortList *net.PortList `protobuf:\"bytes,16,opt,name=source_port_list,json=sourcePortList,proto3\" json:\"source_port_list,omitempty\"`\n\tUserEmail      []string      `protobuf:\"bytes,7,rep,name=user_email,json=userEmail,proto3\" json:\"user_email,omitempty\"`\n\tInboundTag     []string      `protobuf:\"bytes,8,rep,name=inbound_tag,json=inboundTag,proto3\" json:\"inbound_tag,omitempty\"`\n\tProtocol       []string      `protobuf:\"bytes,9,rep,name=protocol,proto3\" json:\"protocol,omitempty\"`\n\tAttributes     string        `protobuf:\"bytes,15,opt,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\tDomainMatcher  string        `protobuf:\"bytes,17,opt,name=domain_matcher,json=domainMatcher,proto3\" json:\"domain_matcher,omitempty\"`\n\t// geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.\n\tGeoDomain     []*routercommon.GeoSite `protobuf:\"bytes,68001,rep,name=geo_domain,json=geoDomain,proto3\" json:\"geo_domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RoutingRule) Reset() {\n\t*x = RoutingRule{}\n\tmi := &file_app_router_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RoutingRule) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RoutingRule) ProtoMessage() {}\n\nfunc (x *RoutingRule) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[0]\n\tif 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 RoutingRule.ProtoReflect.Descriptor instead.\nfunc (*RoutingRule) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *RoutingRule) GetTargetTag() isRoutingRule_TargetTag {\n\tif x != nil {\n\t\treturn x.TargetTag\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetTag() string {\n\tif x != nil {\n\t\tif x, ok := x.TargetTag.(*RoutingRule_Tag); ok {\n\t\t\treturn x.Tag\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingRule) GetBalancingTag() string {\n\tif x != nil {\n\t\tif x, ok := x.TargetTag.(*RoutingRule_BalancingTag); ok {\n\t\t\treturn x.BalancingTag\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingRule) GetDomain() []*routercommon.Domain {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/router/config.proto.\nfunc (x *RoutingRule) GetCidr() []*routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.Cidr\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetGeoip() []*routercommon.GeoIP {\n\tif x != nil {\n\t\treturn x.Geoip\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/router/config.proto.\nfunc (x *RoutingRule) GetPortRange() *net.PortRange {\n\tif x != nil {\n\t\treturn x.PortRange\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetPortList() *net.PortList {\n\tif x != nil {\n\t\treturn x.PortList\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/router/config.proto.\nfunc (x *RoutingRule) GetNetworkList() *net.NetworkList {\n\tif x != nil {\n\t\treturn x.NetworkList\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetNetworks() []net.Network {\n\tif x != nil {\n\t\treturn x.Networks\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in app/router/config.proto.\nfunc (x *RoutingRule) GetSourceCidr() []*routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.SourceCidr\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetSourceGeoip() []*routercommon.GeoIP {\n\tif x != nil {\n\t\treturn x.SourceGeoip\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetSourcePortList() *net.PortList {\n\tif x != nil {\n\t\treturn x.SourcePortList\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetUserEmail() []string {\n\tif x != nil {\n\t\treturn x.UserEmail\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetInboundTag() []string {\n\tif x != nil {\n\t\treturn x.InboundTag\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetProtocol() []string {\n\tif x != nil {\n\t\treturn x.Protocol\n\t}\n\treturn nil\n}\n\nfunc (x *RoutingRule) GetAttributes() string {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingRule) GetDomainMatcher() string {\n\tif x != nil {\n\t\treturn x.DomainMatcher\n\t}\n\treturn \"\"\n}\n\nfunc (x *RoutingRule) GetGeoDomain() []*routercommon.GeoSite {\n\tif x != nil {\n\t\treturn x.GeoDomain\n\t}\n\treturn nil\n}\n\ntype isRoutingRule_TargetTag interface {\n\tisRoutingRule_TargetTag()\n}\n\ntype RoutingRule_Tag struct {\n\t// Tag of outbound that this rule is pointing to.\n\tTag string `protobuf:\"bytes,1,opt,name=tag,proto3,oneof\"`\n}\n\ntype RoutingRule_BalancingTag struct {\n\t// Tag of routing balancer.\n\tBalancingTag string `protobuf:\"bytes,12,opt,name=balancing_tag,json=balancingTag,proto3,oneof\"`\n}\n\nfunc (*RoutingRule_Tag) isRoutingRule_TargetTag() {}\n\nfunc (*RoutingRule_BalancingTag) isRoutingRule_TargetTag() {}\n\ntype BalancingRule struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag              string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tOutboundSelector []string               `protobuf:\"bytes,2,rep,name=outbound_selector,json=outboundSelector,proto3\" json:\"outbound_selector,omitempty\"`\n\tStrategy         string                 `protobuf:\"bytes,3,opt,name=strategy,proto3\" json:\"strategy,omitempty\"`\n\tStrategySettings *anypb.Any             `protobuf:\"bytes,4,opt,name=strategy_settings,json=strategySettings,proto3\" json:\"strategy_settings,omitempty\"`\n\tFallbackTag      string                 `protobuf:\"bytes,5,opt,name=fallback_tag,json=fallbackTag,proto3\" json:\"fallback_tag,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *BalancingRule) Reset() {\n\t*x = BalancingRule{}\n\tmi := &file_app_router_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *BalancingRule) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BalancingRule) ProtoMessage() {}\n\nfunc (x *BalancingRule) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[1]\n\tif 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 BalancingRule.ProtoReflect.Descriptor instead.\nfunc (*BalancingRule) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *BalancingRule) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *BalancingRule) GetOutboundSelector() []string {\n\tif x != nil {\n\t\treturn x.OutboundSelector\n\t}\n\treturn nil\n}\n\nfunc (x *BalancingRule) GetStrategy() string {\n\tif x != nil {\n\t\treturn x.Strategy\n\t}\n\treturn \"\"\n}\n\nfunc (x *BalancingRule) GetStrategySettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.StrategySettings\n\t}\n\treturn nil\n}\n\nfunc (x *BalancingRule) GetFallbackTag() string {\n\tif x != nil {\n\t\treturn x.FallbackTag\n\t}\n\treturn \"\"\n}\n\ntype StrategyWeight struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tRegexp        bool                   `protobuf:\"varint,1,opt,name=regexp,proto3\" json:\"regexp,omitempty\"`\n\tMatch         string                 `protobuf:\"bytes,2,opt,name=match,proto3\" json:\"match,omitempty\"`\n\tValue         float32                `protobuf:\"fixed32,3,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *StrategyWeight) Reset() {\n\t*x = StrategyWeight{}\n\tmi := &file_app_router_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StrategyWeight) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StrategyWeight) ProtoMessage() {}\n\nfunc (x *StrategyWeight) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[2]\n\tif 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 StrategyWeight.ProtoReflect.Descriptor instead.\nfunc (*StrategyWeight) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *StrategyWeight) GetRegexp() bool {\n\tif x != nil {\n\t\treturn x.Regexp\n\t}\n\treturn false\n}\n\nfunc (x *StrategyWeight) GetMatch() string {\n\tif x != nil {\n\t\treturn x.Match\n\t}\n\treturn \"\"\n}\n\nfunc (x *StrategyWeight) GetValue() float32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\ntype StrategyRandomConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tObserverTag   string                 `protobuf:\"bytes,7,opt,name=observer_tag,json=observerTag,proto3\" json:\"observer_tag,omitempty\"`\n\tAliveOnly     bool                   `protobuf:\"varint,8,opt,name=alive_only,json=aliveOnly,proto3\" json:\"alive_only,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *StrategyRandomConfig) Reset() {\n\t*x = StrategyRandomConfig{}\n\tmi := &file_app_router_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StrategyRandomConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StrategyRandomConfig) ProtoMessage() {}\n\nfunc (x *StrategyRandomConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[3]\n\tif 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 StrategyRandomConfig.ProtoReflect.Descriptor instead.\nfunc (*StrategyRandomConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *StrategyRandomConfig) GetObserverTag() string {\n\tif x != nil {\n\t\treturn x.ObserverTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *StrategyRandomConfig) GetAliveOnly() bool {\n\tif x != nil {\n\t\treturn x.AliveOnly\n\t}\n\treturn false\n}\n\ntype StrategyLeastPingConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tObserverTag   string                 `protobuf:\"bytes,7,opt,name=observer_tag,json=observerTag,proto3\" json:\"observer_tag,omitempty\"`\n\tStickyChoice  bool                   `protobuf:\"varint,8,opt,name=sticky_choice,json=stickyChoice,proto3\" json:\"sticky_choice,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *StrategyLeastPingConfig) Reset() {\n\t*x = StrategyLeastPingConfig{}\n\tmi := &file_app_router_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StrategyLeastPingConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StrategyLeastPingConfig) ProtoMessage() {}\n\nfunc (x *StrategyLeastPingConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[4]\n\tif 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 StrategyLeastPingConfig.ProtoReflect.Descriptor instead.\nfunc (*StrategyLeastPingConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *StrategyLeastPingConfig) GetObserverTag() string {\n\tif x != nil {\n\t\treturn x.ObserverTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *StrategyLeastPingConfig) GetStickyChoice() bool {\n\tif x != nil {\n\t\treturn x.StickyChoice\n\t}\n\treturn false\n}\n\ntype StrategyLeastLoadConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// weight settings\n\tCosts []*StrategyWeight `protobuf:\"bytes,2,rep,name=costs,proto3\" json:\"costs,omitempty\"`\n\t// RTT baselines for selecting, int64 values of time.Duration\n\tBaselines []int64 `protobuf:\"varint,3,rep,packed,name=baselines,proto3\" json:\"baselines,omitempty\"`\n\t// expected nodes count to select\n\tExpected int32 `protobuf:\"varint,4,opt,name=expected,proto3\" json:\"expected,omitempty\"`\n\t// max acceptable rtt, filter away high delay nodes. defalut 0\n\tMaxRTT int64 `protobuf:\"varint,5,opt,name=maxRTT,proto3\" json:\"maxRTT,omitempty\"`\n\t// acceptable failure rate\n\tTolerance     float32 `protobuf:\"fixed32,6,opt,name=tolerance,proto3\" json:\"tolerance,omitempty\"`\n\tObserverTag   string  `protobuf:\"bytes,7,opt,name=observer_tag,json=observerTag,proto3\" json:\"observer_tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *StrategyLeastLoadConfig) Reset() {\n\t*x = StrategyLeastLoadConfig{}\n\tmi := &file_app_router_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StrategyLeastLoadConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StrategyLeastLoadConfig) ProtoMessage() {}\n\nfunc (x *StrategyLeastLoadConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[5]\n\tif 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 StrategyLeastLoadConfig.ProtoReflect.Descriptor instead.\nfunc (*StrategyLeastLoadConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *StrategyLeastLoadConfig) GetCosts() []*StrategyWeight {\n\tif x != nil {\n\t\treturn x.Costs\n\t}\n\treturn nil\n}\n\nfunc (x *StrategyLeastLoadConfig) GetBaselines() []int64 {\n\tif x != nil {\n\t\treturn x.Baselines\n\t}\n\treturn nil\n}\n\nfunc (x *StrategyLeastLoadConfig) GetExpected() int32 {\n\tif x != nil {\n\t\treturn x.Expected\n\t}\n\treturn 0\n}\n\nfunc (x *StrategyLeastLoadConfig) GetMaxRTT() int64 {\n\tif x != nil {\n\t\treturn x.MaxRTT\n\t}\n\treturn 0\n}\n\nfunc (x *StrategyLeastLoadConfig) GetTolerance() float32 {\n\tif x != nil {\n\t\treturn x.Tolerance\n\t}\n\treturn 0\n}\n\nfunc (x *StrategyLeastLoadConfig) GetObserverTag() string {\n\tif x != nil {\n\t\treturn x.ObserverTag\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tDomainStrategy DomainStrategy         `protobuf:\"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.app.router.DomainStrategy\" json:\"domain_strategy,omitempty\"`\n\tRule           []*RoutingRule         `protobuf:\"bytes,2,rep,name=rule,proto3\" json:\"rule,omitempty\"`\n\tBalancingRule  []*BalancingRule       `protobuf:\"bytes,3,rep,name=balancing_rule,json=balancingRule,proto3\" json:\"balancing_rule,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_router_config_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[6]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *Config) GetDomainStrategy() DomainStrategy {\n\tif x != nil {\n\t\treturn x.DomainStrategy\n\t}\n\treturn DomainStrategy_AsIs\n}\n\nfunc (x *Config) GetRule() []*RoutingRule {\n\tif x != nil {\n\t\treturn x.Rule\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetBalancingRule() []*BalancingRule {\n\tif x != nil {\n\t\treturn x.BalancingRule\n\t}\n\treturn nil\n}\n\ntype SimplifiedRoutingRule struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Types that are valid to be assigned to TargetTag:\n\t//\n\t//\t*SimplifiedRoutingRule_Tag\n\t//\t*SimplifiedRoutingRule_BalancingTag\n\tTargetTag isSimplifiedRoutingRule_TargetTag `protobuf_oneof:\"target_tag\"`\n\t// List of domains for target domain matching.\n\tDomain []*routercommon.Domain `protobuf:\"bytes,2,rep,name=domain,proto3\" json:\"domain,omitempty\"`\n\t// List of GeoIPs for target IP address matching. If this entry exists, the\n\t// cidr above will have no effect. GeoIP fields with the same country code are\n\t// supposed to contain exactly same content. They will be merged during\n\t// runtime. For customized GeoIPs, please leave country code empty.\n\tGeoip []*routercommon.GeoIP `protobuf:\"bytes,10,rep,name=geoip,proto3\" json:\"geoip,omitempty\"`\n\t// List of ports.\n\tPortList string `protobuf:\"bytes,14,opt,name=port_list,json=portList,proto3\" json:\"port_list,omitempty\"`\n\t// List of networks for matching.\n\tNetworks *net.NetworkList `protobuf:\"bytes,13,opt,name=networks,proto3\" json:\"networks,omitempty\"`\n\t// List of GeoIPs for source IP address matching. If this entry exists, the\n\t// source_cidr above will have no effect.\n\tSourceGeoip []*routercommon.GeoIP `protobuf:\"bytes,11,rep,name=source_geoip,json=sourceGeoip,proto3\" json:\"source_geoip,omitempty\"`\n\t// List of ports for source port matching.\n\tSourcePortList string   `protobuf:\"bytes,16,opt,name=source_port_list,json=sourcePortList,proto3\" json:\"source_port_list,omitempty\"`\n\tUserEmail      []string `protobuf:\"bytes,7,rep,name=user_email,json=userEmail,proto3\" json:\"user_email,omitempty\"`\n\tInboundTag     []string `protobuf:\"bytes,8,rep,name=inbound_tag,json=inboundTag,proto3\" json:\"inbound_tag,omitempty\"`\n\tProtocol       []string `protobuf:\"bytes,9,rep,name=protocol,proto3\" json:\"protocol,omitempty\"`\n\tAttributes     string   `protobuf:\"bytes,15,opt,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\tDomainMatcher  string   `protobuf:\"bytes,17,opt,name=domain_matcher,json=domainMatcher,proto3\" json:\"domain_matcher,omitempty\"`\n\t// geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.\n\tGeoDomain     []*routercommon.GeoSite `protobuf:\"bytes,68001,rep,name=geo_domain,json=geoDomain,proto3\" json:\"geo_domain,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedRoutingRule) Reset() {\n\t*x = SimplifiedRoutingRule{}\n\tmi := &file_app_router_config_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedRoutingRule) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedRoutingRule) ProtoMessage() {}\n\nfunc (x *SimplifiedRoutingRule) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[7]\n\tif 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 SimplifiedRoutingRule.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedRoutingRule) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *SimplifiedRoutingRule) GetTargetTag() isSimplifiedRoutingRule_TargetTag {\n\tif x != nil {\n\t\treturn x.TargetTag\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetTag() string {\n\tif x != nil {\n\t\tif x, ok := x.TargetTag.(*SimplifiedRoutingRule_Tag); ok {\n\t\t\treturn x.Tag\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedRoutingRule) GetBalancingTag() string {\n\tif x != nil {\n\t\tif x, ok := x.TargetTag.(*SimplifiedRoutingRule_BalancingTag); ok {\n\t\t\treturn x.BalancingTag\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedRoutingRule) GetDomain() []*routercommon.Domain {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetGeoip() []*routercommon.GeoIP {\n\tif x != nil {\n\t\treturn x.Geoip\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetPortList() string {\n\tif x != nil {\n\t\treturn x.PortList\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedRoutingRule) GetNetworks() *net.NetworkList {\n\tif x != nil {\n\t\treturn x.Networks\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetSourceGeoip() []*routercommon.GeoIP {\n\tif x != nil {\n\t\treturn x.SourceGeoip\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetSourcePortList() string {\n\tif x != nil {\n\t\treturn x.SourcePortList\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedRoutingRule) GetUserEmail() []string {\n\tif x != nil {\n\t\treturn x.UserEmail\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetInboundTag() []string {\n\tif x != nil {\n\t\treturn x.InboundTag\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetProtocol() []string {\n\tif x != nil {\n\t\treturn x.Protocol\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedRoutingRule) GetAttributes() string {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedRoutingRule) GetDomainMatcher() string {\n\tif x != nil {\n\t\treturn x.DomainMatcher\n\t}\n\treturn \"\"\n}\n\nfunc (x *SimplifiedRoutingRule) GetGeoDomain() []*routercommon.GeoSite {\n\tif x != nil {\n\t\treturn x.GeoDomain\n\t}\n\treturn nil\n}\n\ntype isSimplifiedRoutingRule_TargetTag interface {\n\tisSimplifiedRoutingRule_TargetTag()\n}\n\ntype SimplifiedRoutingRule_Tag struct {\n\t// Tag of outbound that this rule is pointing to.\n\tTag string `protobuf:\"bytes,1,opt,name=tag,proto3,oneof\"`\n}\n\ntype SimplifiedRoutingRule_BalancingTag struct {\n\t// Tag of routing balancer.\n\tBalancingTag string `protobuf:\"bytes,12,opt,name=balancing_tag,json=balancingTag,proto3,oneof\"`\n}\n\nfunc (*SimplifiedRoutingRule_Tag) isSimplifiedRoutingRule_TargetTag() {}\n\nfunc (*SimplifiedRoutingRule_BalancingTag) isSimplifiedRoutingRule_TargetTag() {}\n\ntype SimplifiedConfig struct {\n\tstate          protoimpl.MessageState   `protogen:\"open.v1\"`\n\tDomainStrategy DomainStrategy           `protobuf:\"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.app.router.DomainStrategy\" json:\"domain_strategy,omitempty\"`\n\tRule           []*SimplifiedRoutingRule `protobuf:\"bytes,2,rep,name=rule,proto3\" json:\"rule,omitempty\"`\n\tBalancingRule  []*BalancingRule         `protobuf:\"bytes,3,rep,name=balancing_rule,json=balancingRule,proto3\" json:\"balancing_rule,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_app_router_config_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_config_proto_msgTypes[8]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_router_config_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *SimplifiedConfig) GetDomainStrategy() DomainStrategy {\n\tif x != nil {\n\t\treturn x.DomainStrategy\n\t}\n\treturn DomainStrategy_AsIs\n}\n\nfunc (x *SimplifiedConfig) GetRule() []*SimplifiedRoutingRule {\n\tif x != nil {\n\t\treturn x.Rule\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetBalancingRule() []*BalancingRule {\n\tif x != nil {\n\t\treturn x.BalancingRule\n\t}\n\treturn nil\n}\n\nvar File_app_router_config_proto protoreflect.FileDescriptor\n\nconst file_app_router_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x17app/router/config.proto\\x12\\x15v2ray.core.app.router\\x1a\\x19google/protobuf/any.proto\\x1a\\x15common/net/port.proto\\x1a\\x18common/net/network.proto\\x1a common/protoext/extensions.proto\\x1a$app/router/routercommon/common.proto\\\"\\x80\\b\\n\" +\n\t\"\\vRoutingRule\\x12\\x12\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tH\\x00R\\x03tag\\x12%\\n\" +\n\t\"\\rbalancing_tag\\x18\\f \\x01(\\tH\\x00R\\fbalancingTag\\x12B\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x03(\\v2*.v2ray.core.app.router.routercommon.DomainR\\x06domain\\x12@\\n\" +\n\t\"\\x04cidr\\x18\\x03 \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRB\\x02\\x18\\x01R\\x04cidr\\x12?\\n\" +\n\t\"\\x05geoip\\x18\\n\" +\n\t\" \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\x05geoip\\x12C\\n\" +\n\t\"\\n\" +\n\t\"port_range\\x18\\x04 \\x01(\\v2 .v2ray.core.common.net.PortRangeB\\x02\\x18\\x01R\\tportRange\\x12<\\n\" +\n\t\"\\tport_list\\x18\\x0e \\x01(\\v2\\x1f.v2ray.core.common.net.PortListR\\bportList\\x12I\\n\" +\n\t\"\\fnetwork_list\\x18\\x05 \\x01(\\v2\\\".v2ray.core.common.net.NetworkListB\\x02\\x18\\x01R\\vnetworkList\\x12:\\n\" +\n\t\"\\bnetworks\\x18\\r \\x03(\\x0e2\\x1e.v2ray.core.common.net.NetworkR\\bnetworks\\x12M\\n\" +\n\t\"\\vsource_cidr\\x18\\x06 \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRB\\x02\\x18\\x01R\\n\" +\n\t\"sourceCidr\\x12L\\n\" +\n\t\"\\fsource_geoip\\x18\\v \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\vsourceGeoip\\x12I\\n\" +\n\t\"\\x10source_port_list\\x18\\x10 \\x01(\\v2\\x1f.v2ray.core.common.net.PortListR\\x0esourcePortList\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_email\\x18\\a \\x03(\\tR\\tuserEmail\\x12\\x1f\\n\" +\n\t\"\\vinbound_tag\\x18\\b \\x03(\\tR\\n\" +\n\t\"inboundTag\\x12\\x1a\\n\" +\n\t\"\\bprotocol\\x18\\t \\x03(\\tR\\bprotocol\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"attributes\\x18\\x0f \\x01(\\tR\\n\" +\n\t\"attributes\\x12%\\n\" +\n\t\"\\x0edomain_matcher\\x18\\x11 \\x01(\\tR\\rdomainMatcher\\x12L\\n\" +\n\t\"\\n\" +\n\t\"geo_domain\\x18\\xa1\\x93\\x04 \\x03(\\v2+.v2ray.core.app.router.routercommon.GeoSiteR\\tgeoDomainB\\f\\n\" +\n\t\"\\n\" +\n\t\"target_tag\\\"\\xd0\\x01\\n\" +\n\t\"\\rBalancingRule\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12+\\n\" +\n\t\"\\x11outbound_selector\\x18\\x02 \\x03(\\tR\\x10outboundSelector\\x12\\x1a\\n\" +\n\t\"\\bstrategy\\x18\\x03 \\x01(\\tR\\bstrategy\\x12A\\n\" +\n\t\"\\x11strategy_settings\\x18\\x04 \\x01(\\v2\\x14.google.protobuf.AnyR\\x10strategySettings\\x12!\\n\" +\n\t\"\\ffallback_tag\\x18\\x05 \\x01(\\tR\\vfallbackTag\\\"T\\n\" +\n\t\"\\x0eStrategyWeight\\x12\\x16\\n\" +\n\t\"\\x06regexp\\x18\\x01 \\x01(\\bR\\x06regexp\\x12\\x14\\n\" +\n\t\"\\x05match\\x18\\x02 \\x01(\\tR\\x05match\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x03 \\x01(\\x02R\\x05value\\\"p\\n\" +\n\t\"\\x14StrategyRandomConfig\\x12!\\n\" +\n\t\"\\fobserver_tag\\x18\\a \\x01(\\tR\\vobserverTag\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"alive_only\\x18\\b \\x01(\\bR\\taliveOnly:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\bbalancer\\x12\\x06random\\\"|\\n\" +\n\t\"\\x17StrategyLeastPingConfig\\x12!\\n\" +\n\t\"\\fobserver_tag\\x18\\a \\x01(\\tR\\vobserverTag\\x12#\\n\" +\n\t\"\\rsticky_choice\\x18\\b \\x01(\\bR\\fstickyChoice:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\bbalancer\\x12\\tleastping\\\"\\x84\\x02\\n\" +\n\t\"\\x17StrategyLeastLoadConfig\\x12;\\n\" +\n\t\"\\x05costs\\x18\\x02 \\x03(\\v2%.v2ray.core.app.router.StrategyWeightR\\x05costs\\x12\\x1c\\n\" +\n\t\"\\tbaselines\\x18\\x03 \\x03(\\x03R\\tbaselines\\x12\\x1a\\n\" +\n\t\"\\bexpected\\x18\\x04 \\x01(\\x05R\\bexpected\\x12\\x16\\n\" +\n\t\"\\x06maxRTT\\x18\\x05 \\x01(\\x03R\\x06maxRTT\\x12\\x1c\\n\" +\n\t\"\\ttolerance\\x18\\x06 \\x01(\\x02R\\ttolerance\\x12!\\n\" +\n\t\"\\fobserver_tag\\x18\\a \\x01(\\tR\\vobserverTag:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\bbalancer\\x12\\tleastload\\\"\\xdd\\x01\\n\" +\n\t\"\\x06Config\\x12N\\n\" +\n\t\"\\x0fdomain_strategy\\x18\\x01 \\x01(\\x0e2%.v2ray.core.app.router.DomainStrategyR\\x0edomainStrategy\\x126\\n\" +\n\t\"\\x04rule\\x18\\x02 \\x03(\\v2\\\".v2ray.core.app.router.RoutingRuleR\\x04rule\\x12K\\n\" +\n\t\"\\x0ebalancing_rule\\x18\\x03 \\x03(\\v2$.v2ray.core.app.router.BalancingRuleR\\rbalancingRule\\\"\\xab\\x05\\n\" +\n\t\"\\x15SimplifiedRoutingRule\\x12\\x12\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tH\\x00R\\x03tag\\x12%\\n\" +\n\t\"\\rbalancing_tag\\x18\\f \\x01(\\tH\\x00R\\fbalancingTag\\x12B\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x03(\\v2*.v2ray.core.app.router.routercommon.DomainR\\x06domain\\x12?\\n\" +\n\t\"\\x05geoip\\x18\\n\" +\n\t\" \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\x05geoip\\x12\\x1b\\n\" +\n\t\"\\tport_list\\x18\\x0e \\x01(\\tR\\bportList\\x12>\\n\" +\n\t\"\\bnetworks\\x18\\r \\x01(\\v2\\\".v2ray.core.common.net.NetworkListR\\bnetworks\\x12L\\n\" +\n\t\"\\fsource_geoip\\x18\\v \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\vsourceGeoip\\x12(\\n\" +\n\t\"\\x10source_port_list\\x18\\x10 \\x01(\\tR\\x0esourcePortList\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_email\\x18\\a \\x03(\\tR\\tuserEmail\\x12\\x1f\\n\" +\n\t\"\\vinbound_tag\\x18\\b \\x03(\\tR\\n\" +\n\t\"inboundTag\\x12\\x1a\\n\" +\n\t\"\\bprotocol\\x18\\t \\x03(\\tR\\bprotocol\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"attributes\\x18\\x0f \\x01(\\tR\\n\" +\n\t\"attributes\\x12%\\n\" +\n\t\"\\x0edomain_matcher\\x18\\x11 \\x01(\\tR\\rdomainMatcher\\x12L\\n\" +\n\t\"\\n\" +\n\t\"geo_domain\\x18\\xa1\\x93\\x04 \\x03(\\v2+.v2ray.core.app.router.routercommon.GeoSiteR\\tgeoDomainB\\f\\n\" +\n\t\"\\n\" +\n\t\"target_tag\\\"\\x88\\x02\\n\" +\n\t\"\\x10SimplifiedConfig\\x12N\\n\" +\n\t\"\\x0fdomain_strategy\\x18\\x01 \\x01(\\x0e2%.v2ray.core.app.router.DomainStrategyR\\x0edomainStrategy\\x12@\\n\" +\n\t\"\\x04rule\\x18\\x02 \\x03(\\v2,.v2ray.core.app.router.SimplifiedRoutingRuleR\\x04rule\\x12K\\n\" +\n\t\"\\x0ebalancing_rule\\x18\\x03 \\x03(\\v2$.v2ray.core.app.router.BalancingRuleR\\rbalancingRule:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\aservice\\x12\\x06router*G\\n\" +\n\t\"\\x0eDomainStrategy\\x12\\b\\n\" +\n\t\"\\x04AsIs\\x10\\x00\\x12\\t\\n\" +\n\t\"\\x05UseIp\\x10\\x01\\x12\\x10\\n\" +\n\t\"\\fIpIfNonMatch\\x10\\x02\\x12\\x0e\\n\" +\n\t\"\\n\" +\n\t\"IpOnDemand\\x10\\x03B`\\n\" +\n\t\"\\x19com.v2ray.core.app.routerP\\x01Z)github.com/v2fly/v2ray-core/v5/app/router\\xaa\\x02\\x15V2Ray.Core.App.Routerb\\x06proto3\"\n\nvar (\n\tfile_app_router_config_proto_rawDescOnce sync.Once\n\tfile_app_router_config_proto_rawDescData []byte\n)\n\nfunc file_app_router_config_proto_rawDescGZIP() []byte {\n\tfile_app_router_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_router_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_router_config_proto_rawDesc), len(file_app_router_config_proto_rawDesc)))\n\t})\n\treturn file_app_router_config_proto_rawDescData\n}\n\nvar file_app_router_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_app_router_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9)\nvar file_app_router_config_proto_goTypes = []any{\n\t(DomainStrategy)(0),             // 0: v2ray.core.app.router.DomainStrategy\n\t(*RoutingRule)(nil),             // 1: v2ray.core.app.router.RoutingRule\n\t(*BalancingRule)(nil),           // 2: v2ray.core.app.router.BalancingRule\n\t(*StrategyWeight)(nil),          // 3: v2ray.core.app.router.StrategyWeight\n\t(*StrategyRandomConfig)(nil),    // 4: v2ray.core.app.router.StrategyRandomConfig\n\t(*StrategyLeastPingConfig)(nil), // 5: v2ray.core.app.router.StrategyLeastPingConfig\n\t(*StrategyLeastLoadConfig)(nil), // 6: v2ray.core.app.router.StrategyLeastLoadConfig\n\t(*Config)(nil),                  // 7: v2ray.core.app.router.Config\n\t(*SimplifiedRoutingRule)(nil),   // 8: v2ray.core.app.router.SimplifiedRoutingRule\n\t(*SimplifiedConfig)(nil),        // 9: v2ray.core.app.router.SimplifiedConfig\n\t(*routercommon.Domain)(nil),     // 10: v2ray.core.app.router.routercommon.Domain\n\t(*routercommon.CIDR)(nil),       // 11: v2ray.core.app.router.routercommon.CIDR\n\t(*routercommon.GeoIP)(nil),      // 12: v2ray.core.app.router.routercommon.GeoIP\n\t(*net.PortRange)(nil),           // 13: v2ray.core.common.net.PortRange\n\t(*net.PortList)(nil),            // 14: v2ray.core.common.net.PortList\n\t(*net.NetworkList)(nil),         // 15: v2ray.core.common.net.NetworkList\n\t(net.Network)(0),                // 16: v2ray.core.common.net.Network\n\t(*routercommon.GeoSite)(nil),    // 17: v2ray.core.app.router.routercommon.GeoSite\n\t(*anypb.Any)(nil),               // 18: google.protobuf.Any\n}\nvar file_app_router_config_proto_depIdxs = []int32{\n\t10, // 0: v2ray.core.app.router.RoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain\n\t11, // 1: v2ray.core.app.router.RoutingRule.cidr:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t12, // 2: v2ray.core.app.router.RoutingRule.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t13, // 3: v2ray.core.app.router.RoutingRule.port_range:type_name -> v2ray.core.common.net.PortRange\n\t14, // 4: v2ray.core.app.router.RoutingRule.port_list:type_name -> v2ray.core.common.net.PortList\n\t15, // 5: v2ray.core.app.router.RoutingRule.network_list:type_name -> v2ray.core.common.net.NetworkList\n\t16, // 6: v2ray.core.app.router.RoutingRule.networks:type_name -> v2ray.core.common.net.Network\n\t11, // 7: v2ray.core.app.router.RoutingRule.source_cidr:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t12, // 8: v2ray.core.app.router.RoutingRule.source_geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t14, // 9: v2ray.core.app.router.RoutingRule.source_port_list:type_name -> v2ray.core.common.net.PortList\n\t17, // 10: v2ray.core.app.router.RoutingRule.geo_domain:type_name -> v2ray.core.app.router.routercommon.GeoSite\n\t18, // 11: v2ray.core.app.router.BalancingRule.strategy_settings:type_name -> google.protobuf.Any\n\t3,  // 12: v2ray.core.app.router.StrategyLeastLoadConfig.costs:type_name -> v2ray.core.app.router.StrategyWeight\n\t0,  // 13: v2ray.core.app.router.Config.domain_strategy:type_name -> v2ray.core.app.router.DomainStrategy\n\t1,  // 14: v2ray.core.app.router.Config.rule:type_name -> v2ray.core.app.router.RoutingRule\n\t2,  // 15: v2ray.core.app.router.Config.balancing_rule:type_name -> v2ray.core.app.router.BalancingRule\n\t10, // 16: v2ray.core.app.router.SimplifiedRoutingRule.domain:type_name -> v2ray.core.app.router.routercommon.Domain\n\t12, // 17: v2ray.core.app.router.SimplifiedRoutingRule.geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t15, // 18: v2ray.core.app.router.SimplifiedRoutingRule.networks:type_name -> v2ray.core.common.net.NetworkList\n\t12, // 19: v2ray.core.app.router.SimplifiedRoutingRule.source_geoip:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t17, // 20: v2ray.core.app.router.SimplifiedRoutingRule.geo_domain:type_name -> v2ray.core.app.router.routercommon.GeoSite\n\t0,  // 21: v2ray.core.app.router.SimplifiedConfig.domain_strategy:type_name -> v2ray.core.app.router.DomainStrategy\n\t8,  // 22: v2ray.core.app.router.SimplifiedConfig.rule:type_name -> v2ray.core.app.router.SimplifiedRoutingRule\n\t2,  // 23: v2ray.core.app.router.SimplifiedConfig.balancing_rule:type_name -> v2ray.core.app.router.BalancingRule\n\t24, // [24:24] is the sub-list for method output_type\n\t24, // [24:24] is the sub-list for method input_type\n\t24, // [24:24] is the sub-list for extension type_name\n\t24, // [24:24] is the sub-list for extension extendee\n\t0,  // [0:24] is the sub-list for field type_name\n}\n\nfunc init() { file_app_router_config_proto_init() }\nfunc file_app_router_config_proto_init() {\n\tif File_app_router_config_proto != nil {\n\t\treturn\n\t}\n\tfile_app_router_config_proto_msgTypes[0].OneofWrappers = []any{\n\t\t(*RoutingRule_Tag)(nil),\n\t\t(*RoutingRule_BalancingTag)(nil),\n\t}\n\tfile_app_router_config_proto_msgTypes[7].OneofWrappers = []any{\n\t\t(*SimplifiedRoutingRule_Tag)(nil),\n\t\t(*SimplifiedRoutingRule_BalancingTag)(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: unsafe.Slice(unsafe.StringData(file_app_router_config_proto_rawDesc), len(file_app_router_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   9,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_router_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_router_config_proto_depIdxs,\n\t\tEnumInfos:         file_app_router_config_proto_enumTypes,\n\t\tMessageInfos:      file_app_router_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_router_config_proto = out.File\n\tfile_app_router_config_proto_goTypes = nil\n\tfile_app_router_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/router/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.router;\noption csharp_namespace = \"V2Ray.Core.App.Router\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/router\";\noption java_package = \"com.v2ray.core.app.router\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\nimport \"common/net/port.proto\";\nimport \"common/net/network.proto\";\nimport \"common/protoext/extensions.proto\";\nimport \"app/router/routercommon/common.proto\";\n\n\nmessage RoutingRule {\n  oneof target_tag {\n    // Tag of outbound that this rule is pointing to.\n    string tag = 1;\n\n    // Tag of routing balancer.\n    string balancing_tag = 12;\n  }\n\n  // List of domains for target domain matching.\n  repeated v2ray.core.app.router.routercommon.Domain domain = 2;\n\n  // List of CIDRs for target IP address matching.\n  // Deprecated. Use geoip below.\n  repeated v2ray.core.app.router.routercommon.CIDR cidr = 3 [deprecated = true];\n\n  // List of GeoIPs for target IP address matching. If this entry exists, the\n  // cidr above will have no effect. GeoIP fields with the same country code are\n  // supposed to contain exactly same content. They will be merged during\n  // runtime. For customized GeoIPs, please leave country code empty.\n  repeated v2ray.core.app.router.routercommon.GeoIP geoip = 10;\n\n  // A range of port [from, to]. If the destination port is in this range, this\n  // rule takes effect. Deprecated. Use port_list.\n  v2ray.core.common.net.PortRange port_range = 4 [deprecated = true];\n\n  // List of ports.\n  v2ray.core.common.net.PortList port_list = 14;\n\n  // List of networks. Deprecated. Use networks.\n  v2ray.core.common.net.NetworkList network_list = 5 [deprecated = true];\n\n  // List of networks for matching.\n  repeated v2ray.core.common.net.Network networks = 13;\n\n  // List of CIDRs for source IP address matching.\n  repeated v2ray.core.app.router.routercommon.CIDR source_cidr = 6 [deprecated = true];\n\n  // List of GeoIPs for source IP address matching. If this entry exists, the\n  // source_cidr above will have no effect.\n  repeated v2ray.core.app.router.routercommon.GeoIP source_geoip = 11;\n\n  // List of ports for source port matching.\n  v2ray.core.common.net.PortList source_port_list = 16;\n\n  repeated string user_email = 7;\n  repeated string inbound_tag = 8;\n  repeated string protocol = 9;\n\n  string attributes = 15;\n\n  string domain_matcher = 17;\n\n  // geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.\n  repeated v2ray.core.app.router.routercommon.GeoSite geo_domain = 68001;\n}\n\nmessage BalancingRule {\n  string tag = 1;\n  repeated string outbound_selector = 2;\n  string strategy = 3;\n  google.protobuf.Any strategy_settings = 4;\n  string fallback_tag = 5;\n}\n\nmessage StrategyWeight {\n  bool regexp = 1;\n  string match = 2;\n  float value = 3;\n}\n\nmessage StrategyRandomConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"balancer\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"random\";\n\n  string observer_tag = 7;\n  bool alive_only = 8;\n}\n\nmessage StrategyLeastPingConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"balancer\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"leastping\";\n\n  string observer_tag = 7;\n\n  bool sticky_choice = 8;\n}\n\nmessage StrategyLeastLoadConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"balancer\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"leastload\";\n\n  // weight settings\n  repeated StrategyWeight costs = 2;\n  // RTT baselines for selecting, int64 values of time.Duration\n  repeated int64 baselines = 3;\n  // expected nodes count to select\n  int32 expected = 4;\n  // max acceptable rtt, filter away high delay nodes. defalut 0\n  int64 maxRTT = 5;\n  // acceptable failure rate\n  float tolerance = 6;\n\n  string observer_tag = 7;\n}\n\nenum DomainStrategy {\n  // Use domain as is.\n  AsIs = 0;\n\n  // Always resolve IP for domains.\n  UseIp = 1;\n\n  // Resolve to IP if the domain doesn't match any rules.\n  IpIfNonMatch = 2;\n\n  // Resolve to IP if any rule requires IP matching.\n  IpOnDemand = 3;\n}\n\nmessage Config {\n  DomainStrategy domain_strategy = 1;\n  repeated RoutingRule rule = 2;\n  repeated BalancingRule balancing_rule = 3;\n}\n\nmessage SimplifiedRoutingRule {\n  oneof target_tag {\n    // Tag of outbound that this rule is pointing to.\n    string tag = 1;\n\n    // Tag of routing balancer.\n    string balancing_tag = 12;\n  }\n\n  // List of domains for target domain matching.\n  repeated v2ray.core.app.router.routercommon.Domain domain = 2;\n\n  // List of GeoIPs for target IP address matching. If this entry exists, the\n  // cidr above will have no effect. GeoIP fields with the same country code are\n  // supposed to contain exactly same content. They will be merged during\n  // runtime. For customized GeoIPs, please leave country code empty.\n  repeated v2ray.core.app.router.routercommon.GeoIP geoip = 10;\n\n  // List of ports.\n  string port_list = 14;\n\n  // List of networks for matching.\n  v2ray.core.common.net.NetworkList networks = 13;\n\n  // List of GeoIPs for source IP address matching. If this entry exists, the\n  // source_cidr above will have no effect.\n  repeated v2ray.core.app.router.routercommon.GeoIP source_geoip = 11;\n\n  // List of ports for source port matching.\n  string source_port_list = 16;\n\n  repeated string user_email = 7;\n  repeated string inbound_tag = 8;\n  repeated string protocol = 9;\n\n  string attributes = 15;\n\n  string domain_matcher = 17;\n\n  // geo_domain instruct simplified config loader to load geo domain rule and fill in domain field.\n  repeated v2ray.core.app.router.routercommon.GeoSite geo_domain = 68001;\n}\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"router\";\n\n  DomainStrategy domain_strategy = 1;\n  repeated SimplifiedRoutingRule rule = 2;\n  repeated BalancingRule balancing_rule = 3;\n}"
  },
  {
    "path": "app/router/errors.generated.go",
    "content": "package router\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/router/router.go",
    "content": "package router\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\trouting_dns \"github.com/v2fly/v2ray-core/v5/features/routing/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n)\n\n// Router is an implementation of routing.Router.\ntype Router struct {\n\tdomainStrategy DomainStrategy\n\trules          []*Rule\n\tbalancers      map[string]*Balancer\n\tdns            dns.Client\n}\n\n// Route is an implementation of routing.Route.\ntype Route struct {\n\trouting.Context\n\toutboundGroupTags []string\n\toutboundTag       string\n}\n\n// Init initializes the Router.\nfunc (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm outbound.Manager, dispatcher routing.Dispatcher) error {\n\tr.domainStrategy = config.DomainStrategy\n\tr.dns = d\n\n\tr.balancers = make(map[string]*Balancer, len(config.BalancingRule))\n\tfor _, rule := range config.BalancingRule {\n\t\tbalancer, err := rule.Build(ohm, dispatcher)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbalancer.InjectContext(ctx)\n\t\tr.balancers[rule.Tag] = balancer\n\t}\n\n\tr.rules = make([]*Rule, 0, len(config.Rule))\n\tfor _, rule := range config.Rule {\n\t\tcond, err := rule.BuildCondition()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr := &Rule{\n\t\t\tCondition: cond,\n\t\t\tTag:       rule.GetTag(),\n\t\t}\n\t\tbtag := rule.GetBalancingTag()\n\t\tif len(btag) > 0 {\n\t\t\tbrule, found := r.balancers[btag]\n\t\t\tif !found {\n\t\t\t\treturn newError(\"balancer \", btag, \" not found\")\n\t\t\t}\n\t\t\trr.Balancer = brule\n\t\t}\n\t\tr.rules = append(r.rules, rr)\n\t}\n\n\treturn nil\n}\n\n// PickRoute implements routing.Router.\nfunc (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) {\n\trule, ctx, err := r.pickRouteInternal(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttag, err := rule.GetTag()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Route{Context: ctx, outboundTag: tag}, nil\n}\n\nfunc (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, error) {\n\t// SkipDNSResolve is set from DNS module.\n\t// the DOH remote server maybe a domain name,\n\t// this prevents cycle resolving dead loop\n\tskipDNSResolve := ctx.GetSkipDNSResolve()\n\n\tif r.domainStrategy == DomainStrategy_IpOnDemand && !skipDNSResolve {\n\t\tctx = routing_dns.ContextWithDNSClient(ctx, r.dns)\n\t}\n\n\tfor _, rule := range r.rules {\n\t\tif rule.Apply(ctx) {\n\t\t\treturn rule, ctx, nil\n\t\t}\n\t}\n\n\tif r.domainStrategy != DomainStrategy_IpIfNonMatch || len(ctx.GetTargetDomain()) == 0 || skipDNSResolve {\n\t\treturn nil, ctx, common.ErrNoClue\n\t}\n\n\tctx = routing_dns.ContextWithDNSClient(ctx, r.dns)\n\n\t// Try applying rules again if we have IPs.\n\tfor _, rule := range r.rules {\n\t\tif rule.Apply(ctx) {\n\t\t\treturn rule, ctx, nil\n\t\t}\n\t}\n\n\treturn nil, ctx, common.ErrNoClue\n}\n\n// Start implements common.Runnable.\nfunc (r *Router) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (r *Router) Close() error {\n\treturn nil\n}\n\n// Type implements common.HasType.\nfunc (*Router) Type() interface{} {\n\treturn routing.RouterType()\n}\n\n// GetOutboundGroupTags implements routing.Route.\nfunc (r *Route) GetOutboundGroupTags() []string {\n\treturn r.outboundGroupTags\n}\n\n// GetOutboundTag implements routing.Route.\nfunc (r *Route) GetOutboundTag() string {\n\treturn r.outboundTag\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tr := new(Router)\n\t\tif err := core.RequireFeatures(ctx, func(d dns.Client, ohm outbound.Manager, dispatcher routing.Dispatcher) error {\n\t\t\treturn r.Init(ctx, config.(*Config), d, ohm, dispatcher)\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn r, nil\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tctx = cfgcommon.NewConfigureLoadingContext(ctx)\n\n\t\tgeoloadername := platform.NewEnvFlag(\"v2ray.conf.geoloader\").GetValue(func() string {\n\t\t\treturn \"standard\"\n\t\t})\n\n\t\tif loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {\n\t\t\tcfgcommon.SetGeoDataLoader(ctx, loader)\n\t\t} else {\n\t\t\treturn nil, newError(\"unable to create geo data loader \").Base(err)\n\t\t}\n\n\t\tcfgEnv := cfgcommon.GetConfigureLoadingEnvironment(ctx)\n\t\tgeoLoader := cfgEnv.GetGeoLoader()\n\n\t\tsimplifiedConfig := config.(*SimplifiedConfig)\n\n\t\tvar routingRules []*RoutingRule\n\n\t\tfor _, v := range simplifiedConfig.Rule {\n\t\t\trule := new(RoutingRule)\n\n\t\t\tfor _, geo := range v.Geoip {\n\t\t\t\tif geo.Code != \"\" {\n\t\t\t\t\tfilepath := \"geoip.dat\"\n\t\t\t\t\tif geo.FilePath != \"\" {\n\t\t\t\t\t\tfilepath = geo.FilePath\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgeo.CountryCode = geo.Code\n\t\t\t\t\t}\n\t\t\t\t\tvar err error\n\t\t\t\t\tgeo.Cidr, err = geoLoader.LoadIP(filepath, geo.Code)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, newError(\"unable to load geoip\").Base(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\trule.Geoip = v.Geoip\n\n\t\t\tfor _, geo := range v.SourceGeoip {\n\t\t\t\tif geo.Code != \"\" {\n\t\t\t\t\tfilepath := \"geoip.dat\"\n\t\t\t\t\tif geo.FilePath != \"\" {\n\t\t\t\t\t\tfilepath = geo.FilePath\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgeo.CountryCode = geo.Code\n\t\t\t\t\t}\n\t\t\t\t\tvar err error\n\t\t\t\t\tgeo.Cidr, err = geoLoader.LoadIP(filepath, geo.Code)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, newError(\"unable to load geoip\").Base(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\trule.SourceGeoip = v.SourceGeoip\n\n\t\t\tfor _, geo := range v.GeoDomain {\n\t\t\t\tif geo.Code != \"\" {\n\t\t\t\t\tfilepath := \"geosite.dat\"\n\t\t\t\t\tif geo.FilePath != \"\" {\n\t\t\t\t\t\tfilepath = geo.FilePath\n\t\t\t\t\t}\n\t\t\t\t\tvar err error\n\t\t\t\t\tgeo.Domain, err = geoLoader.LoadGeoSiteWithAttr(filepath, geo.Code)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, newError(\"unable to load geodomain\").Base(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif v.PortList != \"\" {\n\t\t\t\tportList := &cfgcommon.PortList{}\n\t\t\t\terr := portList.UnmarshalText(v.PortList)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\trule.PortList = portList.Build()\n\t\t\t}\n\t\t\tif v.SourcePortList != \"\" {\n\t\t\t\tportList := &cfgcommon.PortList{}\n\t\t\t\terr := portList.UnmarshalText(v.SourcePortList)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\trule.SourcePortList = portList.Build()\n\t\t\t}\n\t\t\trule.Domain = v.Domain\n\t\t\trule.GeoDomain = v.GeoDomain\n\t\t\trule.Networks = v.Networks.GetNetwork()\n\t\t\trule.Protocol = v.Protocol\n\t\t\trule.Attributes = v.Attributes\n\t\t\trule.UserEmail = v.UserEmail\n\t\t\trule.InboundTag = v.InboundTag\n\t\t\trule.DomainMatcher = v.DomainMatcher\n\t\t\tswitch s := v.TargetTag.(type) {\n\t\t\tcase *SimplifiedRoutingRule_Tag:\n\t\t\t\trule.TargetTag = &RoutingRule_Tag{s.Tag}\n\t\t\tcase *SimplifiedRoutingRule_BalancingTag:\n\t\t\t\trule.TargetTag = &RoutingRule_BalancingTag{s.BalancingTag}\n\t\t\t}\n\t\t\troutingRules = append(routingRules, rule)\n\t\t}\n\n\t\tfullConfig := &Config{\n\t\t\tDomainStrategy: simplifiedConfig.DomainStrategy,\n\t\t\tRule:           routingRules,\n\t\t\tBalancingRule:  simplifiedConfig.BalancingRule,\n\t\t}\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n"
  },
  {
    "path": "app/router/router_test.go",
    "content": "package router_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\trouting_session \"github.com/v2fly/v2ray-core/v5/features/routing/session\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/mocks\"\n)\n\ntype mockOutboundManager struct {\n\toutbound.Manager\n\toutbound.HandlerSelector\n}\n\nfunc TestSimpleRouter(t *testing.T) {\n\tconfig := &Config{\n\t\tRule: []*RoutingRule{\n\t\t\t{\n\t\t\t\tTargetTag: &RoutingRule_Tag{\n\t\t\t\t\tTag: \"test\",\n\t\t\t\t},\n\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t},\n\t\t},\n\t}\n\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockDNS := mocks.NewDNSClient(mockCtl)\n\tmockOhm := mocks.NewOutboundManager(mockCtl)\n\tmockHs := mocks.NewOutboundHandlerSelector(mockCtl)\n\n\tr := new(Router)\n\tcommon.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{\n\t\tManager:         mockOhm,\n\t\tHandlerSelector: mockHs,\n\t}, nil))\n\n\tctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80)})\n\troute, err := r.PickRoute(routing_session.AsRoutingContext(ctx))\n\tcommon.Must(err)\n\tif tag := route.GetOutboundTag(); tag != \"test\" {\n\t\tt.Error(\"expect tag 'test', bug actually \", tag)\n\t}\n}\n\nfunc TestSimpleBalancer(t *testing.T) {\n\tconfig := &Config{\n\t\tRule: []*RoutingRule{\n\t\t\t{\n\t\t\t\tTargetTag: &RoutingRule_BalancingTag{\n\t\t\t\t\tBalancingTag: \"balance\",\n\t\t\t\t},\n\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t},\n\t\t},\n\t\tBalancingRule: []*BalancingRule{\n\t\t\t{\n\t\t\t\tTag:              \"balance\",\n\t\t\t\tOutboundSelector: []string{\"test-\"},\n\t\t\t},\n\t\t},\n\t}\n\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockDNS := mocks.NewDNSClient(mockCtl)\n\tmockOhm := mocks.NewOutboundManager(mockCtl)\n\tmockHs := mocks.NewOutboundHandlerSelector(mockCtl)\n\n\tmockHs.EXPECT().Select(gomock.Eq([]string{\"test-\"})).Return([]string{\"test\"})\n\n\tr := new(Router)\n\tcommon.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{\n\t\tManager:         mockOhm,\n\t\tHandlerSelector: mockHs,\n\t}, nil))\n\n\tctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80)})\n\troute, err := r.PickRoute(routing_session.AsRoutingContext(ctx))\n\tcommon.Must(err)\n\tif tag := route.GetOutboundTag(); tag != \"test\" {\n\t\tt.Error(\"expect tag 'test', bug actually \", tag)\n\t}\n}\n\n/*\n\nDo not work right now: need a full client setup\n\nfunc TestLeastLoadBalancer(t *testing.T) {\n\tconfig := &Config{\n\t\tRule: []*RoutingRule{\n\t\t\t{\n\t\t\t\tTargetTag: &RoutingRule_BalancingTag{\n\t\t\t\t\tBalancingTag: \"balance\",\n\t\t\t\t},\n\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t},\n\t\t},\n\t\tBalancingRule: []*BalancingRule{\n\t\t\t{\n\t\t\t\tTag:              \"balance\",\n\t\t\t\tOutboundSelector: []string{\"test-\"},\n\t\t\t\tStrategy:         \"leastLoad\",\n\t\t\t\tStrategySettings: serial.ToTypedMessage(&StrategyLeastLoadConfig{\n\t\t\t\t\tBaselines:   nil,\n\t\t\t\t\tExpected:    1,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t}\n\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockDNS := mocks.NewDNSClient(mockCtl)\n\tmockOhm := mocks.NewOutboundManager(mockCtl)\n\tmockHs := mocks.NewOutboundHandlerSelector(mockCtl)\n\n\tmockHs.EXPECT().Select(gomock.Eq([]string{\"test-\"})).Return([]string{\"test1\"})\n\n\tr := new(Router)\n\tcommon.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{\n\t\tManager:         mockOhm,\n\t\tHandlerSelector: mockHs,\n\t}, nil))\n\tctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2ray.com\"), 80)})\n\troute, err := r.PickRoute(routing_session.AsRoutingContext(ctx))\n\tcommon.Must(err)\n\tif tag := route.GetOutboundTag(); tag != \"test1\" {\n\t\tt.Error(\"expect tag 'test1', bug actually \", tag)\n\t}\n}*/\n\nfunc TestIPOnDemand(t *testing.T) {\n\tconfig := &Config{\n\t\tDomainStrategy: DomainStrategy_IpOnDemand,\n\t\tRule: []*RoutingRule{\n\t\t\t{\n\t\t\t\tTargetTag: &RoutingRule_Tag{\n\t\t\t\t\tTag: \"test\",\n\t\t\t\t},\n\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     []byte{192, 168, 0, 0},\n\t\t\t\t\t\tPrefix: 16,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockDNS := mocks.NewDNSClient(mockCtl)\n\tmockDNS.EXPECT().LookupIP(gomock.Eq(\"v2fly.org\")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()\n\n\tr := new(Router)\n\tcommon.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))\n\n\tctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80)})\n\troute, err := r.PickRoute(routing_session.AsRoutingContext(ctx))\n\tcommon.Must(err)\n\tif tag := route.GetOutboundTag(); tag != \"test\" {\n\t\tt.Error(\"expect tag 'test', bug actually \", tag)\n\t}\n}\n\nfunc TestIPIfNonMatchDomain(t *testing.T) {\n\tconfig := &Config{\n\t\tDomainStrategy: DomainStrategy_IpIfNonMatch,\n\t\tRule: []*RoutingRule{\n\t\t\t{\n\t\t\t\tTargetTag: &RoutingRule_Tag{\n\t\t\t\t\tTag: \"test\",\n\t\t\t\t},\n\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     []byte{192, 168, 0, 0},\n\t\t\t\t\t\tPrefix: 16,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockDNS := mocks.NewDNSClient(mockCtl)\n\tmockDNS.EXPECT().LookupIP(gomock.Eq(\"v2fly.org\")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()\n\n\tr := new(Router)\n\tcommon.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))\n\n\tctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80)})\n\troute, err := r.PickRoute(routing_session.AsRoutingContext(ctx))\n\tcommon.Must(err)\n\tif tag := route.GetOutboundTag(); tag != \"test\" {\n\t\tt.Error(\"expect tag 'test', bug actually \", tag)\n\t}\n}\n\nfunc TestIPIfNonMatchIP(t *testing.T) {\n\tconfig := &Config{\n\t\tDomainStrategy: DomainStrategy_IpIfNonMatch,\n\t\tRule: []*RoutingRule{\n\t\t\t{\n\t\t\t\tTargetTag: &RoutingRule_Tag{\n\t\t\t\t\tTag: \"test\",\n\t\t\t\t},\n\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t{\n\t\t\t\t\t\tIp:     []byte{127, 0, 0, 0},\n\t\t\t\t\t\tPrefix: 8,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockDNS := mocks.NewDNSClient(mockCtl)\n\n\tr := new(Router)\n\tcommon.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))\n\n\tctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)})\n\troute, err := r.PickRoute(routing_session.AsRoutingContext(ctx))\n\tcommon.Must(err)\n\tif tag := route.GetOutboundTag(); tag != \"test\" {\n\t\tt.Error(\"expect tag 'test', bug actually \", tag)\n\t}\n}\n"
  },
  {
    "path": "app/router/routercommon/common.pb.go",
    "content": "package routercommon\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// Type of domain value.\ntype Domain_Type int32\n\nconst (\n\t// The value is used as is.\n\tDomain_Plain Domain_Type = 0\n\t// The value is used as a regular expression.\n\tDomain_Regex Domain_Type = 1\n\t// The value is a root domain.\n\tDomain_RootDomain Domain_Type = 2\n\t// The value is a domain.\n\tDomain_Full Domain_Type = 3\n)\n\n// Enum value maps for Domain_Type.\nvar (\n\tDomain_Type_name = map[int32]string{\n\t\t0: \"Plain\",\n\t\t1: \"Regex\",\n\t\t2: \"RootDomain\",\n\t\t3: \"Full\",\n\t}\n\tDomain_Type_value = map[string]int32{\n\t\t\"Plain\":      0,\n\t\t\"Regex\":      1,\n\t\t\"RootDomain\": 2,\n\t\t\"Full\":       3,\n\t}\n)\n\nfunc (x Domain_Type) Enum() *Domain_Type {\n\tp := new(Domain_Type)\n\t*p = x\n\treturn p\n}\n\nfunc (x Domain_Type) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Domain_Type) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_app_router_routercommon_common_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Domain_Type) Type() protoreflect.EnumType {\n\treturn &file_app_router_routercommon_common_proto_enumTypes[0]\n}\n\nfunc (x Domain_Type) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Domain_Type.Descriptor instead.\nfunc (Domain_Type) EnumDescriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{0, 0}\n}\n\n// Domain for routing decision.\ntype Domain struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Domain matching type.\n\tType Domain_Type `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.app.router.routercommon.Domain_Type\" json:\"type,omitempty\"`\n\t// Domain value.\n\tValue string `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n\t// Attributes of this domain. May be used for filtering.\n\tAttribute     []*Domain_Attribute `protobuf:\"bytes,3,rep,name=attribute,proto3\" json:\"attribute,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Domain) Reset() {\n\t*x = Domain{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Domain) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Domain) ProtoMessage() {}\n\nfunc (x *Domain) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[0]\n\tif 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 Domain.ProtoReflect.Descriptor instead.\nfunc (*Domain) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Domain) GetType() Domain_Type {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn Domain_Plain\n}\n\nfunc (x *Domain) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *Domain) GetAttribute() []*Domain_Attribute {\n\tif x != nil {\n\t\treturn x.Attribute\n\t}\n\treturn nil\n}\n\n// IP for routing decision, in CIDR form.\ntype CIDR struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// IP address, should be either 4 or 16 bytes.\n\tIp []byte `protobuf:\"bytes,1,opt,name=ip,proto3\" json:\"ip,omitempty\"`\n\t// Number of leading ones in the network mask.\n\tPrefix        uint32 `protobuf:\"varint,2,opt,name=prefix,proto3\" json:\"prefix,omitempty\"`\n\tIpAddr        string `protobuf:\"bytes,68000,opt,name=ip_addr,json=ipAddr,proto3\" json:\"ip_addr,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *CIDR) Reset() {\n\t*x = CIDR{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *CIDR) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*CIDR) ProtoMessage() {}\n\nfunc (x *CIDR) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[1]\n\tif 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 CIDR.ProtoReflect.Descriptor instead.\nfunc (*CIDR) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *CIDR) GetIp() []byte {\n\tif x != nil {\n\t\treturn x.Ip\n\t}\n\treturn nil\n}\n\nfunc (x *CIDR) GetPrefix() uint32 {\n\tif x != nil {\n\t\treturn x.Prefix\n\t}\n\treturn 0\n}\n\nfunc (x *CIDR) GetIpAddr() string {\n\tif x != nil {\n\t\treturn x.IpAddr\n\t}\n\treturn \"\"\n}\n\ntype GeoIP struct {\n\tstate        protoimpl.MessageState `protogen:\"open.v1\"`\n\tCountryCode  string                 `protobuf:\"bytes,1,opt,name=country_code,json=countryCode,proto3\" json:\"country_code,omitempty\"`\n\tCidr         []*CIDR                `protobuf:\"bytes,2,rep,name=cidr,proto3\" json:\"cidr,omitempty\"`\n\tInverseMatch bool                   `protobuf:\"varint,3,opt,name=inverse_match,json=inverseMatch,proto3\" json:\"inverse_match,omitempty\"`\n\t// resource_hash instruct simplified config converter to load domain from geo file.\n\tResourceHash  []byte `protobuf:\"bytes,4,opt,name=resource_hash,json=resourceHash,proto3\" json:\"resource_hash,omitempty\"`\n\tCode          string `protobuf:\"bytes,5,opt,name=code,proto3\" json:\"code,omitempty\"`\n\tFilePath      string `protobuf:\"bytes,68000,opt,name=file_path,json=filePath,proto3\" json:\"file_path,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GeoIP) Reset() {\n\t*x = GeoIP{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GeoIP) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GeoIP) ProtoMessage() {}\n\nfunc (x *GeoIP) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[2]\n\tif 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 GeoIP.ProtoReflect.Descriptor instead.\nfunc (*GeoIP) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *GeoIP) GetCountryCode() string {\n\tif x != nil {\n\t\treturn x.CountryCode\n\t}\n\treturn \"\"\n}\n\nfunc (x *GeoIP) GetCidr() []*CIDR {\n\tif x != nil {\n\t\treturn x.Cidr\n\t}\n\treturn nil\n}\n\nfunc (x *GeoIP) GetInverseMatch() bool {\n\tif x != nil {\n\t\treturn x.InverseMatch\n\t}\n\treturn false\n}\n\nfunc (x *GeoIP) GetResourceHash() []byte {\n\tif x != nil {\n\t\treturn x.ResourceHash\n\t}\n\treturn nil\n}\n\nfunc (x *GeoIP) GetCode() string {\n\tif x != nil {\n\t\treturn x.Code\n\t}\n\treturn \"\"\n}\n\nfunc (x *GeoIP) GetFilePath() string {\n\tif x != nil {\n\t\treturn x.FilePath\n\t}\n\treturn \"\"\n}\n\ntype GeoIPList struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tEntry         []*GeoIP               `protobuf:\"bytes,1,rep,name=entry,proto3\" json:\"entry,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GeoIPList) Reset() {\n\t*x = GeoIPList{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GeoIPList) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GeoIPList) ProtoMessage() {}\n\nfunc (x *GeoIPList) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[3]\n\tif 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 GeoIPList.ProtoReflect.Descriptor instead.\nfunc (*GeoIPList) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *GeoIPList) GetEntry() []*GeoIP {\n\tif x != nil {\n\t\treturn x.Entry\n\t}\n\treturn nil\n}\n\ntype GeoSite struct {\n\tstate       protoimpl.MessageState `protogen:\"open.v1\"`\n\tCountryCode string                 `protobuf:\"bytes,1,opt,name=country_code,json=countryCode,proto3\" json:\"country_code,omitempty\"`\n\tDomain      []*Domain              `protobuf:\"bytes,2,rep,name=domain,proto3\" json:\"domain,omitempty\"`\n\t// resource_hash instruct simplified config converter to load domain from geo file.\n\tResourceHash  []byte `protobuf:\"bytes,3,opt,name=resource_hash,json=resourceHash,proto3\" json:\"resource_hash,omitempty\"`\n\tCode          string `protobuf:\"bytes,4,opt,name=code,proto3\" json:\"code,omitempty\"`\n\tFilePath      string `protobuf:\"bytes,68000,opt,name=file_path,json=filePath,proto3\" json:\"file_path,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GeoSite) Reset() {\n\t*x = GeoSite{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GeoSite) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GeoSite) ProtoMessage() {}\n\nfunc (x *GeoSite) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[4]\n\tif 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 GeoSite.ProtoReflect.Descriptor instead.\nfunc (*GeoSite) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *GeoSite) GetCountryCode() string {\n\tif x != nil {\n\t\treturn x.CountryCode\n\t}\n\treturn \"\"\n}\n\nfunc (x *GeoSite) GetDomain() []*Domain {\n\tif x != nil {\n\t\treturn x.Domain\n\t}\n\treturn nil\n}\n\nfunc (x *GeoSite) GetResourceHash() []byte {\n\tif x != nil {\n\t\treturn x.ResourceHash\n\t}\n\treturn nil\n}\n\nfunc (x *GeoSite) GetCode() string {\n\tif x != nil {\n\t\treturn x.Code\n\t}\n\treturn \"\"\n}\n\nfunc (x *GeoSite) GetFilePath() string {\n\tif x != nil {\n\t\treturn x.FilePath\n\t}\n\treturn \"\"\n}\n\ntype GeoSiteList struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tEntry         []*GeoSite             `protobuf:\"bytes,1,rep,name=entry,proto3\" json:\"entry,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GeoSiteList) Reset() {\n\t*x = GeoSiteList{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GeoSiteList) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GeoSiteList) ProtoMessage() {}\n\nfunc (x *GeoSiteList) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[5]\n\tif 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 GeoSiteList.ProtoReflect.Descriptor instead.\nfunc (*GeoSiteList) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *GeoSiteList) GetEntry() []*GeoSite {\n\tif x != nil {\n\t\treturn x.Entry\n\t}\n\treturn nil\n}\n\ntype Domain_Attribute struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\tKey   string                 `protobuf:\"bytes,1,opt,name=key,proto3\" json:\"key,omitempty\"`\n\t// Types that are valid to be assigned to TypedValue:\n\t//\n\t//\t*Domain_Attribute_BoolValue\n\t//\t*Domain_Attribute_IntValue\n\tTypedValue    isDomain_Attribute_TypedValue `protobuf_oneof:\"typed_value\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Domain_Attribute) Reset() {\n\t*x = Domain_Attribute{}\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Domain_Attribute) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Domain_Attribute) ProtoMessage() {}\n\nfunc (x *Domain_Attribute) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_router_routercommon_common_proto_msgTypes[6]\n\tif 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 Domain_Attribute.ProtoReflect.Descriptor instead.\nfunc (*Domain_Attribute) Descriptor() ([]byte, []int) {\n\treturn file_app_router_routercommon_common_proto_rawDescGZIP(), []int{0, 0}\n}\n\nfunc (x *Domain_Attribute) GetKey() string {\n\tif x != nil {\n\t\treturn x.Key\n\t}\n\treturn \"\"\n}\n\nfunc (x *Domain_Attribute) GetTypedValue() isDomain_Attribute_TypedValue {\n\tif x != nil {\n\t\treturn x.TypedValue\n\t}\n\treturn nil\n}\n\nfunc (x *Domain_Attribute) GetBoolValue() bool {\n\tif x != nil {\n\t\tif x, ok := x.TypedValue.(*Domain_Attribute_BoolValue); ok {\n\t\t\treturn x.BoolValue\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (x *Domain_Attribute) GetIntValue() int64 {\n\tif x != nil {\n\t\tif x, ok := x.TypedValue.(*Domain_Attribute_IntValue); ok {\n\t\t\treturn x.IntValue\n\t\t}\n\t}\n\treturn 0\n}\n\ntype isDomain_Attribute_TypedValue interface {\n\tisDomain_Attribute_TypedValue()\n}\n\ntype Domain_Attribute_BoolValue struct {\n\tBoolValue bool `protobuf:\"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof\"`\n}\n\ntype Domain_Attribute_IntValue struct {\n\tIntValue int64 `protobuf:\"varint,3,opt,name=int_value,json=intValue,proto3,oneof\"`\n}\n\nfunc (*Domain_Attribute_BoolValue) isDomain_Attribute_TypedValue() {}\n\nfunc (*Domain_Attribute_IntValue) isDomain_Attribute_TypedValue() {}\n\nvar File_app_router_routercommon_common_proto protoreflect.FileDescriptor\n\nconst file_app_router_routercommon_common_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$app/router/routercommon/common.proto\\x12\\\"v2ray.core.app.router.routercommon\\x1a common/protoext/extensions.proto\\\"\\xdd\\x02\\n\" +\n\t\"\\x06Domain\\x12C\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2/.v2ray.core.app.router.routercommon.Domain.TypeR\\x04type\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value\\x12R\\n\" +\n\t\"\\tattribute\\x18\\x03 \\x03(\\v24.v2ray.core.app.router.routercommon.Domain.AttributeR\\tattribute\\x1al\\n\" +\n\t\"\\tAttribute\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x1f\\n\" +\n\t\"\\n\" +\n\t\"bool_value\\x18\\x02 \\x01(\\bH\\x00R\\tboolValue\\x12\\x1d\\n\" +\n\t\"\\tint_value\\x18\\x03 \\x01(\\x03H\\x00R\\bintValueB\\r\\n\" +\n\t\"\\vtyped_value\\\"6\\n\" +\n\t\"\\x04Type\\x12\\t\\n\" +\n\t\"\\x05Plain\\x10\\x00\\x12\\t\\n\" +\n\t\"\\x05Regex\\x10\\x01\\x12\\x0e\\n\" +\n\t\"\\n\" +\n\t\"RootDomain\\x10\\x02\\x12\\b\\n\" +\n\t\"\\x04Full\\x10\\x03\\\"S\\n\" +\n\t\"\\x04CIDR\\x12\\x0e\\n\" +\n\t\"\\x02ip\\x18\\x01 \\x01(\\fR\\x02ip\\x12\\x16\\n\" +\n\t\"\\x06prefix\\x18\\x02 \\x01(\\rR\\x06prefix\\x12#\\n\" +\n\t\"\\aip_addr\\x18\\xa0\\x93\\x04 \\x01(\\tB\\b\\x82\\xb5\\x18\\x04:\\x02ipR\\x06ipAddr\\\"\\xfa\\x01\\n\" +\n\t\"\\x05GeoIP\\x12!\\n\" +\n\t\"\\fcountry_code\\x18\\x01 \\x01(\\tR\\vcountryCode\\x12<\\n\" +\n\t\"\\x04cidr\\x18\\x02 \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRR\\x04cidr\\x12#\\n\" +\n\t\"\\rinverse_match\\x18\\x03 \\x01(\\bR\\finverseMatch\\x12#\\n\" +\n\t\"\\rresource_hash\\x18\\x04 \\x01(\\fR\\fresourceHash\\x12\\x12\\n\" +\n\t\"\\x04code\\x18\\x05 \\x01(\\tR\\x04code\\x122\\n\" +\n\t\"\\tfile_path\\x18\\xa0\\x93\\x04 \\x01(\\tB\\x13\\x82\\xb5\\x18\\x0f2\\rresource_hashR\\bfilePath\\\"L\\n\" +\n\t\"\\tGeoIPList\\x12?\\n\" +\n\t\"\\x05entry\\x18\\x01 \\x03(\\v2).v2ray.core.app.router.routercommon.GeoIPR\\x05entry\\\"\\xdd\\x01\\n\" +\n\t\"\\aGeoSite\\x12!\\n\" +\n\t\"\\fcountry_code\\x18\\x01 \\x01(\\tR\\vcountryCode\\x12B\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x03(\\v2*.v2ray.core.app.router.routercommon.DomainR\\x06domain\\x12#\\n\" +\n\t\"\\rresource_hash\\x18\\x03 \\x01(\\fR\\fresourceHash\\x12\\x12\\n\" +\n\t\"\\x04code\\x18\\x04 \\x01(\\tR\\x04code\\x122\\n\" +\n\t\"\\tfile_path\\x18\\xa0\\x93\\x04 \\x01(\\tB\\x13\\x82\\xb5\\x18\\x0f2\\rresource_hashR\\bfilePath\\\"P\\n\" +\n\t\"\\vGeoSiteList\\x12A\\n\" +\n\t\"\\x05entry\\x18\\x01 \\x03(\\v2+.v2ray.core.app.router.routercommon.GeoSiteR\\x05entryB\\x87\\x01\\n\" +\n\t\"&com.v2ray.core.app.router.routercommonP\\x01Z6github.com/v2fly/v2ray-core/v5/app/router/routercommon\\xaa\\x02\\\"V2Ray.Core.App.Router.Routercommonb\\x06proto3\"\n\nvar (\n\tfile_app_router_routercommon_common_proto_rawDescOnce sync.Once\n\tfile_app_router_routercommon_common_proto_rawDescData []byte\n)\n\nfunc file_app_router_routercommon_common_proto_rawDescGZIP() []byte {\n\tfile_app_router_routercommon_common_proto_rawDescOnce.Do(func() {\n\t\tfile_app_router_routercommon_common_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_router_routercommon_common_proto_rawDesc), len(file_app_router_routercommon_common_proto_rawDesc)))\n\t})\n\treturn file_app_router_routercommon_common_proto_rawDescData\n}\n\nvar file_app_router_routercommon_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_app_router_routercommon_common_proto_msgTypes = make([]protoimpl.MessageInfo, 7)\nvar file_app_router_routercommon_common_proto_goTypes = []any{\n\t(Domain_Type)(0),         // 0: v2ray.core.app.router.routercommon.Domain.Type\n\t(*Domain)(nil),           // 1: v2ray.core.app.router.routercommon.Domain\n\t(*CIDR)(nil),             // 2: v2ray.core.app.router.routercommon.CIDR\n\t(*GeoIP)(nil),            // 3: v2ray.core.app.router.routercommon.GeoIP\n\t(*GeoIPList)(nil),        // 4: v2ray.core.app.router.routercommon.GeoIPList\n\t(*GeoSite)(nil),          // 5: v2ray.core.app.router.routercommon.GeoSite\n\t(*GeoSiteList)(nil),      // 6: v2ray.core.app.router.routercommon.GeoSiteList\n\t(*Domain_Attribute)(nil), // 7: v2ray.core.app.router.routercommon.Domain.Attribute\n}\nvar file_app_router_routercommon_common_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.router.routercommon.Domain.type:type_name -> v2ray.core.app.router.routercommon.Domain.Type\n\t7, // 1: v2ray.core.app.router.routercommon.Domain.attribute:type_name -> v2ray.core.app.router.routercommon.Domain.Attribute\n\t2, // 2: v2ray.core.app.router.routercommon.GeoIP.cidr:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t3, // 3: v2ray.core.app.router.routercommon.GeoIPList.entry:type_name -> v2ray.core.app.router.routercommon.GeoIP\n\t1, // 4: v2ray.core.app.router.routercommon.GeoSite.domain:type_name -> v2ray.core.app.router.routercommon.Domain\n\t5, // 5: v2ray.core.app.router.routercommon.GeoSiteList.entry:type_name -> v2ray.core.app.router.routercommon.GeoSite\n\t6, // [6:6] is the sub-list for method output_type\n\t6, // [6:6] is the sub-list for method input_type\n\t6, // [6:6] is the sub-list for extension type_name\n\t6, // [6:6] is the sub-list for extension extendee\n\t0, // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_app_router_routercommon_common_proto_init() }\nfunc file_app_router_routercommon_common_proto_init() {\n\tif File_app_router_routercommon_common_proto != nil {\n\t\treturn\n\t}\n\tfile_app_router_routercommon_common_proto_msgTypes[6].OneofWrappers = []any{\n\t\t(*Domain_Attribute_BoolValue)(nil),\n\t\t(*Domain_Attribute_IntValue)(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: unsafe.Slice(unsafe.StringData(file_app_router_routercommon_common_proto_rawDesc), len(file_app_router_routercommon_common_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   7,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_router_routercommon_common_proto_goTypes,\n\t\tDependencyIndexes: file_app_router_routercommon_common_proto_depIdxs,\n\t\tEnumInfos:         file_app_router_routercommon_common_proto_enumTypes,\n\t\tMessageInfos:      file_app_router_routercommon_common_proto_msgTypes,\n\t}.Build()\n\tFile_app_router_routercommon_common_proto = out.File\n\tfile_app_router_routercommon_common_proto_goTypes = nil\n\tfile_app_router_routercommon_common_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/router/routercommon/common.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.router.routercommon;\noption csharp_namespace = \"V2Ray.Core.App.Router.Routercommon\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/router/routercommon\";\noption java_package = \"com.v2ray.core.app.router.routercommon\";\noption java_multiple_files = true;\n\n\nimport \"common/protoext/extensions.proto\";\n\n// Domain for routing decision.\nmessage Domain {\n  // Type of domain value.\n  enum Type {\n    // The value is used as is.\n    Plain = 0;\n    // The value is used as a regular expression.\n    Regex = 1;\n    // The value is a root domain.\n    RootDomain = 2;\n    // The value is a domain.\n    Full = 3;\n  }\n\n  // Domain matching type.\n  Type type = 1;\n\n  // Domain value.\n  string value = 2;\n\n  message Attribute {\n    string key = 1;\n\n    oneof typed_value {\n      bool bool_value = 2;\n      int64 int_value = 3;\n    }\n  }\n\n  // Attributes of this domain. May be used for filtering.\n  repeated Attribute attribute = 3;\n}\n\n// IP for routing decision, in CIDR form.\nmessage CIDR {\n  // IP address, should be either 4 or 16 bytes.\n  bytes ip = 1;\n\n  // Number of leading ones in the network mask.\n  uint32 prefix = 2;\n\n  string ip_addr = 68000 [(v2ray.core.common.protoext.field_opt).convert_time_parse_ip = \"ip\"];\n}\n\nmessage GeoIP {\n  string country_code = 1;\n  repeated CIDR cidr = 2;\n  bool inverse_match = 3;\n\n  // resource_hash instruct simplified config converter to load domain from geo file.\n  bytes resource_hash = 4;\n  string code = 5;\n\n  string file_path = 68000[(v2ray.core.common.protoext.field_opt).convert_time_resource_loading = \"resource_hash\"];\n}\n\nmessage GeoIPList {\n  repeated GeoIP entry = 1;\n}\n\nmessage GeoSite {\n  string country_code = 1;\n  repeated Domain domain = 2;\n\n  // resource_hash instruct simplified config converter to load domain from geo file.\n  bytes resource_hash = 3;\n  string code = 4;\n\n  string file_path = 68000[(v2ray.core.common.protoext.field_opt).convert_time_resource_loading = \"resource_hash\"];\n}\n\nmessage GeoSiteList {\n  repeated GeoSite entry = 1;\n}\n"
  },
  {
    "path": "app/router/strategy_leastload.go",
    "content": "package router\n\nimport (\n\t\"context\"\n\t\"math\"\n\t\"sort\"\n\t\"time\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\n// LeastLoadStrategy represents a least load balancing strategy\ntype LeastLoadStrategy struct {\n\tsettings *StrategyLeastLoadConfig\n\tcosts    *WeightManager\n\n\tobserver extension.Observatory\n\n\tctx context.Context\n}\n\nfunc (l *LeastLoadStrategy) GetPrincipleTarget(strings []string) []string {\n\tvar ret []string\n\tnodes := l.pickOutbounds(strings)\n\tfor _, v := range nodes {\n\t\tret = append(ret, v.Tag)\n\t}\n\treturn ret\n}\n\n// NewLeastLoadStrategy creates a new LeastLoadStrategy with settings\nfunc NewLeastLoadStrategy(settings *StrategyLeastLoadConfig) *LeastLoadStrategy {\n\treturn &LeastLoadStrategy{\n\t\tsettings: settings,\n\t\tcosts: NewWeightManager(\n\t\t\tsettings.Costs, 1,\n\t\t\tfunc(value, cost float64) float64 {\n\t\t\t\treturn value * math.Pow(cost, 0.5)\n\t\t\t},\n\t\t),\n\t}\n}\n\n// node is a minimal copy of HealthCheckResult\n// we don't use HealthCheckResult directly because\n// it may change by health checker during routing\ntype node struct {\n\tTag              string\n\tCountAll         int\n\tCountFail        int\n\tRTTAverage       time.Duration\n\tRTTDeviation     time.Duration\n\tRTTDeviationCost time.Duration\n}\n\nfunc (l *LeastLoadStrategy) InjectContext(ctx context.Context) {\n\tl.ctx = ctx\n}\n\nfunc (l *LeastLoadStrategy) PickOutbound(candidates []string) string {\n\tselects := l.pickOutbounds(candidates)\n\tcount := len(selects)\n\tif count == 0 {\n\t\t// goes to fallbackTag\n\t\treturn \"\"\n\t}\n\treturn selects[dice.Roll(count)].Tag\n}\n\nfunc (l *LeastLoadStrategy) pickOutbounds(candidates []string) []*node {\n\tqualified := l.getNodes(candidates, time.Duration(l.settings.MaxRTT))\n\tselects := l.selectLeastLoad(qualified)\n\treturn selects\n}\n\n// selectLeastLoad selects nodes according to Baselines and Expected Count.\n//\n// The strategy always improves network response speed, not matter which mode below is configured.\n// But they can still have different priorities.\n//\n// 1. Bandwidth priority: no Baseline + Expected Count > 0.: selects `Expected Count` of nodes.\n// (one if Expected Count <= 0)\n//\n// 2. Bandwidth priority advanced: Baselines + Expected Count > 0.\n// Select `Expected Count` amount of nodes, and also those near them according to baselines.\n// In other words, it selects according to different Baselines, until one of them matches\n// the Expected Count, if no Baseline matches, Expected Count applied.\n//\n// 3. Speed priority: Baselines + `Expected Count <= 0`.\n// go through all baselines until find selects, if not, select none. Used in combination\n// with 'balancer.fallbackTag', it means: selects qualified nodes or use the fallback.\nfunc (l *LeastLoadStrategy) selectLeastLoad(nodes []*node) []*node {\n\tif len(nodes) == 0 {\n\t\tnewError(\"least load: no qualified outbound\").AtInfo().WriteToLog()\n\t\treturn nil\n\t}\n\texpected := int(l.settings.Expected)\n\tavailableCount := len(nodes)\n\tif expected > availableCount {\n\t\treturn nodes\n\t}\n\n\tif expected <= 0 {\n\t\texpected = 1\n\t}\n\tif len(l.settings.Baselines) == 0 {\n\t\treturn nodes[:expected]\n\t}\n\n\tcount := 0\n\t// go through all base line until find expected selects\n\tfor _, b := range l.settings.Baselines {\n\t\tbaseline := time.Duration(b)\n\t\tfor i := count; i < availableCount; i++ {\n\t\t\tif nodes[i].RTTDeviationCost >= baseline {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcount = i + 1\n\t\t}\n\t\t// don't continue if find expected selects\n\t\tif count >= expected {\n\t\t\tnewError(\"applied baseline: \", baseline).AtDebug().WriteToLog()\n\t\t\tbreak\n\t\t}\n\t}\n\tif l.settings.Expected > 0 && count < expected {\n\t\tcount = expected\n\t}\n\treturn nodes[:count]\n}\n\nfunc (l *LeastLoadStrategy) getNodes(candidates []string, maxRTT time.Duration) []*node {\n\tif l.observer == nil {\n\t\tcommon.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error {\n\t\t\tl.observer = observatory\n\t\t\treturn nil\n\t\t}))\n\t}\n\n\tvar result proto.Message\n\tif l.settings.ObserverTag == \"\" {\n\t\tobserveResult, err := l.observer.GetObservation(l.ctx)\n\t\tif err != nil {\n\t\t\tnewError(\"cannot get observation\").Base(err).WriteToLog()\n\t\t\treturn make([]*node, 0)\n\t\t}\n\t\tresult = observeResult\n\t} else {\n\t\tobserveResult, err := common.Must2(l.observer.(features.TaggedFeatures).GetFeaturesByTag(l.settings.ObserverTag)).(extension.Observatory).GetObservation(l.ctx)\n\t\tif err != nil {\n\t\t\tnewError(\"cannot get observation\").Base(err).WriteToLog()\n\t\t\treturn make([]*node, 0)\n\t\t}\n\t\tresult = observeResult\n\t}\n\n\tresults := result.(*observatory.ObservationResult)\n\n\toutboundlist := outboundList(candidates)\n\n\tvar ret []*node\n\n\tfor _, v := range results.Status {\n\t\tif v.Alive && (v.Delay < maxRTT.Milliseconds() || maxRTT == 0) && outboundlist.contains(v.OutboundTag) {\n\t\t\trecord := &node{\n\t\t\t\tTag:              v.OutboundTag,\n\t\t\t\tCountAll:         1,\n\t\t\t\tCountFail:        1,\n\t\t\t\tRTTAverage:       time.Duration(v.Delay) * time.Millisecond,\n\t\t\t\tRTTDeviation:     time.Duration(v.Delay) * time.Millisecond,\n\t\t\t\tRTTDeviationCost: time.Duration(l.costs.Apply(v.OutboundTag, float64(time.Duration(v.Delay)*time.Millisecond))),\n\t\t\t}\n\n\t\t\tif v.HealthPing != nil {\n\t\t\t\trecord.RTTAverage = time.Duration(v.HealthPing.Average)\n\t\t\t\trecord.RTTDeviation = time.Duration(v.HealthPing.Deviation)\n\t\t\t\trecord.RTTDeviationCost = time.Duration(l.costs.Apply(v.OutboundTag, float64(v.HealthPing.Deviation)))\n\t\t\t\trecord.CountAll = int(v.HealthPing.All)\n\t\t\t\trecord.CountFail = int(v.HealthPing.Fail)\n\t\t\t}\n\t\t\tret = append(ret, record)\n\t\t}\n\t}\n\n\tleastloadSort(ret)\n\treturn ret\n}\n\nfunc leastloadSort(nodes []*node) {\n\tsort.Slice(nodes, func(i, j int) bool {\n\t\tleft := nodes[i]\n\t\tright := nodes[j]\n\t\tif left.RTTDeviationCost != right.RTTDeviationCost {\n\t\t\treturn left.RTTDeviationCost < right.RTTDeviationCost\n\t\t}\n\t\tif left.RTTAverage != right.RTTAverage {\n\t\t\treturn left.RTTAverage < right.RTTAverage\n\t\t}\n\t\tif left.CountFail != right.CountFail {\n\t\t\treturn left.CountFail < right.CountFail\n\t\t}\n\t\tif left.CountAll != right.CountAll {\n\t\t\treturn left.CountAll > right.CountAll\n\t\t}\n\t\treturn left.Tag < right.Tag\n\t})\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*StrategyLeastLoadConfig)(nil), nil))\n}\n"
  },
  {
    "path": "app/router/strategy_leastload_test.go",
    "content": "package router\n\nimport (\n\t\"testing\"\n)\n\n/*\nSplit into multiple package, need to be tested separately\n\n\tfunc TestSelectLeastLoad(t *testing.T) {\n\t\tsettings := &StrategyLeastLoadConfig{\n\t\t\tHealthCheck: &HealthPingConfig{\n\t\t\t\tSamplingCount: 10,\n\t\t\t},\n\t\t\tExpected: 1,\n\t\t\tMaxRTT:   int64(time.Millisecond * time.Duration(800)),\n\t\t}\n\t\tstrategy := NewLeastLoadStrategy(settings)\n\t\t// std 40\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(60))\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(140))\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(60))\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(140))\n\t\t// std 60\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(40))\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(160))\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(40))\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(160))\n\t\t// std 0, but >MaxRTT\n\t\tstrategy.PutResult(\"c\", time.Millisecond*time.Duration(1000))\n\t\tstrategy.PutResult(\"c\", time.Millisecond*time.Duration(1000))\n\t\tstrategy.PutResult(\"c\", time.Millisecond*time.Duration(1000))\n\t\tstrategy.PutResult(\"c\", time.Millisecond*time.Duration(1000))\n\t\texpected := \"a\"\n\t\tactual := strategy.SelectAndPick([]string{\"a\", \"b\", \"c\", \"untested\"})\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"expected: %v, actual: %v\", expected, actual)\n\t\t}\n\t}\n\n\tfunc TestSelectLeastLoadWithCost(t *testing.T) {\n\t\tsettings := &StrategyLeastLoadConfig{\n\t\t\tHealthCheck: &HealthPingConfig{\n\t\t\t\tSamplingCount: 10,\n\t\t\t},\n\t\t\tCosts: []*StrategyWeight{\n\t\t\t\t{Match: \"a\", Value: 9},\n\t\t\t},\n\t\t\tExpected: 1,\n\t\t}\n\t\tstrategy := NewLeastLoadStrategy(settings, nil)\n\t\t// std 40, std+c 120\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(60))\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(140))\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(60))\n\t\tstrategy.PutResult(\"a\", time.Millisecond*time.Duration(140))\n\t\t// std 60\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(40))\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(160))\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(40))\n\t\tstrategy.PutResult(\"b\", time.Millisecond*time.Duration(160))\n\t\texpected := \"b\"\n\t\tactual := strategy.SelectAndPick([]string{\"a\", \"b\", \"untested\"})\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"expected: %v, actual: %v\", expected, actual)\n\t\t}\n\t}\n*/\nfunc TestSelectLeastExpected(t *testing.T) {\n\tstrategy := &LeastLoadStrategy{\n\t\tsettings: &StrategyLeastLoadConfig{\n\t\t\tBaselines: nil,\n\t\t\tExpected:  3,\n\t\t},\n\t}\n\tnodes := []*node{\n\t\t{Tag: \"a\", RTTDeviationCost: 100},\n\t\t{Tag: \"b\", RTTDeviationCost: 200},\n\t\t{Tag: \"c\", RTTDeviationCost: 300},\n\t\t{Tag: \"d\", RTTDeviationCost: 350},\n\t}\n\texpected := 3\n\tns := strategy.selectLeastLoad(nodes)\n\tif len(ns) != expected {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, len(ns))\n\t}\n}\n\nfunc TestSelectLeastExpected2(t *testing.T) {\n\tstrategy := &LeastLoadStrategy{\n\t\tsettings: &StrategyLeastLoadConfig{\n\t\t\tBaselines: nil,\n\t\t\tExpected:  3,\n\t\t},\n\t}\n\tnodes := []*node{\n\t\t{Tag: \"a\", RTTDeviationCost: 100},\n\t\t{Tag: \"b\", RTTDeviationCost: 200},\n\t}\n\texpected := 2\n\tns := strategy.selectLeastLoad(nodes)\n\tif len(ns) != expected {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, len(ns))\n\t}\n}\n\nfunc TestSelectLeastExpectedAndBaselines(t *testing.T) {\n\tstrategy := &LeastLoadStrategy{\n\t\tsettings: &StrategyLeastLoadConfig{\n\t\t\tBaselines: []int64{200, 300, 400},\n\t\t\tExpected:  3,\n\t\t},\n\t}\n\tnodes := []*node{\n\t\t{Tag: \"a\", RTTDeviationCost: 100},\n\t\t{Tag: \"b\", RTTDeviationCost: 200},\n\t\t{Tag: \"c\", RTTDeviationCost: 250},\n\t\t{Tag: \"d\", RTTDeviationCost: 300},\n\t\t{Tag: \"e\", RTTDeviationCost: 310},\n\t}\n\texpected := 3\n\tns := strategy.selectLeastLoad(nodes)\n\tif len(ns) != expected {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, len(ns))\n\t}\n}\n\nfunc TestSelectLeastExpectedAndBaselines2(t *testing.T) {\n\tstrategy := &LeastLoadStrategy{\n\t\tsettings: &StrategyLeastLoadConfig{\n\t\t\tBaselines: []int64{200, 300, 400},\n\t\t\tExpected:  3,\n\t\t},\n\t}\n\tnodes := []*node{\n\t\t{Tag: \"a\", RTTDeviationCost: 500},\n\t\t{Tag: \"b\", RTTDeviationCost: 600},\n\t\t{Tag: \"c\", RTTDeviationCost: 700},\n\t\t{Tag: \"d\", RTTDeviationCost: 800},\n\t\t{Tag: \"e\", RTTDeviationCost: 900},\n\t}\n\texpected := 3\n\tns := strategy.selectLeastLoad(nodes)\n\tif len(ns) != expected {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, len(ns))\n\t}\n}\n\nfunc TestSelectLeastLoadBaselines(t *testing.T) {\n\tstrategy := &LeastLoadStrategy{\n\t\tsettings: &StrategyLeastLoadConfig{\n\t\t\tBaselines: []int64{200, 400, 600},\n\t\t\tExpected:  0,\n\t\t},\n\t}\n\tnodes := []*node{\n\t\t{Tag: \"a\", RTTDeviationCost: 100},\n\t\t{Tag: \"b\", RTTDeviationCost: 200},\n\t\t{Tag: \"c\", RTTDeviationCost: 300},\n\t}\n\texpected := 1\n\tns := strategy.selectLeastLoad(nodes)\n\tif len(ns) != expected {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, len(ns))\n\t}\n}\n\nfunc TestSelectLeastLoadBaselinesNoQualified(t *testing.T) {\n\tstrategy := &LeastLoadStrategy{\n\t\tsettings: &StrategyLeastLoadConfig{\n\t\t\tBaselines: []int64{200, 400, 600},\n\t\t\tExpected:  0,\n\t\t},\n\t}\n\tnodes := []*node{\n\t\t{Tag: \"a\", RTTDeviationCost: 800},\n\t\t{Tag: \"b\", RTTDeviationCost: 1000},\n\t}\n\texpected := 0\n\tns := strategy.selectLeastLoad(nodes)\n\tif len(ns) != expected {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, len(ns))\n\t}\n}\n"
  },
  {
    "path": "app/router/strategy_leastping.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage router\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\ntype LeastPingStrategy struct {\n\tctx         context.Context\n\tobservatory extension.Observatory\n\n\tconfig *StrategyLeastPingConfig\n\n\tlock       sync.Mutex\n\tlastChoice string\n}\n\nfunc (l *LeastPingStrategy) GetPrincipleTarget(strings []string) []string {\n\treturn []string{l.PickOutbound(strings)}\n}\n\nfunc (l *LeastPingStrategy) InjectContext(ctx context.Context) {\n\tl.ctx = ctx\n}\n\nfunc (l *LeastPingStrategy) PickOutbound(strings []string) string {\n\tif l.observatory == nil {\n\t\tcommon.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error {\n\t\t\tif l.config.ObserverTag != \"\" {\n\t\t\t\tl.observatory = common.Must2(observatory.(features.TaggedFeatures).GetFeaturesByTag(l.config.ObserverTag)).(extension.Observatory)\n\t\t\t} else {\n\t\t\t\tl.observatory = observatory\n\t\t\t}\n\t\t\treturn nil\n\t\t}))\n\t}\n\n\tif l.observatory == nil {\n\t\tnewError(\"cannot find observatory\").WriteToLog()\n\t\treturn \"\"\n\t}\n\n\tobserveReport, err := l.observatory.GetObservation(l.ctx)\n\tif err != nil {\n\t\tnewError(\"cannot get observe report\").Base(err).WriteToLog()\n\t\treturn \"\"\n\t}\n\toutboundsList := outboundList(strings)\n\tif result, ok := observeReport.(*observatory.ObservationResult); ok {\n\t\tstatus := result.Status\n\t\tleastPing := int64(99999999)\n\t\tselectedOutboundName := \"\"\n\t\tfor _, v := range status {\n\t\t\tif outboundsList.contains(v.OutboundTag) && v.Alive && v.Delay < leastPing {\n\t\t\t\tselectedOutboundName = v.OutboundTag\n\t\t\t\tleastPing = v.Delay\n\t\t\t}\n\t\t}\n\t\t{\n\t\t\tl.lock.Lock()\n\t\t\tif selectedOutboundName == \"\" && l.config.StickyChoice {\n\t\t\t\tselectedOutboundName = l.lastChoice\n\t\t\t}\n\t\t\tl.lastChoice = selectedOutboundName\n\t\t\tl.lock.Unlock()\n\t\t}\n\t\treturn selectedOutboundName\n\t}\n\n\t// No way to understand observeReport\n\treturn \"\"\n}\n\ntype outboundList []string\n\nfunc (o outboundList) contains(name string) bool {\n\tfor _, v := range o {\n\t\tif v == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*StrategyLeastPingConfig)(nil), nil))\n}\n"
  },
  {
    "path": "app/router/strategy_random.go",
    "content": "package router\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/protobuf/runtime/protoiface\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\n// RandomStrategy represents a random balancing strategy\ntype RandomStrategy struct {\n\tctx         context.Context\n\tsettings    *StrategyRandomConfig\n\tobservatory extension.Observatory\n}\n\nfunc (s *RandomStrategy) GetPrincipleTarget(strings []string) []string {\n\treturn strings\n}\n\n// NewRandomStrategy creates a new RandomStrategy with settings\nfunc NewRandomStrategy(settings *StrategyRandomConfig) *RandomStrategy {\n\treturn &RandomStrategy{\n\t\tsettings: settings,\n\t}\n}\n\nfunc (s *RandomStrategy) InjectContext(ctx context.Context) {\n\tif s != nil {\n\t\ts.ctx = ctx\n\t}\n}\n\nfunc (s *RandomStrategy) PickOutbound(candidates []string) string {\n\tif s != nil && s.settings.AliveOnly {\n\t\t// candidates are considered alive unless observed otherwise\n\t\tif s.observatory == nil {\n\t\t\tcore.RequireFeatures(s.ctx, func(observatory extension.Observatory) error {\n\t\t\t\ts.observatory = observatory\n\t\t\t\treturn nil\n\t\t\t})\n\t\t}\n\t\tif s.observatory != nil {\n\t\t\tvar observeReport protoiface.MessageV1\n\t\t\tvar err error\n\t\t\tif s.settings.ObserverTag == \"\" {\n\t\t\t\tobserveReport, err = s.observatory.GetObservation(s.ctx)\n\t\t\t} else {\n\t\t\t\tobserveReport, err = common.Must2(s.observatory.(features.TaggedFeatures).GetFeaturesByTag(s.settings.ObserverTag)).(extension.Observatory).GetObservation(s.ctx)\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\taliveTags := make([]string, 0)\n\t\t\t\tif result, ok := observeReport.(*observatory.ObservationResult); ok {\n\t\t\t\t\tstatus := result.Status\n\t\t\t\t\tstatusMap := make(map[string]*observatory.OutboundStatus)\n\t\t\t\t\tfor _, outboundStatus := range status {\n\t\t\t\t\t\tstatusMap[outboundStatus.OutboundTag] = outboundStatus\n\t\t\t\t\t}\n\t\t\t\t\tfor _, candidate := range candidates {\n\t\t\t\t\t\tif outboundStatus, found := statusMap[candidate]; found {\n\t\t\t\t\t\t\tif outboundStatus.Alive {\n\t\t\t\t\t\t\t\taliveTags = append(aliveTags, candidate)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// unfound candidate is considered alive\n\t\t\t\t\t\t\taliveTags = append(aliveTags, candidate)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcandidates = aliveTags\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcount := len(candidates)\n\tif count == 0 {\n\t\t// goes to fallbackTag\n\t\treturn \"\"\n\t}\n\treturn candidates[dice.Roll(count)]\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*StrategyRandomConfig)(nil), nil))\n}\n"
  },
  {
    "path": "app/router/weight.go",
    "content": "package router\n\nimport (\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype weightScaler func(value, weight float64) float64\n\nvar numberFinder = regexp.MustCompile(`\\d+(\\.\\d+)?`)\n\n// NewWeightManager creates a new WeightManager with settings\nfunc NewWeightManager(s []*StrategyWeight, defaultWeight float64, scaler weightScaler) *WeightManager {\n\treturn &WeightManager{\n\t\tsettings:      s,\n\t\tcache:         make(map[string]float64),\n\t\tscaler:        scaler,\n\t\tdefaultWeight: defaultWeight,\n\t}\n}\n\n// WeightManager manages weights for specific settings\ntype WeightManager struct {\n\tsettings      []*StrategyWeight\n\tcache         map[string]float64\n\tscaler        weightScaler\n\tdefaultWeight float64\n\tmu            sync.Mutex\n}\n\n// Get gets the weight of specified tag\nfunc (s *WeightManager) Get(tag string) float64 {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tweight, ok := s.cache[tag]\n\tif ok {\n\t\treturn weight\n\t}\n\tweight = s.findValue(tag)\n\ts.cache[tag] = weight\n\treturn weight\n}\n\n// Apply applies weight to the value\nfunc (s *WeightManager) Apply(tag string, value float64) float64 {\n\treturn s.scaler(value, s.Get(tag))\n}\n\nfunc (s *WeightManager) findValue(tag string) float64 {\n\tfor _, w := range s.settings {\n\t\tmatched := s.getMatch(tag, w.Match, w.Regexp)\n\t\tif matched == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif w.Value > 0 {\n\t\t\treturn float64(w.Value)\n\t\t}\n\t\t// auto weight from matched\n\t\tnumStr := numberFinder.FindString(matched)\n\t\tif numStr == \"\" {\n\t\t\treturn s.defaultWeight\n\t\t}\n\t\tweight, err := strconv.ParseFloat(numStr, 64)\n\t\tif err != nil {\n\t\t\tnewError(\"unexpected error from ParseFloat: \", err).AtError().WriteToLog()\n\t\t\treturn s.defaultWeight\n\t\t}\n\t\treturn weight\n\t}\n\treturn s.defaultWeight\n}\n\nfunc (s *WeightManager) getMatch(tag, find string, isRegexp bool) string {\n\tif !isRegexp {\n\t\tidx := strings.Index(tag, find)\n\t\tif idx < 0 {\n\t\t\treturn \"\"\n\t\t}\n\t\treturn find\n\t}\n\tr, err := regexp.Compile(find)\n\tif err != nil {\n\t\tnewError(\"invalid regexp: \", find, \"err: \", err).AtError().WriteToLog()\n\t\treturn \"\"\n\t}\n\treturn r.FindString(tag)\n}\n"
  },
  {
    "path": "app/router/weight_test.go",
    "content": "package router_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n)\n\nfunc TestWeight(t *testing.T) {\n\tmanager := router.NewWeightManager(\n\t\t[]*router.StrategyWeight{\n\t\t\t{\n\t\t\t\tMatch: \"x5\",\n\t\t\t\tValue: 100,\n\t\t\t},\n\t\t\t{\n\t\t\t\tMatch: \"x8\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tRegexp: true,\n\t\t\t\tMatch:  `\\bx0+(\\.\\d+)?\\b`,\n\t\t\t\tValue:  1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tRegexp: true,\n\t\t\t\tMatch:  `\\bx\\d+(\\.\\d+)?\\b`,\n\t\t\t},\n\t\t},\n\t\t1, func(v, w float64) float64 {\n\t\t\treturn v * w\n\t\t},\n\t)\n\ttags := []string{\n\t\t\"node name, x5, and more\",\n\t\t\"node name, x8\",\n\t\t\"node name, x15\",\n\t\t\"node name, x0100, and more\",\n\t\t\"node name, x10.1\",\n\t\t\"node name, x00.1, and more\",\n\t}\n\t// test weight\n\texpected := []float64{100, 8, 15, 100, 10.1, 1}\n\tactual := make([]float64, 0)\n\tfor _, tag := range tags {\n\t\tactual = append(actual, manager.Get(tag))\n\t}\n\tif !reflect.DeepEqual(expected, actual) {\n\t\tt.Errorf(\"expected: %v, actual: %v\", expected, actual)\n\t}\n\t// test scale\n\texpected2 := []float64{1000, 80, 150, 1000, 101, 10}\n\tactual2 := make([]float64, 0)\n\tfor _, tag := range tags {\n\t\tactual2 = append(actual2, manager.Apply(tag, 10))\n\t}\n\tif !reflect.DeepEqual(expected2, actual2) {\n\t\tt.Errorf(\"expected2: %v, actual2: %v\", expected2, actual2)\n\t}\n}\n"
  },
  {
    "path": "app/stats/channel.go",
    "content": "package stats\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n// Channel is an implementation of stats.Channel.\ntype Channel struct {\n\tchannel     chan channelMessage\n\tsubscribers []chan interface{}\n\n\t// Synchronization components\n\taccess sync.RWMutex\n\tclosed chan struct{}\n\n\t// Channel options\n\tblocking   bool // Set blocking state if channel buffer reaches limit\n\tbufferSize int  // Set to 0 as no buffering\n\tsubsLimit  int  // Set to 0 as no subscriber limit\n}\n\n// NewChannel creates an instance of Statistics Channel.\nfunc NewChannel(config *ChannelConfig) *Channel {\n\treturn &Channel{\n\t\tchannel:    make(chan channelMessage, config.BufferSize),\n\t\tsubsLimit:  int(config.SubscriberLimit),\n\t\tbufferSize: int(config.BufferSize),\n\t\tblocking:   config.Blocking,\n\t}\n}\n\n// Subscribers implements stats.Channel.\nfunc (c *Channel) Subscribers() []chan interface{} {\n\tc.access.RLock()\n\tdefer c.access.RUnlock()\n\treturn c.subscribers\n}\n\n// Subscribe implements stats.Channel.\nfunc (c *Channel) Subscribe() (chan interface{}, error) {\n\tc.access.Lock()\n\tdefer c.access.Unlock()\n\tif c.subsLimit > 0 && len(c.subscribers) >= c.subsLimit {\n\t\treturn nil, newError(\"Number of subscribers has reached limit\")\n\t}\n\tsubscriber := make(chan interface{}, c.bufferSize)\n\tc.subscribers = append(c.subscribers, subscriber)\n\treturn subscriber, nil\n}\n\n// Unsubscribe implements stats.Channel.\nfunc (c *Channel) Unsubscribe(subscriber chan interface{}) error {\n\tc.access.Lock()\n\tdefer c.access.Unlock()\n\tfor i, s := range c.subscribers {\n\t\tif s == subscriber {\n\t\t\t// Copy to new memory block to prevent modifying original data\n\t\t\tsubscribers := make([]chan interface{}, len(c.subscribers)-1)\n\t\t\tcopy(subscribers[:i], c.subscribers[:i])\n\t\t\tcopy(subscribers[i:], c.subscribers[i+1:])\n\t\t\tc.subscribers = subscribers\n\t\t}\n\t}\n\treturn nil\n}\n\n// Publish implements stats.Channel.\nfunc (c *Channel) Publish(ctx context.Context, msg interface{}) {\n\tselect { // Early exit if channel closed\n\tcase <-c.closed:\n\t\treturn\n\tdefault:\n\t\tpub := channelMessage{context: ctx, message: msg}\n\t\tif c.blocking {\n\t\t\tpub.publish(c.channel)\n\t\t} else {\n\t\t\tpub.publishNonBlocking(c.channel)\n\t\t}\n\t}\n}\n\n// Running returns whether the channel is running.\nfunc (c *Channel) Running() bool {\n\tselect {\n\tcase <-c.closed: // Channel closed\n\tdefault: // Channel running or not initialized\n\t\tif c.closed != nil { // Channel initialized\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Start implements common.Runnable.\nfunc (c *Channel) Start() error {\n\tc.access.Lock()\n\tdefer c.access.Unlock()\n\tif !c.Running() {\n\t\tc.closed = make(chan struct{}) // Reset close signal\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase pub := <-c.channel: // Published message received\n\t\t\t\t\tfor _, sub := range c.Subscribers() { // Concurrency-safe subscribers retrievement\n\t\t\t\t\t\tif c.blocking {\n\t\t\t\t\t\t\tpub.broadcast(sub)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpub.broadcastNonBlocking(sub)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tcase <-c.closed: // Channel closed\n\t\t\t\t\tfor _, sub := range c.Subscribers() { // Remove all subscribers\n\t\t\t\t\t\tcommon.Must(c.Unsubscribe(sub))\n\t\t\t\t\t\tclose(sub)\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\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (c *Channel) Close() error {\n\tc.access.Lock()\n\tdefer c.access.Unlock()\n\tif c.Running() {\n\t\tclose(c.closed) // Send closed signal\n\t}\n\treturn nil\n}\n\n// channelMessage is the published message with guaranteed delivery.\n// message is discarded only when the context is early cancelled.\ntype channelMessage struct {\n\tcontext context.Context\n\tmessage interface{}\n}\n\nfunc (c channelMessage) publish(publisher chan channelMessage) {\n\tselect {\n\tcase publisher <- c:\n\tcase <-c.context.Done():\n\t}\n}\n\nfunc (c channelMessage) publishNonBlocking(publisher chan channelMessage) {\n\tselect {\n\tcase publisher <- c:\n\tdefault: // Create another goroutine to keep sending message\n\t\tgo c.publish(publisher)\n\t}\n}\n\nfunc (c channelMessage) broadcast(subscriber chan interface{}) {\n\tselect {\n\tcase subscriber <- c.message:\n\tcase <-c.context.Done():\n\t}\n}\n\nfunc (c channelMessage) broadcastNonBlocking(subscriber chan interface{}) {\n\tselect {\n\tcase subscriber <- c.message:\n\tdefault: // Create another goroutine to keep sending message\n\t\tgo c.broadcast(subscriber)\n\t}\n}\n"
  },
  {
    "path": "app/stats/channel_test.go",
    "content": "package stats_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\nfunc TestStatsChannel(t *testing.T) {\n\t// At most 2 subscribers could be registered\n\tc := NewChannel(&ChannelConfig{SubscriberLimit: 2, Blocking: true})\n\n\ta, err := stats.SubscribeRunnableChannel(c)\n\tcommon.Must(err)\n\tif !c.Running() {\n\t\tt.Fatal(\"unexpected failure in running channel after first subscription\")\n\t}\n\n\tb, err := c.Subscribe()\n\tcommon.Must(err)\n\n\t// Test that third subscriber is forbidden\n\t_, err = c.Subscribe()\n\tif err == nil {\n\t\tt.Fatal(\"unexpected successful subscription\")\n\t}\n\tt.Log(\"expected error: \", err)\n\n\tstopCh := make(chan struct{})\n\terrCh := make(chan string)\n\n\tgo func() {\n\t\tc.Publish(context.Background(), 1)\n\t\tc.Publish(context.Background(), 2)\n\t\tc.Publish(context.Background(), \"3\")\n\t\tc.Publish(context.Background(), []int{4})\n\t\tstopCh <- struct{}{}\n\t}()\n\n\tgo func() {\n\t\tif v, ok := (<-a).(int); !ok || v != 1 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 1)\n\t\t}\n\t\tif v, ok := (<-a).(int); !ok || v != 2 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 2)\n\t\t}\n\t\tif v, ok := (<-a).(string); !ok || v != \"3\" {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", \"3\")\n\t\t}\n\t\tif v, ok := (<-a).([]int); !ok || v[0] != 4 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", []int{4})\n\t\t}\n\t\tstopCh <- struct{}{}\n\t}()\n\n\tgo func() {\n\t\tif v, ok := (<-b).(int); !ok || v != 1 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 1)\n\t\t}\n\t\tif v, ok := (<-b).(int); !ok || v != 2 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 2)\n\t\t}\n\t\tif v, ok := (<-b).(string); !ok || v != \"3\" {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", \"3\")\n\t\t}\n\t\tif v, ok := (<-b).([]int); !ok || v[0] != 4 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", []int{4})\n\t\t}\n\t\tstopCh <- struct{}{}\n\t}()\n\n\ttimeout := time.After(2 * time.Second)\n\tfor i := 0; i < 3; i++ {\n\t\tselect {\n\t\tcase <-timeout:\n\t\t\tt.Fatal(\"Test timeout after 2s\")\n\t\tcase e := <-errCh:\n\t\t\tt.Fatal(e)\n\t\tcase <-stopCh:\n\t\t}\n\t}\n\n\t// Test the unsubscription of channel\n\tcommon.Must(c.Unsubscribe(b))\n\n\t// Test the last subscriber will close channel with `UnsubscribeClosableChannel`\n\tcommon.Must(stats.UnsubscribeClosableChannel(c, a))\n\tif c.Running() {\n\t\tt.Fatal(\"unexpected running channel after unsubscribing the last subscriber\")\n\t}\n}\n\nfunc TestStatsChannelUnsubcribe(t *testing.T) {\n\tc := NewChannel(&ChannelConfig{Blocking: true})\n\tcommon.Must(c.Start())\n\tdefer c.Close()\n\n\ta, err := c.Subscribe()\n\tcommon.Must(err)\n\tdefer c.Unsubscribe(a)\n\n\tb, err := c.Subscribe()\n\tcommon.Must(err)\n\n\tpauseCh := make(chan struct{})\n\tstopCh := make(chan struct{})\n\terrCh := make(chan string)\n\n\t{\n\t\tvar aSet, bSet bool\n\t\tfor _, s := range c.Subscribers() {\n\t\t\tif s == a {\n\t\t\t\taSet = true\n\t\t\t}\n\t\t\tif s == b {\n\t\t\t\tbSet = true\n\t\t\t}\n\t\t}\n\t\tif !(aSet && bSet) {\n\t\t\tt.Fatal(\"unexpected subscribers: \", c.Subscribers())\n\t\t}\n\t}\n\n\tgo func() { // Blocking publish\n\t\tc.Publish(context.Background(), 1)\n\t\t<-pauseCh // Wait for `b` goroutine to resume sending message\n\t\tc.Publish(context.Background(), 2)\n\t}()\n\n\tgo func() {\n\t\tif v, ok := (<-a).(int); !ok || v != 1 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 1)\n\t\t}\n\t\tif v, ok := (<-a).(int); !ok || v != 2 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 2)\n\t\t}\n\t}()\n\n\tgo func() {\n\t\tif v, ok := (<-b).(int); !ok || v != 1 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 1)\n\t\t}\n\t\t// Unsubscribe `b` while publishing is paused\n\t\tc.Unsubscribe(b)\n\t\t{ // Test `b` is not in subscribers\n\t\t\tvar aSet, bSet bool\n\t\t\tfor _, s := range c.Subscribers() {\n\t\t\t\tif s == a {\n\t\t\t\t\taSet = true\n\t\t\t\t}\n\t\t\t\tif s == b {\n\t\t\t\t\tbSet = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !(aSet && !bSet) {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected subscribers: \", c.Subscribers())\n\t\t\t}\n\t\t}\n\t\t// Resume publishing progress\n\t\tclose(pauseCh)\n\t\t// Test `b` is neither closed nor able to receive any data\n\t\tselect {\n\t\tcase v, ok := <-b:\n\t\t\tif ok {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected data received: \", v)\n\t\t\t} else {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected closed channel: \", b)\n\t\t\t}\n\t\tdefault:\n\t\t}\n\t\tclose(stopCh)\n\t}()\n\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tt.Fatal(\"Test timeout after 2s\")\n\tcase e := <-errCh:\n\t\tt.Fatal(e)\n\tcase <-stopCh:\n\t}\n}\n\nfunc TestStatsChannelBlocking(t *testing.T) {\n\t// Do not use buffer so as to create blocking scenario\n\tc := NewChannel(&ChannelConfig{BufferSize: 0, Blocking: true})\n\tcommon.Must(c.Start())\n\tdefer c.Close()\n\n\ta, err := c.Subscribe()\n\tcommon.Must(err)\n\tdefer c.Unsubscribe(a)\n\n\tpauseCh := make(chan struct{})\n\tstopCh := make(chan struct{})\n\terrCh := make(chan string)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\n\t// Test blocking channel publishing\n\tgo func() {\n\t\t// Dummy message with no subscriber receiving, will block broadcasting goroutine\n\t\tc.Publish(context.Background(), nil)\n\n\t\t<-pauseCh\n\n\t\t// Publishing should be blocked here, for last message was not cleared and buffer was full\n\t\tc.Publish(context.Background(), nil)\n\n\t\tpauseCh <- struct{}{}\n\n\t\t// Publishing should still be blocked here\n\t\tc.Publish(ctx, nil)\n\n\t\t// Check publishing is done because context is canceled\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tif ctx.Err() != context.Canceled {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected error: \", ctx.Err())\n\t\t\t}\n\t\tdefault:\n\t\t\terrCh <- \"unexpected non-blocked publishing\"\n\t\t}\n\t\tclose(stopCh)\n\t}()\n\n\tgo func() {\n\t\tpauseCh <- struct{}{}\n\n\t\tselect {\n\t\tcase <-pauseCh:\n\t\t\terrCh <- \"unexpected non-blocked publishing\"\n\t\tcase <-time.After(100 * time.Millisecond):\n\t\t}\n\n\t\t// Receive first published message\n\t\t<-a\n\n\t\tselect {\n\t\tcase <-pauseCh:\n\t\tcase <-time.After(100 * time.Millisecond):\n\t\t\terrCh <- \"unexpected blocking publishing\"\n\t\t}\n\n\t\t// Manually cancel the context to end publishing\n\t\tcancel()\n\t}()\n\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tt.Fatal(\"Test timeout after 2s\")\n\tcase e := <-errCh:\n\t\tt.Fatal(e)\n\tcase <-stopCh:\n\t}\n}\n\nfunc TestStatsChannelNonBlocking(t *testing.T) {\n\t// Do not use buffer so as to create blocking scenario\n\tc := NewChannel(&ChannelConfig{BufferSize: 0, Blocking: false})\n\tcommon.Must(c.Start())\n\tdefer c.Close()\n\n\ta, err := c.Subscribe()\n\tcommon.Must(err)\n\tdefer c.Unsubscribe(a)\n\n\tpauseCh := make(chan struct{})\n\tstopCh := make(chan struct{})\n\terrCh := make(chan string)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\n\t// Test blocking channel publishing\n\tgo func() {\n\t\tc.Publish(context.Background(), nil)\n\t\tc.Publish(context.Background(), nil)\n\t\tpauseCh <- struct{}{}\n\t\t<-pauseCh\n\t\tc.Publish(ctx, nil)\n\t\tc.Publish(ctx, nil)\n\t\t// Check publishing is done because context is canceled\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tif ctx.Err() != context.Canceled {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected error: \", ctx.Err())\n\t\t\t}\n\t\tcase <-time.After(100 * time.Millisecond):\n\t\t\terrCh <- \"unexpected non-cancelled publishing\"\n\t\t}\n\t}()\n\n\tgo func() {\n\t\t// Check publishing won't block even if there is no subscriber receiving message\n\t\tselect {\n\t\tcase <-pauseCh:\n\t\tcase <-time.After(100 * time.Millisecond):\n\t\t\terrCh <- \"unexpected blocking publishing\"\n\t\t}\n\n\t\t// Receive first and second published message\n\t\t<-a\n\t\t<-a\n\n\t\tpauseCh <- struct{}{}\n\n\t\t// Manually cancel the context to end publishing\n\t\tcancel()\n\n\t\t// Check third and forth published message is cancelled and cannot receive\n\t\t<-time.After(100 * time.Millisecond)\n\t\tselect {\n\t\tcase <-a:\n\t\t\terrCh <- \"unexpected non-cancelled publishing\"\n\t\tdefault:\n\t\t}\n\t\tselect {\n\t\tcase <-a:\n\t\t\terrCh <- \"unexpected non-cancelled publishing\"\n\t\tdefault:\n\t\t}\n\t\tclose(stopCh)\n\t}()\n\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tt.Fatal(\"Test timeout after 2s\")\n\tcase e := <-errCh:\n\t\tt.Fatal(e)\n\tcase <-stopCh:\n\t}\n}\n\nfunc TestStatsChannelConcurrency(t *testing.T) {\n\t// Do not use buffer so as to create blocking scenario\n\tc := NewChannel(&ChannelConfig{BufferSize: 0, Blocking: true})\n\tcommon.Must(c.Start())\n\tdefer c.Close()\n\n\ta, err := c.Subscribe()\n\tcommon.Must(err)\n\tdefer c.Unsubscribe(a)\n\n\tb, err := c.Subscribe()\n\tcommon.Must(err)\n\tdefer c.Unsubscribe(b)\n\n\tstopCh := make(chan struct{})\n\terrCh := make(chan string)\n\n\tgo func() { // Blocking publish\n\t\tc.Publish(context.Background(), 1)\n\t\tc.Publish(context.Background(), 2)\n\t}()\n\n\tgo func() {\n\t\tif v, ok := (<-a).(int); !ok || v != 1 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 1)\n\t\t}\n\t\tif v, ok := (<-a).(int); !ok || v != 2 {\n\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v, \", wanted \", 2)\n\t\t}\n\t}()\n\n\tgo func() {\n\t\t// Block `b` for a time so as to ensure source channel is trying to send message to `b`.\n\t\t<-time.After(25 * time.Millisecond)\n\t\t// This causes concurrency scenario: unsubscribe `b` while trying to send message to it\n\t\tc.Unsubscribe(b)\n\t\t// Test `b` is not closed and can still receive data 1:\n\t\t// Because unsubscribe won't affect the ongoing process of sending message.\n\t\tselect {\n\t\tcase v, ok := <-b:\n\t\t\tif v1, ok1 := v.(int); !(ok && ok1 && v1 == 1) {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected failure in receiving data: \", 1)\n\t\t\t}\n\t\tdefault:\n\t\t\terrCh <- fmt.Sprint(\"unexpected block from receiving data: \", 1)\n\t\t}\n\t\t// Test `b` is not closed but cannot receive data 2:\n\t\t// Because in a new round of messaging, `b` has been unsubscribed.\n\t\tselect {\n\t\tcase v, ok := <-b:\n\t\t\tif ok {\n\t\t\t\terrCh <- fmt.Sprint(\"unexpected receiving: \", v)\n\t\t\t} else {\n\t\t\t\terrCh <- \"unexpected closing of channel\"\n\t\t\t}\n\t\tdefault:\n\t\t}\n\t\tclose(stopCh)\n\t}()\n\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tt.Fatal(\"Test timeout after 2s\")\n\tcase e := <-errCh:\n\t\tt.Fatal(e)\n\tcase <-stopCh:\n\t}\n}\n"
  },
  {
    "path": "app/stats/command/command.go",
    "content": "package command\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\t\"time\"\n\n\tgrpc \"google.golang.org/grpc\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\tfeature_stats \"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\n// statsServer is an implementation of StatsService.\ntype statsServer struct {\n\tstats     feature_stats.Manager\n\tstartTime time.Time\n}\n\nfunc NewStatsServer(manager feature_stats.Manager) StatsServiceServer {\n\treturn &statsServer{\n\t\tstats:     manager,\n\t\tstartTime: time.Now(),\n\t}\n}\n\nfunc (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (*GetStatsResponse, error) {\n\tc := s.stats.GetCounter(request.Name)\n\tif c == nil {\n\t\treturn nil, newError(request.Name, \" not found.\")\n\t}\n\tvar value int64\n\tif request.Reset_ {\n\t\tvalue = c.Set(0)\n\t} else {\n\t\tvalue = c.Value()\n\t}\n\treturn &GetStatsResponse{\n\t\tStat: &Stat{\n\t\t\tName:  request.Name,\n\t\t\tValue: value,\n\t\t},\n\t}, nil\n}\n\nfunc (s *statsServer) QueryStats(ctx context.Context, request *QueryStatsRequest) (*QueryStatsResponse, error) {\n\tmgroup := &strmatcher.LinearIndexMatcher{}\n\tif request.Pattern != \"\" {\n\t\trequest.Patterns = append(request.Patterns, request.Pattern)\n\t}\n\tt := strmatcher.Substr\n\tif request.Regexp {\n\t\tt = strmatcher.Regex\n\t}\n\tfor _, p := range request.Patterns {\n\t\tm, err := t.New(p)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmgroup.Add(m)\n\t}\n\n\tresponse := &QueryStatsResponse{}\n\n\tmanager, ok := s.stats.(*stats.Manager)\n\tif !ok {\n\t\treturn nil, newError(\"QueryStats only works its own stats.Manager.\")\n\t}\n\n\tmanager.VisitCounters(func(name string, c feature_stats.Counter) bool {\n\t\tif mgroup.Size() == 0 || len(mgroup.Match(name)) > 0 {\n\t\t\tvar value int64\n\t\t\tif request.Reset_ {\n\t\t\t\tvalue = c.Set(0)\n\t\t\t} else {\n\t\t\t\tvalue = c.Value()\n\t\t\t}\n\t\t\tresponse.Stat = append(response.Stat, &Stat{\n\t\t\t\tName:  name,\n\t\t\t\tValue: value,\n\t\t\t})\n\t\t}\n\t\treturn true\n\t})\n\n\treturn response, nil\n}\n\nfunc (s *statsServer) GetSysStats(ctx context.Context, request *SysStatsRequest) (*SysStatsResponse, error) {\n\tvar rtm runtime.MemStats\n\truntime.ReadMemStats(&rtm)\n\n\tuptime := time.Since(s.startTime)\n\n\tresponse := &SysStatsResponse{\n\t\tUptime:       uint32(uptime.Seconds()),\n\t\tNumGoroutine: uint32(runtime.NumGoroutine()),\n\t\tAlloc:        rtm.Alloc,\n\t\tTotalAlloc:   rtm.TotalAlloc,\n\t\tSys:          rtm.Sys,\n\t\tMallocs:      rtm.Mallocs,\n\t\tFrees:        rtm.Frees,\n\t\tLiveObjects:  rtm.Mallocs - rtm.Frees,\n\t\tNumGC:        rtm.NumGC,\n\t\tPauseTotalNs: rtm.PauseTotalNs,\n\t}\n\n\treturn response, nil\n}\n\nfunc (s *statsServer) mustEmbedUnimplementedStatsServiceServer() {}\n\ntype service struct {\n\tstatsManager feature_stats.Manager\n}\n\nfunc (s *service) Register(server *grpc.Server) {\n\tRegisterStatsServiceServer(server, NewStatsServer(s.statsManager))\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\ts := new(service)\n\n\t\tcore.RequireFeatures(ctx, func(sm feature_stats.Manager) {\n\t\t\ts.statsManager = sm\n\t\t})\n\n\t\treturn s, nil\n\t}))\n}\n"
  },
  {
    "path": "app/stats/command/command.pb.go",
    "content": "package command\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 GetStatsRequest struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Name of the stat counter.\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Whether or not to reset the counter to fetching its value.\n\tReset_        bool `protobuf:\"varint,2,opt,name=reset,proto3\" json:\"reset,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetStatsRequest) Reset() {\n\t*x = GetStatsRequest{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetStatsRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetStatsRequest) ProtoMessage() {}\n\nfunc (x *GetStatsRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[0]\n\tif 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 GetStatsRequest.ProtoReflect.Descriptor instead.\nfunc (*GetStatsRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *GetStatsRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *GetStatsRequest) GetReset_() bool {\n\tif x != nil {\n\t\treturn x.Reset_\n\t}\n\treturn false\n}\n\ntype Stat struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tValue         int64                  `protobuf:\"varint,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Stat) Reset() {\n\t*x = Stat{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Stat) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Stat) ProtoMessage() {}\n\nfunc (x *Stat) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[1]\n\tif 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 Stat.ProtoReflect.Descriptor instead.\nfunc (*Stat) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Stat) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Stat) GetValue() int64 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\ntype GetStatsResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tStat          *Stat                  `protobuf:\"bytes,1,opt,name=stat,proto3\" json:\"stat,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetStatsResponse) Reset() {\n\t*x = GetStatsResponse{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetStatsResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetStatsResponse) ProtoMessage() {}\n\nfunc (x *GetStatsResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[2]\n\tif 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 GetStatsResponse.ProtoReflect.Descriptor instead.\nfunc (*GetStatsResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *GetStatsResponse) GetStat() *Stat {\n\tif x != nil {\n\t\treturn x.Stat\n\t}\n\treturn nil\n}\n\ntype QueryStatsRequest struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Deprecated, use Patterns instead\n\tPattern       string   `protobuf:\"bytes,1,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tReset_        bool     `protobuf:\"varint,2,opt,name=reset,proto3\" json:\"reset,omitempty\"`\n\tPatterns      []string `protobuf:\"bytes,3,rep,name=patterns,proto3\" json:\"patterns,omitempty\"`\n\tRegexp        bool     `protobuf:\"varint,4,opt,name=regexp,proto3\" json:\"regexp,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *QueryStatsRequest) Reset() {\n\t*x = QueryStatsRequest{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *QueryStatsRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*QueryStatsRequest) ProtoMessage() {}\n\nfunc (x *QueryStatsRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[3]\n\tif 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 QueryStatsRequest.ProtoReflect.Descriptor instead.\nfunc (*QueryStatsRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *QueryStatsRequest) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryStatsRequest) GetReset_() bool {\n\tif x != nil {\n\t\treturn x.Reset_\n\t}\n\treturn false\n}\n\nfunc (x *QueryStatsRequest) GetPatterns() []string {\n\tif x != nil {\n\t\treturn x.Patterns\n\t}\n\treturn nil\n}\n\nfunc (x *QueryStatsRequest) GetRegexp() bool {\n\tif x != nil {\n\t\treturn x.Regexp\n\t}\n\treturn false\n}\n\ntype QueryStatsResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tStat          []*Stat                `protobuf:\"bytes,1,rep,name=stat,proto3\" json:\"stat,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *QueryStatsResponse) Reset() {\n\t*x = QueryStatsResponse{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *QueryStatsResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*QueryStatsResponse) ProtoMessage() {}\n\nfunc (x *QueryStatsResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[4]\n\tif 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 QueryStatsResponse.ProtoReflect.Descriptor instead.\nfunc (*QueryStatsResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *QueryStatsResponse) GetStat() []*Stat {\n\tif x != nil {\n\t\treturn x.Stat\n\t}\n\treturn nil\n}\n\ntype SysStatsRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SysStatsRequest) Reset() {\n\t*x = SysStatsRequest{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SysStatsRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SysStatsRequest) ProtoMessage() {}\n\nfunc (x *SysStatsRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[5]\n\tif 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 SysStatsRequest.ProtoReflect.Descriptor instead.\nfunc (*SysStatsRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{5}\n}\n\ntype SysStatsResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tNumGoroutine  uint32                 `protobuf:\"varint,1,opt,name=NumGoroutine,proto3\" json:\"NumGoroutine,omitempty\"`\n\tNumGC         uint32                 `protobuf:\"varint,2,opt,name=NumGC,proto3\" json:\"NumGC,omitempty\"`\n\tAlloc         uint64                 `protobuf:\"varint,3,opt,name=Alloc,proto3\" json:\"Alloc,omitempty\"`\n\tTotalAlloc    uint64                 `protobuf:\"varint,4,opt,name=TotalAlloc,proto3\" json:\"TotalAlloc,omitempty\"`\n\tSys           uint64                 `protobuf:\"varint,5,opt,name=Sys,proto3\" json:\"Sys,omitempty\"`\n\tMallocs       uint64                 `protobuf:\"varint,6,opt,name=Mallocs,proto3\" json:\"Mallocs,omitempty\"`\n\tFrees         uint64                 `protobuf:\"varint,7,opt,name=Frees,proto3\" json:\"Frees,omitempty\"`\n\tLiveObjects   uint64                 `protobuf:\"varint,8,opt,name=LiveObjects,proto3\" json:\"LiveObjects,omitempty\"`\n\tPauseTotalNs  uint64                 `protobuf:\"varint,9,opt,name=PauseTotalNs,proto3\" json:\"PauseTotalNs,omitempty\"`\n\tUptime        uint32                 `protobuf:\"varint,10,opt,name=Uptime,proto3\" json:\"Uptime,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SysStatsResponse) Reset() {\n\t*x = SysStatsResponse{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SysStatsResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SysStatsResponse) ProtoMessage() {}\n\nfunc (x *SysStatsResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[6]\n\tif 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 SysStatsResponse.ProtoReflect.Descriptor instead.\nfunc (*SysStatsResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *SysStatsResponse) GetNumGoroutine() uint32 {\n\tif x != nil {\n\t\treturn x.NumGoroutine\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetNumGC() uint32 {\n\tif x != nil {\n\t\treturn x.NumGC\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetAlloc() uint64 {\n\tif x != nil {\n\t\treturn x.Alloc\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetTotalAlloc() uint64 {\n\tif x != nil {\n\t\treturn x.TotalAlloc\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetSys() uint64 {\n\tif x != nil {\n\t\treturn x.Sys\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetMallocs() uint64 {\n\tif x != nil {\n\t\treturn x.Mallocs\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetFrees() uint64 {\n\tif x != nil {\n\t\treturn x.Frees\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetLiveObjects() uint64 {\n\tif x != nil {\n\t\treturn x.LiveObjects\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetPauseTotalNs() uint64 {\n\tif x != nil {\n\t\treturn x.PauseTotalNs\n\t}\n\treturn 0\n}\n\nfunc (x *SysStatsResponse) GetUptime() uint32 {\n\tif x != nil {\n\t\treturn x.Uptime\n\t}\n\treturn 0\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_stats_command_command_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_command_command_proto_msgTypes[7]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_command_command_proto_rawDescGZIP(), []int{7}\n}\n\nvar File_app_stats_command_command_proto protoreflect.FileDescriptor\n\nconst file_app_stats_command_command_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1fapp/stats/command/command.proto\\x12\\x1cv2ray.core.app.stats.command\\x1a common/protoext/extensions.proto\\\";\\n\" +\n\t\"\\x0fGetStatsRequest\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x14\\n\" +\n\t\"\\x05reset\\x18\\x02 \\x01(\\bR\\x05reset\\\"0\\n\" +\n\t\"\\x04Stat\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\x03R\\x05value\\\"J\\n\" +\n\t\"\\x10GetStatsResponse\\x126\\n\" +\n\t\"\\x04stat\\x18\\x01 \\x01(\\v2\\\".v2ray.core.app.stats.command.StatR\\x04stat\\\"w\\n\" +\n\t\"\\x11QueryStatsRequest\\x12\\x18\\n\" +\n\t\"\\apattern\\x18\\x01 \\x01(\\tR\\apattern\\x12\\x14\\n\" +\n\t\"\\x05reset\\x18\\x02 \\x01(\\bR\\x05reset\\x12\\x1a\\n\" +\n\t\"\\bpatterns\\x18\\x03 \\x03(\\tR\\bpatterns\\x12\\x16\\n\" +\n\t\"\\x06regexp\\x18\\x04 \\x01(\\bR\\x06regexp\\\"L\\n\" +\n\t\"\\x12QueryStatsResponse\\x126\\n\" +\n\t\"\\x04stat\\x18\\x01 \\x03(\\v2\\\".v2ray.core.app.stats.command.StatR\\x04stat\\\"\\x11\\n\" +\n\t\"\\x0fSysStatsRequest\\\"\\xa2\\x02\\n\" +\n\t\"\\x10SysStatsResponse\\x12\\\"\\n\" +\n\t\"\\fNumGoroutine\\x18\\x01 \\x01(\\rR\\fNumGoroutine\\x12\\x14\\n\" +\n\t\"\\x05NumGC\\x18\\x02 \\x01(\\rR\\x05NumGC\\x12\\x14\\n\" +\n\t\"\\x05Alloc\\x18\\x03 \\x01(\\x04R\\x05Alloc\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"TotalAlloc\\x18\\x04 \\x01(\\x04R\\n\" +\n\t\"TotalAlloc\\x12\\x10\\n\" +\n\t\"\\x03Sys\\x18\\x05 \\x01(\\x04R\\x03Sys\\x12\\x18\\n\" +\n\t\"\\aMallocs\\x18\\x06 \\x01(\\x04R\\aMallocs\\x12\\x14\\n\" +\n\t\"\\x05Frees\\x18\\a \\x01(\\x04R\\x05Frees\\x12 \\n\" +\n\t\"\\vLiveObjects\\x18\\b \\x01(\\x04R\\vLiveObjects\\x12\\\"\\n\" +\n\t\"\\fPauseTotalNs\\x18\\t \\x01(\\x04R\\fPauseTotalNs\\x12\\x16\\n\" +\n\t\"\\x06Uptime\\x18\\n\" +\n\t\" \\x01(\\rR\\x06Uptime\\\"\\\"\\n\" +\n\t\"\\x06Config:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\vgrpcservice\\x12\\x05stats2\\xde\\x02\\n\" +\n\t\"\\fStatsService\\x12k\\n\" +\n\t\"\\bGetStats\\x12-.v2ray.core.app.stats.command.GetStatsRequest\\x1a..v2ray.core.app.stats.command.GetStatsResponse\\\"\\x00\\x12q\\n\" +\n\t\"\\n\" +\n\t\"QueryStats\\x12/.v2ray.core.app.stats.command.QueryStatsRequest\\x1a0.v2ray.core.app.stats.command.QueryStatsResponse\\\"\\x00\\x12n\\n\" +\n\t\"\\vGetSysStats\\x12-.v2ray.core.app.stats.command.SysStatsRequest\\x1a..v2ray.core.app.stats.command.SysStatsResponse\\\"\\x00Bu\\n\" +\n\t\" com.v2ray.core.app.stats.commandP\\x01Z0github.com/v2fly/v2ray-core/v5/app/stats/command\\xaa\\x02\\x1cV2Ray.Core.App.Stats.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_stats_command_command_proto_rawDescOnce sync.Once\n\tfile_app_stats_command_command_proto_rawDescData []byte\n)\n\nfunc file_app_stats_command_command_proto_rawDescGZIP() []byte {\n\tfile_app_stats_command_command_proto_rawDescOnce.Do(func() {\n\t\tfile_app_stats_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_stats_command_command_proto_rawDesc), len(file_app_stats_command_command_proto_rawDesc)))\n\t})\n\treturn file_app_stats_command_command_proto_rawDescData\n}\n\nvar file_app_stats_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 8)\nvar file_app_stats_command_command_proto_goTypes = []any{\n\t(*GetStatsRequest)(nil),    // 0: v2ray.core.app.stats.command.GetStatsRequest\n\t(*Stat)(nil),               // 1: v2ray.core.app.stats.command.Stat\n\t(*GetStatsResponse)(nil),   // 2: v2ray.core.app.stats.command.GetStatsResponse\n\t(*QueryStatsRequest)(nil),  // 3: v2ray.core.app.stats.command.QueryStatsRequest\n\t(*QueryStatsResponse)(nil), // 4: v2ray.core.app.stats.command.QueryStatsResponse\n\t(*SysStatsRequest)(nil),    // 5: v2ray.core.app.stats.command.SysStatsRequest\n\t(*SysStatsResponse)(nil),   // 6: v2ray.core.app.stats.command.SysStatsResponse\n\t(*Config)(nil),             // 7: v2ray.core.app.stats.command.Config\n}\nvar file_app_stats_command_command_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.app.stats.command.GetStatsResponse.stat:type_name -> v2ray.core.app.stats.command.Stat\n\t1, // 1: v2ray.core.app.stats.command.QueryStatsResponse.stat:type_name -> v2ray.core.app.stats.command.Stat\n\t0, // 2: v2ray.core.app.stats.command.StatsService.GetStats:input_type -> v2ray.core.app.stats.command.GetStatsRequest\n\t3, // 3: v2ray.core.app.stats.command.StatsService.QueryStats:input_type -> v2ray.core.app.stats.command.QueryStatsRequest\n\t5, // 4: v2ray.core.app.stats.command.StatsService.GetSysStats:input_type -> v2ray.core.app.stats.command.SysStatsRequest\n\t2, // 5: v2ray.core.app.stats.command.StatsService.GetStats:output_type -> v2ray.core.app.stats.command.GetStatsResponse\n\t4, // 6: v2ray.core.app.stats.command.StatsService.QueryStats:output_type -> v2ray.core.app.stats.command.QueryStatsResponse\n\t6, // 7: v2ray.core.app.stats.command.StatsService.GetSysStats:output_type -> v2ray.core.app.stats.command.SysStatsResponse\n\t5, // [5:8] is the sub-list for method output_type\n\t2, // [2:5] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_app_stats_command_command_proto_init() }\nfunc file_app_stats_command_command_proto_init() {\n\tif File_app_stats_command_command_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: unsafe.Slice(unsafe.StringData(file_app_stats_command_command_proto_rawDesc), len(file_app_stats_command_command_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   8,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_stats_command_command_proto_goTypes,\n\t\tDependencyIndexes: file_app_stats_command_command_proto_depIdxs,\n\t\tMessageInfos:      file_app_stats_command_command_proto_msgTypes,\n\t}.Build()\n\tFile_app_stats_command_command_proto = out.File\n\tfile_app_stats_command_command_proto_goTypes = nil\n\tfile_app_stats_command_command_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/stats/command/command.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.stats.command;\noption csharp_namespace = \"V2Ray.Core.App.Stats.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/stats/command\";\noption java_package = \"com.v2ray.core.app.stats.command\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage GetStatsRequest {\n  // Name of the stat counter.\n  string name = 1;\n  // Whether or not to reset the counter to fetching its value.\n  bool reset = 2;\n}\n\nmessage Stat {\n  string name = 1;\n  int64 value = 2;\n}\n\nmessage GetStatsResponse {\n  Stat stat = 1;\n}\n\nmessage QueryStatsRequest {\n  // Deprecated, use Patterns instead\n  string pattern = 1;\n  bool reset = 2;\n  repeated string patterns = 3;\n  bool regexp = 4;\n}\n\nmessage QueryStatsResponse {\n  repeated Stat stat = 1;\n}\n\nmessage SysStatsRequest {}\n\nmessage SysStatsResponse {\n  uint32 NumGoroutine = 1;\n  uint32 NumGC = 2;\n  uint64 Alloc = 3;\n  uint64 TotalAlloc = 4;\n  uint64 Sys = 5;\n  uint64 Mallocs = 6;\n  uint64 Frees = 7;\n  uint64 LiveObjects = 8;\n  uint64 PauseTotalNs = 9;\n  uint32 Uptime = 10;\n}\n\nservice StatsService {\n  rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {}\n  rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {}\n  rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {}\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"stats\";\n}\n"
  },
  {
    "path": "app/stats/command/command_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tStatsService_GetStats_FullMethodName    = \"/v2ray.core.app.stats.command.StatsService/GetStats\"\n\tStatsService_QueryStats_FullMethodName  = \"/v2ray.core.app.stats.command.StatsService/QueryStats\"\n\tStatsService_GetSysStats_FullMethodName = \"/v2ray.core.app.stats.command.StatsService/GetSysStats\"\n)\n\n// StatsServiceClient is the client API for StatsService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype StatsServiceClient interface {\n\tGetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error)\n\tQueryStats(ctx context.Context, in *QueryStatsRequest, opts ...grpc.CallOption) (*QueryStatsResponse, error)\n\tGetSysStats(ctx context.Context, in *SysStatsRequest, opts ...grpc.CallOption) (*SysStatsResponse, error)\n}\n\ntype statsServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewStatsServiceClient(cc grpc.ClientConnInterface) StatsServiceClient {\n\treturn &statsServiceClient{cc}\n}\n\nfunc (c *statsServiceClient) GetStats(ctx context.Context, in *GetStatsRequest, opts ...grpc.CallOption) (*GetStatsResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(GetStatsResponse)\n\terr := c.cc.Invoke(ctx, StatsService_GetStats_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *statsServiceClient) QueryStats(ctx context.Context, in *QueryStatsRequest, opts ...grpc.CallOption) (*QueryStatsResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(QueryStatsResponse)\n\terr := c.cc.Invoke(ctx, StatsService_QueryStats_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *statsServiceClient) GetSysStats(ctx context.Context, in *SysStatsRequest, opts ...grpc.CallOption) (*SysStatsResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(SysStatsResponse)\n\terr := c.cc.Invoke(ctx, StatsService_GetSysStats_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// StatsServiceServer is the server API for StatsService service.\n// All implementations must embed UnimplementedStatsServiceServer\n// for forward compatibility.\ntype StatsServiceServer interface {\n\tGetStats(context.Context, *GetStatsRequest) (*GetStatsResponse, error)\n\tQueryStats(context.Context, *QueryStatsRequest) (*QueryStatsResponse, error)\n\tGetSysStats(context.Context, *SysStatsRequest) (*SysStatsResponse, error)\n\tmustEmbedUnimplementedStatsServiceServer()\n}\n\n// UnimplementedStatsServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedStatsServiceServer struct{}\n\nfunc (UnimplementedStatsServiceServer) GetStats(context.Context, *GetStatsRequest) (*GetStatsResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method GetStats not implemented\")\n}\nfunc (UnimplementedStatsServiceServer) QueryStats(context.Context, *QueryStatsRequest) (*QueryStatsResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method QueryStats not implemented\")\n}\nfunc (UnimplementedStatsServiceServer) GetSysStats(context.Context, *SysStatsRequest) (*SysStatsResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method GetSysStats not implemented\")\n}\nfunc (UnimplementedStatsServiceServer) mustEmbedUnimplementedStatsServiceServer() {}\nfunc (UnimplementedStatsServiceServer) testEmbeddedByValue()                      {}\n\n// UnsafeStatsServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to StatsServiceServer will\n// result in compilation errors.\ntype UnsafeStatsServiceServer interface {\n\tmustEmbedUnimplementedStatsServiceServer()\n}\n\nfunc RegisterStatsServiceServer(s grpc.ServiceRegistrar, srv StatsServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedStatsServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&StatsService_ServiceDesc, srv)\n}\n\nfunc _StatsService_GetStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetStatsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(StatsServiceServer).GetStats(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: StatsService_GetStats_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(StatsServiceServer).GetStats(ctx, req.(*GetStatsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _StatsService_QueryStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(QueryStatsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(StatsServiceServer).QueryStats(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: StatsService_QueryStats_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(StatsServiceServer).QueryStats(ctx, req.(*QueryStatsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _StatsService_GetSysStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SysStatsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(StatsServiceServer).GetSysStats(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: StatsService_GetSysStats_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(StatsServiceServer).GetSysStats(ctx, req.(*SysStatsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// StatsService_ServiceDesc is the grpc.ServiceDesc for StatsService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar StatsService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.stats.command.StatsService\",\n\tHandlerType: (*StatsServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetStats\",\n\t\t\tHandler:    _StatsService_GetStats_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"QueryStats\",\n\t\t\tHandler:    _StatsService_QueryStats_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetSysStats\",\n\t\t\tHandler:    _StatsService_GetSysStats_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"app/stats/command/command.proto\",\n}\n"
  },
  {
    "path": "app/stats/command/command_test.go",
    "content": "package command_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t. \"github.com/v2fly/v2ray-core/v5/app/stats/command\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc TestGetStats(t *testing.T) {\n\tm, err := stats.NewManager(context.Background(), &stats.Config{})\n\tcommon.Must(err)\n\n\tsc, err := m.RegisterCounter(\"test_counter\")\n\tcommon.Must(err)\n\n\tsc.Set(1)\n\n\ts := NewStatsServer(m)\n\n\ttestCases := []struct {\n\t\tname  string\n\t\treset bool\n\t\tvalue int64\n\t\terr   bool\n\t}{\n\t\t{\n\t\t\tname: \"counterNotExist\",\n\t\t\terr:  true,\n\t\t},\n\t\t{\n\t\t\tname:  \"test_counter\",\n\t\t\treset: true,\n\t\t\tvalue: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"test_counter\",\n\t\t\tvalue: 0,\n\t\t},\n\t}\n\tfor _, tc := range testCases {\n\t\tresp, err := s.GetStats(context.Background(), &GetStatsRequest{\n\t\t\tName:   tc.name,\n\t\t\tReset_: tc.reset,\n\t\t})\n\t\tif tc.err {\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"nil error: \", tc.name)\n\t\t\t}\n\t\t} else {\n\t\t\tcommon.Must(err)\n\t\t\tif r := cmp.Diff(resp.Stat, &Stat{Name: tc.name, Value: tc.value}, cmpopts.IgnoreUnexported(Stat{})); r != \"\" {\n\t\t\t\tt.Error(r)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestQueryStats(t *testing.T) {\n\tm, err := stats.NewManager(context.Background(), &stats.Config{})\n\tcommon.Must(err)\n\n\tsc1, err := m.RegisterCounter(\"test_counter\")\n\tcommon.Must(err)\n\tsc1.Set(1)\n\n\tsc2, err := m.RegisterCounter(\"test_counter_2\")\n\tcommon.Must(err)\n\tsc2.Set(2)\n\n\tsc3, err := m.RegisterCounter(\"test_counter_3\")\n\tcommon.Must(err)\n\tsc3.Set(3)\n\n\ts := NewStatsServer(m)\n\tresp, err := s.QueryStats(context.Background(), &QueryStatsRequest{\n\t\tPattern: \"counter_\",\n\t})\n\tcommon.Must(err)\n\tif r := cmp.Diff(resp.Stat, []*Stat{\n\t\t{Name: \"test_counter_2\", Value: 2},\n\t\t{Name: \"test_counter_3\", Value: 3},\n\t}, cmpopts.SortSlices(func(s1, s2 *Stat) bool { return s1.Name < s2.Name }),\n\t\tcmpopts.IgnoreUnexported(Stat{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "app/stats/command/errors.generated.go",
    "content": "package command\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/stats/config.pb.go",
    "content": "package stats\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_stats_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype ChannelConfig struct {\n\tstate           protoimpl.MessageState `protogen:\"open.v1\"`\n\tBlocking        bool                   `protobuf:\"varint,1,opt,name=Blocking,proto3\" json:\"Blocking,omitempty\"`\n\tSubscriberLimit int32                  `protobuf:\"varint,2,opt,name=SubscriberLimit,proto3\" json:\"SubscriberLimit,omitempty\"`\n\tBufferSize      int32                  `protobuf:\"varint,3,opt,name=BufferSize,proto3\" json:\"BufferSize,omitempty\"`\n\tunknownFields   protoimpl.UnknownFields\n\tsizeCache       protoimpl.SizeCache\n}\n\nfunc (x *ChannelConfig) Reset() {\n\t*x = ChannelConfig{}\n\tmi := &file_app_stats_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ChannelConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ChannelConfig) ProtoMessage() {}\n\nfunc (x *ChannelConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_stats_config_proto_msgTypes[1]\n\tif 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 ChannelConfig.ProtoReflect.Descriptor instead.\nfunc (*ChannelConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_stats_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ChannelConfig) GetBlocking() bool {\n\tif x != nil {\n\t\treturn x.Blocking\n\t}\n\treturn false\n}\n\nfunc (x *ChannelConfig) GetSubscriberLimit() int32 {\n\tif x != nil {\n\t\treturn x.SubscriberLimit\n\t}\n\treturn 0\n}\n\nfunc (x *ChannelConfig) GetBufferSize() int32 {\n\tif x != nil {\n\t\treturn x.BufferSize\n\t}\n\treturn 0\n}\n\nvar File_app_stats_config_proto protoreflect.FileDescriptor\n\nconst file_app_stats_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x16app/stats/config.proto\\x12\\x14v2ray.core.app.stats\\x1a common/protoext/extensions.proto\\\"\\x1e\\n\" +\n\t\"\\x06Config:\\x14\\x82\\xb5\\x18\\x10\\n\" +\n\t\"\\aservice\\x12\\x05stats\\\"u\\n\" +\n\t\"\\rChannelConfig\\x12\\x1a\\n\" +\n\t\"\\bBlocking\\x18\\x01 \\x01(\\bR\\bBlocking\\x12(\\n\" +\n\t\"\\x0fSubscriberLimit\\x18\\x02 \\x01(\\x05R\\x0fSubscriberLimit\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"BufferSize\\x18\\x03 \\x01(\\x05R\\n\" +\n\t\"BufferSizeB]\\n\" +\n\t\"\\x18com.v2ray.core.app.statsP\\x01Z(github.com/v2fly/v2ray-core/v5/app/stats\\xaa\\x02\\x14V2Ray.Core.App.Statsb\\x06proto3\"\n\nvar (\n\tfile_app_stats_config_proto_rawDescOnce sync.Once\n\tfile_app_stats_config_proto_rawDescData []byte\n)\n\nfunc file_app_stats_config_proto_rawDescGZIP() []byte {\n\tfile_app_stats_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_stats_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_stats_config_proto_rawDesc), len(file_app_stats_config_proto_rawDesc)))\n\t})\n\treturn file_app_stats_config_proto_rawDescData\n}\n\nvar file_app_stats_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_app_stats_config_proto_goTypes = []any{\n\t(*Config)(nil),        // 0: v2ray.core.app.stats.Config\n\t(*ChannelConfig)(nil), // 1: v2ray.core.app.stats.ChannelConfig\n}\nvar file_app_stats_config_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_app_stats_config_proto_init() }\nfunc file_app_stats_config_proto_init() {\n\tif File_app_stats_config_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: unsafe.Slice(unsafe.StringData(file_app_stats_config_proto_rawDesc), len(file_app_stats_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_stats_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_stats_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_stats_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_stats_config_proto = out.File\n\tfile_app_stats_config_proto_goTypes = nil\n\tfile_app_stats_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/stats/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.stats;\noption csharp_namespace = \"V2Ray.Core.App.Stats\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/stats\";\noption java_package = \"com.v2ray.core.app.stats\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"stats\";\n}\n\nmessage ChannelConfig {\n  bool Blocking = 1;\n  int32 SubscriberLimit = 2;\n  int32 BufferSize = 3;\n}\n"
  },
  {
    "path": "app/stats/counter.go",
    "content": "package stats\n\nimport \"sync/atomic\"\n\n// Counter is an implementation of stats.Counter.\ntype Counter struct {\n\tvalue int64\n}\n\n// Value implements stats.Counter.\nfunc (c *Counter) Value() int64 {\n\treturn atomic.LoadInt64(&c.value)\n}\n\n// Set implements stats.Counter.\nfunc (c *Counter) Set(newValue int64) int64 {\n\treturn atomic.SwapInt64(&c.value, newValue)\n}\n\n// Add implements stats.Counter.\nfunc (c *Counter) Add(delta int64) int64 {\n\treturn atomic.AddInt64(&c.value, delta)\n}\n"
  },
  {
    "path": "app/stats/counter_test.go",
    "content": "package stats_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\nfunc TestStatsCounter(t *testing.T) {\n\traw, err := common.CreateObject(context.Background(), &Config{})\n\tcommon.Must(err)\n\n\tm := raw.(stats.Manager)\n\tc, err := m.RegisterCounter(\"test.counter\")\n\tcommon.Must(err)\n\n\tif v := c.Add(1); v != 1 {\n\t\tt.Fatal(\"unpexcted Add(1) return: \", v, \", wanted \", 1)\n\t}\n\n\tif v := c.Set(0); v != 1 {\n\t\tt.Fatal(\"unexpected Set(0) return: \", v, \", wanted \", 1)\n\t}\n\n\tif v := c.Value(); v != 0 {\n\t\tt.Fatal(\"unexpected Value() return: \", v, \", wanted \", 0)\n\t}\n}\n"
  },
  {
    "path": "app/stats/errors.generated.go",
    "content": "package stats\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/stats/stats.go",
    "content": "package stats\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\n// Manager is an implementation of stats.Manager.\ntype Manager struct {\n\taccess   sync.RWMutex\n\tcounters map[string]*Counter\n\tchannels map[string]*Channel\n\trunning  bool\n}\n\n// NewManager creates an instance of Statistics Manager.\nfunc NewManager(ctx context.Context, config *Config) (*Manager, error) {\n\tm := &Manager{\n\t\tcounters: make(map[string]*Counter),\n\t\tchannels: make(map[string]*Channel),\n\t}\n\n\treturn m, nil\n}\n\n// Type implements common.HasType.\nfunc (*Manager) Type() interface{} {\n\treturn stats.ManagerType()\n}\n\n// RegisterCounter implements stats.Manager.\nfunc (m *Manager) RegisterCounter(name string) (stats.Counter, error) {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tif _, found := m.counters[name]; found {\n\t\treturn nil, newError(\"Counter \", name, \" already registered.\")\n\t}\n\tnewError(\"create new counter \", name).AtDebug().WriteToLog()\n\tc := new(Counter)\n\tm.counters[name] = c\n\treturn c, nil\n}\n\n// UnregisterCounter implements stats.Manager.\nfunc (m *Manager) UnregisterCounter(name string) error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tif _, found := m.counters[name]; found {\n\t\tnewError(\"remove counter \", name).AtDebug().WriteToLog()\n\t\tdelete(m.counters, name)\n\t}\n\treturn nil\n}\n\n// GetCounter implements stats.Manager.\nfunc (m *Manager) GetCounter(name string) stats.Counter {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\n\tif c, found := m.counters[name]; found {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// VisitCounters calls visitor function on all managed counters.\nfunc (m *Manager) VisitCounters(visitor func(string, stats.Counter) bool) {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\n\tfor name, c := range m.counters {\n\t\tif !visitor(name, c) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// RegisterChannel implements stats.Manager.\nfunc (m *Manager) RegisterChannel(name string) (stats.Channel, error) {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tif _, found := m.channels[name]; found {\n\t\treturn nil, newError(\"Channel \", name, \" already registered.\")\n\t}\n\tnewError(\"create new channel \", name).AtDebug().WriteToLog()\n\tc := NewChannel(&ChannelConfig{BufferSize: 64, Blocking: false})\n\tm.channels[name] = c\n\tif m.running {\n\t\treturn c, c.Start()\n\t}\n\treturn c, nil\n}\n\n// UnregisterChannel implements stats.Manager.\nfunc (m *Manager) UnregisterChannel(name string) error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\n\tif c, found := m.channels[name]; found {\n\t\tnewError(\"remove channel \", name).AtDebug().WriteToLog()\n\t\tdelete(m.channels, name)\n\t\treturn c.Close()\n\t}\n\treturn nil\n}\n\n// GetChannel implements stats.Manager.\nfunc (m *Manager) GetChannel(name string) stats.Channel {\n\tm.access.RLock()\n\tdefer m.access.RUnlock()\n\n\tif c, found := m.channels[name]; found {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// Start implements common.Runnable.\nfunc (m *Manager) Start() error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\tm.running = true\n\terrs := []error{}\n\tfor _, channel := range m.channels {\n\t\tif err := channel.Start(); err != nil {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\tif len(errs) != 0 {\n\t\treturn errors.Combine(errs...)\n\t}\n\treturn nil\n}\n\n// Close implement common.Closable.\nfunc (m *Manager) Close() error {\n\tm.access.Lock()\n\tdefer m.access.Unlock()\n\tm.running = false\n\terrs := []error{}\n\tfor name, channel := range m.channels {\n\t\tnewError(\"remove channel \", name).AtDebug().WriteToLog()\n\t\tdelete(m.channels, name)\n\t\tif err := channel.Close(); err != nil {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\tif len(errs) != 0 {\n\t\treturn errors.Combine(errs...)\n\t}\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewManager(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "app/stats/stats_test.go",
    "content": "package stats_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\nfunc TestInterface(t *testing.T) {\n\t_ = (stats.Manager)(new(Manager))\n}\n\nfunc TestStatsChannelRunnable(t *testing.T) {\n\traw, err := common.CreateObject(context.Background(), &Config{})\n\tcommon.Must(err)\n\n\tm := raw.(stats.Manager)\n\n\tch1, err := m.RegisterChannel(\"test.channel.1\")\n\tc1 := ch1.(*Channel)\n\tcommon.Must(err)\n\n\tif c1.Running() {\n\t\tt.Fatalf(\"unexpected running channel: test.channel.%d\", 1)\n\t}\n\n\tcommon.Must(m.Start())\n\n\tif !c1.Running() {\n\t\tt.Fatalf(\"unexpected non-running channel: test.channel.%d\", 1)\n\t}\n\n\tch2, err := m.RegisterChannel(\"test.channel.2\")\n\tc2 := ch2.(*Channel)\n\tcommon.Must(err)\n\n\tif !c2.Running() {\n\t\tt.Fatalf(\"unexpected non-running channel: test.channel.%d\", 2)\n\t}\n\n\ts1, err := c1.Subscribe()\n\tcommon.Must(err)\n\tcommon.Must(c1.Close())\n\n\tif c1.Running() {\n\t\tt.Fatalf(\"unexpected running channel: test.channel.%d\", 1)\n\t}\n\n\tselect { // Check all subscribers in closed channel are closed\n\tcase _, ok := <-s1:\n\t\tif ok {\n\t\t\tt.Fatalf(\"unexpected non-closed subscriber in channel: test.channel.%d\", 1)\n\t\t}\n\tcase <-time.After(500 * time.Millisecond):\n\t\tt.Fatalf(\"unexpected non-closed subscriber in channel: test.channel.%d\", 1)\n\t}\n\n\tif len(c1.Subscribers()) != 0 { // Check subscribers in closed channel are emptied\n\t\tt.Fatalf(\"unexpected non-empty subscribers in channel: test.channel.%d\", 1)\n\t}\n\n\tcommon.Must(m.Close())\n\n\tif c2.Running() {\n\t\tt.Fatalf(\"unexpected running channel: test.channel.%d\", 2)\n\t}\n\n\tch3, err := m.RegisterChannel(\"test.channel.3\")\n\tc3 := ch3.(*Channel)\n\tcommon.Must(err)\n\n\tif c3.Running() {\n\t\tt.Fatalf(\"unexpected running channel: test.channel.%d\", 3)\n\t}\n\n\tcommon.Must(c3.Start())\n\tcommon.Must(m.UnregisterChannel(\"test.channel.3\"))\n\n\tif c3.Running() { // Test that unregistering will close the channel.\n\t\tt.Fatalf(\"unexpected running channel: test.channel.%d\", 3)\n\t}\n}\n"
  },
  {
    "path": "app/subscription/config.pb.go",
    "content": "package subscription\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ImportSource struct {\n\tstate                protoimpl.MessageState `protogen:\"open.v1\"`\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\tTagPrefix            string                 `protobuf:\"bytes,3,opt,name=tag_prefix,json=tagPrefix,proto3\" json:\"tag_prefix,omitempty\"`\n\tImportUsingTag       string                 `protobuf:\"bytes,4,opt,name=import_using_tag,json=importUsingTag,proto3\" json:\"import_using_tag,omitempty\"`\n\tDefaultExpireSeconds uint64                 `protobuf:\"varint,5,opt,name=default_expire_seconds,json=defaultExpireSeconds,proto3\" json:\"default_expire_seconds,omitempty\"`\n\tunknownFields        protoimpl.UnknownFields\n\tsizeCache            protoimpl.SizeCache\n}\n\nfunc (x *ImportSource) Reset() {\n\t*x = ImportSource{}\n\tmi := &file_app_subscription_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ImportSource) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ImportSource) ProtoMessage() {}\n\nfunc (x *ImportSource) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_config_proto_msgTypes[0]\n\tif 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 ImportSource.ProtoReflect.Descriptor instead.\nfunc (*ImportSource) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ImportSource) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *ImportSource) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *ImportSource) GetTagPrefix() string {\n\tif x != nil {\n\t\treturn x.TagPrefix\n\t}\n\treturn \"\"\n}\n\nfunc (x *ImportSource) GetImportUsingTag() string {\n\tif x != nil {\n\t\treturn x.ImportUsingTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *ImportSource) GetDefaultExpireSeconds() uint64 {\n\tif x != nil {\n\t\treturn x.DefaultExpireSeconds\n\t}\n\treturn 0\n}\n\n// Config is the settings for Subscription Manager.\ntype Config struct {\n\tstate                         protoimpl.MessageState `protogen:\"open.v1\"`\n\tImports                       []*ImportSource        `protobuf:\"bytes,1,rep,name=imports,proto3\" json:\"imports,omitempty\"`\n\tNonnativeConverterOverlay     []byte                 `protobuf:\"bytes,2,opt,name=nonnative_converter_overlay,json=nonnativeConverterOverlay,proto3\" json:\"nonnative_converter_overlay,omitempty\"`\n\tNonnativeConverterOverlayFile string                 `protobuf:\"bytes,96002,opt,name=nonnative_converter_overlay_file,json=nonnativeConverterOverlayFile,proto3\" json:\"nonnative_converter_overlay_file,omitempty\"`\n\tPersistence                   bool                   `protobuf:\"varint,3,opt,name=persistence,proto3\" json:\"persistence,omitempty\"`\n\tunknownFields                 protoimpl.UnknownFields\n\tsizeCache                     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_subscription_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetImports() []*ImportSource {\n\tif x != nil {\n\t\treturn x.Imports\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetNonnativeConverterOverlay() []byte {\n\tif x != nil {\n\t\treturn x.NonnativeConverterOverlay\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetNonnativeConverterOverlayFile() string {\n\tif x != nil {\n\t\treturn x.NonnativeConverterOverlayFile\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetPersistence() bool {\n\tif x != nil {\n\t\treturn x.Persistence\n\t}\n\treturn false\n}\n\nvar File_app_subscription_config_proto protoreflect.FileDescriptor\n\nconst file_app_subscription_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1dapp/subscription/config.proto\\x12\\x1bv2ray.core.app.subscription\\x1a common/protoext/extensions.proto\\\"\\xb3\\x01\\n\" +\n\t\"\\fImportSource\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x10\\n\" +\n\t\"\\x03url\\x18\\x02 \\x01(\\tR\\x03url\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"tag_prefix\\x18\\x03 \\x01(\\tR\\ttagPrefix\\x12(\\n\" +\n\t\"\\x10import_using_tag\\x18\\x04 \\x01(\\tR\\x0eimportUsingTag\\x124\\n\" +\n\t\"\\x16default_expire_seconds\\x18\\x05 \\x01(\\x04R\\x14defaultExpireSeconds\\\"\\xba\\x02\\n\" +\n\t\"\\x06Config\\x12C\\n\" +\n\t\"\\aimports\\x18\\x01 \\x03(\\v2).v2ray.core.app.subscription.ImportSourceR\\aimports\\x12>\\n\" +\n\t\"\\x1bnonnative_converter_overlay\\x18\\x02 \\x01(\\fR\\x19nonnativeConverterOverlay\\x12l\\n\" +\n\t\" nonnative_converter_overlay_file\\x18\\x82\\xee\\x05 \\x01(\\tB!\\x82\\xb5\\x18\\x1d\\\"\\x1bnonnative_converter_overlayR\\x1dnonnativeConverterOverlayFile\\x12 \\n\" +\n\t\"\\vpersistence\\x18\\x03 \\x01(\\bR\\vpersistence:\\x1b\\x82\\xb5\\x18\\x17\\n\" +\n\t\"\\aservice\\x12\\fsubscriptionBr\\n\" +\n\t\"\\x1fcom.v2ray.core.app.subscriptionP\\x01Z/github.com/v2fly/v2ray-core/v5/app/subscription\\xaa\\x02\\x1bV2Ray.Core.App.Subscriptionb\\x06proto3\"\n\nvar (\n\tfile_app_subscription_config_proto_rawDescOnce sync.Once\n\tfile_app_subscription_config_proto_rawDescData []byte\n)\n\nfunc file_app_subscription_config_proto_rawDescGZIP() []byte {\n\tfile_app_subscription_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_subscription_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_subscription_config_proto_rawDesc), len(file_app_subscription_config_proto_rawDesc)))\n\t})\n\treturn file_app_subscription_config_proto_rawDescData\n}\n\nvar file_app_subscription_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_app_subscription_config_proto_goTypes = []any{\n\t(*ImportSource)(nil), // 0: v2ray.core.app.subscription.ImportSource\n\t(*Config)(nil),       // 1: v2ray.core.app.subscription.Config\n}\nvar file_app_subscription_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.app.subscription.Config.imports:type_name -> v2ray.core.app.subscription.ImportSource\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_app_subscription_config_proto_init() }\nfunc file_app_subscription_config_proto_init() {\n\tif File_app_subscription_config_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: unsafe.Slice(unsafe.StringData(file_app_subscription_config_proto_rawDesc), len(file_app_subscription_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_subscription_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_subscription_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_subscription_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_subscription_config_proto = out.File\n\tfile_app_subscription_config_proto_goTypes = nil\n\tfile_app_subscription_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/subscription/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.subscription;\n\noption csharp_namespace = \"V2Ray.Core.App.Subscription\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/subscription\";\noption java_package = \"com.v2ray.core.app.subscription\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage ImportSource {\n  string name = 1;\n  string url = 2;\n  string tag_prefix = 3;\n\n  string import_using_tag = 4;\n\n  uint64 default_expire_seconds = 5;\n}\n\n// Config is the settings for Subscription Manager.\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"subscription\";\n\n  repeated ImportSource imports = 1;\n\n  bytes nonnative_converter_overlay = 2;\n  string nonnative_converter_overlay_file = 96002 [(v2ray.core.common.protoext.field_opt).convert_time_read_file_into = \"nonnative_converter_overlay\"];\n\n  bool persistence = 3;\n}"
  },
  {
    "path": "app/subscription/containers/base64urlline/base64urlline.go",
    "content": "package base64urlline\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/subscription/containers/base64urlline/errors.generated.go",
    "content": "package base64urlline\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/containers/base64urlline/parser.go",
    "content": "package base64urlline\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc newBase64URLLineParser() containers.SubscriptionContainerDocumentParser {\n\treturn &parser{}\n}\n\ntype parser struct{}\n\nfunc (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {\n\tresult := &containers.Container{}\n\tresult.Kind = \"Base64URLLine\"\n\tresult.Metadata = make(map[string]string)\n\n\tbodyDecoder := base64.NewDecoder(base64.StdEncoding, bytes.NewReader(rawConfig))\n\tdecoded, err := io.ReadAll(bodyDecoder)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to decode base64url body base64\").Base(err)\n\t}\n\tscanner := bufio.NewScanner(bytes.NewReader(decoded))\n\n\tconst maxCapacity int = 1024 * 256\n\tbuf := make([]byte, maxCapacity)\n\tscanner.Buffer(buf, maxCapacity)\n\n\tfor scanner.Scan() {\n\t\tresult.ServerSpecs = append(result.ServerSpecs, containers.UnparsedServerConf{\n\t\t\tKindHint: \"URL\",\n\t\t\tContent:  scanner.Bytes(),\n\t\t})\n\t}\n\treturn result, nil\n}\n\nfunc init() {\n\tcommon.Must(containers.RegisterParser(\"Base64URLLine\", newBase64URLLineParser()))\n}\n"
  },
  {
    "path": "app/subscription/containers/containers.go",
    "content": "package containers\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype UnparsedServerConf struct {\n\tKindHint string\n\tContent  []byte\n}\n\ntype Container struct {\n\tKind        string\n\tMetadata    map[string]string\n\tServerSpecs []UnparsedServerConf\n}\n\ntype SubscriptionContainerDocumentParser interface {\n\tParseSubscriptionContainerDocument(rawConfig []byte) (*Container, error)\n}\n\nvar knownParsers = make(map[string]SubscriptionContainerDocumentParser)\n\nfunc RegisterParser(kind string, parser SubscriptionContainerDocumentParser) error {\n\tif _, found := knownParsers[kind]; found {\n\t\treturn newError(\"parser already registered for kind \", kind)\n\t}\n\tknownParsers[kind] = parser\n\treturn nil\n}\n"
  },
  {
    "path": "app/subscription/containers/dataurlsingle/dataurl.go",
    "content": "package dataurlsingle\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\n\t\"github.com/vincent-petithory/dataurl\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc newSingularDataURLParser() containers.SubscriptionContainerDocumentParser {\n\treturn &parser{}\n}\n\ntype parser struct{}\n\nfunc (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {\n\tdataURL, err := dataurl.Decode(bytes.NewReader(rawConfig))\n\tif err != nil {\n\t\treturn nil, newError(\"unable to decode dataURL\").Base(err)\n\t}\n\tif dataURL.MediaType.Type != \"application\" {\n\t\treturn nil, newError(\"unsupported media type: \", dataURL.MediaType.Type)\n\t}\n\tif !strings.HasPrefix(dataURL.MediaType.Subtype, \"vnd.v2ray.subscription-singular\") {\n\t\treturn nil, newError(\"unsupported media subtype: \", dataURL.MediaType.Subtype)\n\t}\n\tresult := &containers.Container{}\n\tresult.Kind = \"DataURLSingle\"\n\tresult.Metadata = make(map[string]string)\n\tresult.ServerSpecs = append(result.ServerSpecs, containers.UnparsedServerConf{\n\t\tKindHint: \"\",\n\t\tContent:  dataURL.Data,\n\t})\n\treturn result, nil\n}\n\nfunc init() {\n\tcommon.Must(containers.RegisterParser(\"DataURLSingle\", newSingularDataURLParser()))\n}\n"
  },
  {
    "path": "app/subscription/containers/dataurlsingle/errors.generated.go",
    "content": "package dataurlsingle\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/containers/errors.generated.go",
    "content": "package containers\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/containers/jsonfieldarray/errors.generated.go",
    "content": "package jsonfieldarray\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/containers/jsonfieldarray/jsonfieldarray.go",
    "content": "package jsonfieldarray\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/subscription/containers/jsonfieldarray/jsonified/errors.generated.go",
    "content": "package jsonified\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/containers/jsonfieldarray/jsonified/jsonified.go",
    "content": "package jsonified\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/subscription/containers/jsonfieldarray/jsonified/parser.go",
    "content": "package jsonified\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tjsonConf \"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n)\n\nfunc newJsonifiedYamlParser() containers.SubscriptionContainerDocumentParser {\n\treturn &jsonifiedYAMLParser{}\n}\n\ntype jsonifiedYAMLParser struct{}\n\nfunc (j jsonifiedYAMLParser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {\n\tparser := jsonfieldarray.NewJSONFieldArrayParser()\n\tjsonified, err := jsonConf.FromYAML(rawConfig)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse as yaml\").Base(err)\n\t}\n\tcontainer, err := parser.ParseSubscriptionContainerDocument(jsonified)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse as jsonfieldarray\").Base(err)\n\t}\n\tcontainer.Kind = \"Yaml2Json+\" + container.Kind\n\n\tfor _, value := range container.ServerSpecs {\n\t\tvalue.KindHint = \"Yaml2Json+\" + value.KindHint\n\t}\n\treturn container, nil\n}\n\nfunc init() {\n\tcommon.Must(containers.RegisterParser(\"Yaml2Json\", newJsonifiedYamlParser()))\n}\n"
  },
  {
    "path": "app/subscription/containers/jsonfieldarray/parser.go",
    "content": "package jsonfieldarray\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n// NewJSONFieldArrayParser internal api\nfunc NewJSONFieldArrayParser() containers.SubscriptionContainerDocumentParser {\n\treturn newJSONFieldArrayParser()\n}\n\nfunc newJSONFieldArrayParser() containers.SubscriptionContainerDocumentParser {\n\treturn &parser{}\n}\n\ntype parser struct{}\n\ntype jsonDocument map[string]json.RawMessage\n\nfunc (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {\n\tresult := &containers.Container{}\n\tresult.Kind = \"JsonFieldArray\"\n\tresult.Metadata = make(map[string]string)\n\n\tvar doc jsonDocument\n\tif err := json.Unmarshal(rawConfig, &doc); err != nil {\n\t\treturn nil, newError(\"failed to parse as json\").Base(err)\n\t}\n\n\tfor key, value := range doc {\n\t\tswitch value[0] {\n\t\tcase '[':\n\t\t\tparsedArray, err := p.parseArray(value, \"JsonFieldArray+\"+key)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse as json array\").Base(err)\n\t\t\t}\n\t\t\tresult.ServerSpecs = append(result.ServerSpecs, parsedArray...)\n\t\tcase '{':\n\t\t\tfallthrough\n\t\tdefault:\n\t\t\tresult.Metadata[key] = string(value)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc (p parser) parseArray(rawConfig []byte, kindHint string) ([]containers.UnparsedServerConf, error) {\n\tvar result []json.RawMessage\n\tif err := json.Unmarshal(rawConfig, &result); err != nil {\n\t\treturn nil, newError(\"failed to parse as json array\").Base(err)\n\t}\n\tvar ret []containers.UnparsedServerConf\n\tfor _, value := range result {\n\t\tret = append(ret, containers.UnparsedServerConf{\n\t\t\tKindHint: kindHint,\n\t\t\tContent:  []byte(value),\n\t\t})\n\t}\n\treturn ret, nil\n}\n\nfunc init() {\n\tcommon.Must(containers.RegisterParser(\"JsonFieldArray\", newJSONFieldArrayParser()))\n}\n"
  },
  {
    "path": "app/subscription/containers/tryall.go",
    "content": "package containers\n\nfunc TryAllParsers(rawConfig []byte, prioritizedParser string) (*Container, error) {\n\tif prioritizedParser != \"\" {\n\t\tif parser, found := knownParsers[prioritizedParser]; found {\n\t\t\tcontainer, err := parser.ParseSubscriptionContainerDocument(rawConfig)\n\t\t\tif err == nil {\n\t\t\t\treturn container, nil\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, parser := range knownParsers {\n\t\tcontainer, err := parser.ParseSubscriptionContainerDocument(rawConfig)\n\t\tif err == nil {\n\t\t\treturn container, nil\n\t\t}\n\t}\n\treturn nil, newError(\"no parser found for config\")\n}\n"
  },
  {
    "path": "app/subscription/containers/urlline/errors.generated.go",
    "content": "package urlline\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/containers/urlline/parser.go",
    "content": "package urlline\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc newURLLineParser() containers.SubscriptionContainerDocumentParser {\n\treturn &parser{}\n}\n\ntype parser struct{}\n\nfunc (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {\n\tresult := &containers.Container{}\n\tresult.Kind = \"URLLine\"\n\tresult.Metadata = make(map[string]string)\n\n\tscanner := bufio.NewScanner(bytes.NewReader(rawConfig))\n\n\tconst maxCapacity int = 1024 * 256\n\tbuf := make([]byte, maxCapacity)\n\tscanner.Buffer(buf, maxCapacity)\n\n\tparsedLine := 0\n\tfailedLine := 0\n\n\tfor scanner.Scan() {\n\t\tcontent := scanner.Text()\n\t\tcontent = strings.TrimSpace(content)\n\t\tif strings.HasPrefix(content, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(content, \"//\") {\n\t\t\tcontinue\n\t\t}\n\t\t_, err := url.Parse(content)\n\t\tif err != nil {\n\t\t\tfailedLine++\n\t\t\tcontinue\n\t\t} else {\n\t\t\tparsedLine++\n\t\t}\n\t\tresult.ServerSpecs = append(result.ServerSpecs, containers.UnparsedServerConf{\n\t\t\tKindHint: \"URL\",\n\t\t\tContent:  scanner.Bytes(),\n\t\t})\n\t}\n\n\tif failedLine > parsedLine || parsedLine == 0 {\n\t\treturn nil, newError(\"failed to parse as URLLine\").Base(newError(\"too many failed lines\"))\n\t}\n\n\treturn result, nil\n}\n\nfunc init() {\n\tcommon.Must(containers.RegisterParser(\"URLLine\", newURLLineParser()))\n}\n"
  },
  {
    "path": "app/subscription/containers/urlline/urlline.go",
    "content": "package urlline\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/subscription/documentfetcher/dataurlfetcher/dataurl.go",
    "content": "package dataurlfetcher\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/vincent-petithory/dataurl\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc newDataURLFetcher() *dataURLFetcher {\n\treturn &dataURLFetcher{}\n}\n\nfunc init() {\n\tcommon.Must(documentfetcher.RegisterFetcher(\"dataurl\", newDataURLFetcher()))\n}\n\ntype dataURLFetcher struct{}\n\nfunc (d *dataURLFetcher) DownloadDocument(ctx context.Context, source *subscription.ImportSource, opts ...documentfetcher.FetcherOptions) ([]byte, error) {\n\tdataURL, err := dataurl.DecodeString(source.Url)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to decode dataURL\").Base(err)\n\t}\n\tif dataURL.MediaType.Type != \"application\" {\n\t\treturn nil, newError(\"unsupported media type: \", dataURL.MediaType.Type)\n\t}\n\tif !strings.HasPrefix(dataURL.MediaType.Subtype, \"vnd.v2ray.subscription\") {\n\t\treturn nil, newError(\"unsupported media subtype: \", dataURL.MediaType.Subtype)\n\t}\n\treturn []byte(source.Url), nil\n}\n"
  },
  {
    "path": "app/subscription/documentfetcher/dataurlfetcher/errors.generated.go",
    "content": "package dataurlfetcher\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/documentfetcher/errors.generated.go",
    "content": "package documentfetcher\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/documentfetcher/fetcher.go",
    "content": "package documentfetcher\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype FetcherOptions interface{}\n\ntype Fetcher interface {\n\tDownloadDocument(ctx context.Context, source *subscription.ImportSource, opts ...FetcherOptions) ([]byte, error)\n}\n\nvar knownFetcher = make(map[string]Fetcher)\n\nfunc RegisterFetcher(name string, fetcher Fetcher) error {\n\tif _, found := knownFetcher[name]; found {\n\t\treturn newError(\"fetcher \", name, \" already registered\")\n\t}\n\tknownFetcher[name] = fetcher\n\treturn nil\n}\n\nfunc GetFetcher(name string) (Fetcher, error) {\n\tif fetcher, found := knownFetcher[name]; found {\n\t\treturn fetcher, nil\n\t}\n\treturn nil, newError(\"fetcher \", name, \" not found\")\n}\n"
  },
  {
    "path": "app/subscription/documentfetcher/httpfetcher/errors.generated.go",
    "content": "package httpfetcher\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/documentfetcher/httpfetcher/http.go",
    "content": "package httpfetcher\n\nimport (\n\t\"context\"\n\t\"io\"\n\tgonet \"net\"\n\t\"net/http\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc newHTTPFetcher() *httpFetcher {\n\treturn &httpFetcher{}\n}\n\nfunc init() {\n\tcommon.Must(documentfetcher.RegisterFetcher(\"http\", newHTTPFetcher()))\n}\n\ntype httpFetcher struct{}\n\nfunc (h *httpFetcher) DownloadDocument(ctx context.Context, source *subscription.ImportSource, opts ...documentfetcher.FetcherOptions) ([]byte, error) {\n\tinstanceNetwork := envctx.EnvironmentFromContext(ctx).(environment.InstanceNetworkCapabilitySet)\n\toutboundDialer := instanceNetwork.OutboundDialer()\n\tvar httpRoundTripper http.RoundTripper //nolint: gosimple\n\thttpRoundTripper = &http.Transport{\n\t\tDialContext: func(ctx_ context.Context, network string, addr string) (gonet.Conn, error) {\n\t\t\tdest, err := net.ParseDestination(network + \":\" + addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"unable to parse destination\")\n\t\t\t}\n\t\t\treturn outboundDialer(ctx, dest, source.ImportUsingTag)\n\t\t},\n\t}\n\trequest, err := http.NewRequest(\"GET\", source.Url, nil)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to generate request\").Base(err)\n\t}\n\tresp, err := httpRoundTripper.RoundTrip(request)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to send request\").Base(err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, newError(\"unexpected http status \", resp.StatusCode, \"=\", resp.Status)\n\t}\n\tdata, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to read response\").Base(err)\n\t}\n\treturn data, nil\n}\n"
  },
  {
    "path": "app/subscription/entries/entries.go",
    "content": "package entries\n\nimport \"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype Converter interface {\n\tConvertToAbstractServerConfig(rawConfig []byte, kindHint string) (*specs.SubscriptionServerConfig, error)\n}\n"
  },
  {
    "path": "app/subscription/entries/errors.generated.go",
    "content": "package entries\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/entries/nonnative/converter.go",
    "content": "package nonnative\n\nimport (\n\t\"io/fs\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries/nonnative/nonnativeifce\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype nonNativeConverter struct {\n\tmatcher *DefMatcher\n}\n\nfunc (n *nonNativeConverter) ConvertToAbstractServerConfig(rawConfig []byte, kindHint string) (*specs.SubscriptionServerConfig, error) {\n\tnonNativeLink := ExtractAllValuesFromBytes(rawConfig)\n\tnonNativeLink.Values[\"_kind\"] = kindHint\n\tresult, err := n.matcher.ExecuteAll(nonNativeLink)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to find working converting template\").Base(err)\n\t}\n\toutboundParser := outbound.NewOutboundEntriesParser()\n\toutboundEntries, err := outboundParser.ConvertToAbstractServerConfig(result, \"\")\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse template output as outbound entries\").Base(err)\n\t}\n\treturn outboundEntries, nil\n}\n\nfunc NewNonNativeConverter(fs fs.FS) (entries.Converter, error) {\n\tmatcher := NewDefMatcher()\n\tif fs == nil {\n\t\terr := matcher.LoadEmbeddedDefinitions()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to load embedded definitions\").Base(err)\n\t\t}\n\t} else {\n\t\terr := matcher.LoadDefinitions(fs)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to load provided definitions\").Base(err)\n\t\t}\n\t}\n\treturn &nonNativeConverter{matcher: matcher}, nil\n}\n\nfunc init() {\n\tcommon.Must(entries.RegisterConverter(\"nonnative\", common.Must2(NewNonNativeConverter(nil)).(entries.Converter)))\n\tnonnativeifce.NewNonNativeConverterConstructor = NewNonNativeConverter\n}\n"
  },
  {
    "path": "app/subscription/entries/nonnative/definitions/shadowsocks.jsont",
    "content": "{{if assertExists . \"root_!kind\" | not}} Unknown environment {{end}}\n{{if assertIsOneOf . \"root_!kind\" \"json\" \"link\" | not}} This template only works for json input. {{end}}\n\n{{ $type := tryGet . \"root_!kind\"}}\n\n{{ $methodName := tryGet . \"root_!json_method_!unquoted\" \"root_!json_protocol_!unquoted\" \"root_!json_cipher_!unquoted\" \"root_!link_userinfo_!value_!rawContent\"}}\n{{ if eq $type \"link\" }}\n    {{ $methodName = splitAndGetNth \":\" 0 $methodName}}\n{{end}}\n{{if assertValueIsOneOf $methodName \"chacha20-ietf-poly1305\" \"chacha20-poly1305\" \"aes-128-gcm\" \"aes-256-gcm\" | not}}\n    This template only works for ss. {{end}}\n\n{{ $server_address := tryGet . \"root_!json_server\" \"root_!json_address\" \"root_!json_endpoint\" \"root_!link_host\"}}\n{{ $server_port := tryGet . \"root_!json_port\" \"root_!json_server_port\" \"root_!json_endpoint\" \"root_!link_host\"}}\n{{if $server_address | splitAndGetAfterNth \":\" 0 | len | lt 1}}\n    {{ $server_addressport_unquoted := tryGet . \"root_!json_endpoint_!unquoted\" \"root_!link_host\"}}\n    {{ $server_port = $server_addressport_unquoted | splitAndGetNth \":\" -1}}\n\n    {{ $server_portWithSep := printf \":%v\" $server_port}}\n    {{ $server_address = $server_addressport_unquoted | stringCutSuffix $server_portWithSep | jsonEncode}}\n{{end}}\n\n{{ $name_annotation := tryGet . \"root_!json_name_!unquoted\" \"root_!json_id_!unquoted\" \"root_!json_tag_!unquoted\" \"root_!json_remarks_!unquoted\" \"root_!link_fragment\" \"<default>\"}}\n\n{{$password := tryGet . \"root_!json_password\" \"root_!json_psk\" \"root_!link_userinfo_!value_!rawContent\"}}\n{{ if eq $type \"link\" }}\n    {{ $password = splitAndGetNth \":\" 1 $password | jsonEncode}}\n{{end}}\n\n{\n    \"protocol\": \"shadowsocks\",\n    \"settings\": {\n        \"address\": {{$server_address}},\n        \"port\": {{$server_port}},\n        \"method\": {{$methodName | jsonEncode}},\n        \"password\": {{$password}}\n        },\n    \"metadata\":{\n\n        \"TagName\": {{print $name_annotation \"_\" $server_address | jsonEncode}},\n        \"DisplayName\": {{print $name_annotation | jsonEncode}}\n    }\n}"
  },
  {
    "path": "app/subscription/entries/nonnative/definitions/shadowsocks2022.jsont",
    "content": "{{if assertExists . \"root_!kind\" | not}} Unknown environment {{end}}\n{{if assertIsOneOf . \"root_!kind\" \"json\" | not}} This template only works for json input. {{end}}\n\n{{ $methodName := tryGet . \"root_!json_method_!unquoted\" \"root_!json_protocol_!unquoted\"}}\n{{if assertValueIsOneOf $methodName \"2022-blake3-aes-128-gcm\" \"2022-blake3-aes-256-gcm\" | not}}\n    This template only works for ss2022. {{end}}\n\n{{ $server_address := tryGet . \"root_!json_server\" \"root_!json_address\" \"root_!json_endpoint\"}}\n{{ $server_port := tryGet . \"root_!json_port\" \"root_!json_server_port\" \"root_!json_endpoint\"}}\n{{if $server_address | splitAndGetAfterNth \":\" 0 | len | gt 1}}\n    {{ $server_addressport_unquoted := tryGet . \"root_!json_endpoint_!unquoted\"}}\n    {{ $server_port = $server_addressport_unquoted | splitAndGetAfterNth \":\" -1}}\n\n    {{ $server_portWithSep := printf \":%v\" $server_port}}\n    {{ $server_address = $server_addressport_unquoted | stringCutSuffix $server_portWithSep | jsonEncode}}\n{{end}}\n\n{{ $name_annotation := tryGet . \"root_!json_name_!unquoted\" \"root_!json_id_!unquoted\" \"root_!json_tag_!unquoted\" \"root_!json_remarks_!unquoted\" \"<default>\"}}\n\n{{ $psk := tryGet . \"root_!json_password_!unquoted\" \"root_!json_psk_!unquoted\"}}\n{{ $ipsk_encoded := \"\" }}\n{{if $psk | splitAndGetAfterNth \":\" 0 | len | ne 1}}\n    {{ $origpsk := $psk }}\n    {{ $psk = $psk | splitAndGetNth \":\" -1 }}\n    {{ $pskWithSep := printf \":%v\" $psk}}\n    {{ $ipsk_encoded = $origpsk | stringCutSuffix $pskWithSep | splitAndGetAfterNth \":\" 0 | jsonEncode}}\n{{else}}\n    {{$ipsk_encoded = tryGet . \"root_!json_iPSKs\" \"<default>\"}}\n{{end}}\n\n\n    {\n      \"protocol\": \"shadowsocks2022\",\n      \"settings\": {\n        \"address\": {{$server_address}},\n        \"port\": {{$server_port}},\n        \"method\": {{$methodName | jsonEncode}},\n        \"psk\": {{$psk | jsonEncode}}\n        {{if $ipsk_encoded|len|ne 0}}\n                ,\n                \"ipsk\": {{$ipsk_encoded}}\n        {{end}}\n      },\n\n    \"metadata\":{\n\n    \"TagName\": {{print $name_annotation \"_\" $server_address | jsonEncode}},\n    \"DisplayName\": {{print $name_annotation | jsonEncode}}\n    }\n\n    }"
  },
  {
    "path": "app/subscription/entries/nonnative/definitions/vmess.jsont",
    "content": "{{if assertExists . \"root_!kind\" | not}} Unknown environment {{end}}\n{{ $protocol_name := tryGet . \"root_!link_protocol\" \"root_!json_type_!unquoted\"}}\n{{if assertValueIsOneOf $protocol_name \"vmess\" | not}} This template will only handle vmess link {{end}}\n\n{{ $server_address := tryGet . \"root_!link_host_!base64_!json_add\" \"root_!json_server\"}}\n{{ $server_uuid := tryGet . \"root_!link_host_!base64_!json_id\" \"root_!json_uuid\"}}\n{{ $server_port := tryGet . \"root_!link_host_!base64_!json_port_!unquoted\" \"root_!link_host_!base64_!json_port\" \"root_!json_port_!unquoted\" \"root_!json_port\"}}\n\n{{ $transport_type := tryGet . \"root_!link_host_!base64_!json_net_!unquoted\" \"root_!json_network_!unquoted\" \"<default>\"}}\n{{ $transport_type = $transport_type | unalias \"tcp\" \"\"}}\n\n{{ $name_annotation := tryGet . \"root_!link_host_!base64_!json_ps_!unquoted\" \"root_!json_name_!unquoted\" \"<default>\"}}\n\n{{if assertValueIsOneOf $transport_type \"tcp\" \"kcp\" \"ws\" \"h2\" \"quic\" \"grpc\"| not }}\n    unknown transport type {{end}}\n\n    {{$transport_grpc_service_name := \"\"}}\n    {{ if $transport_type | eq \"grpc\"}}\n        {{ $transport_grpc_service_name = tryGet . \"root_!link_host_!base64_!json_path\" \"<default>\"}}\n    {{end}}\n\n    {{$transport_ws_path := \"\"}}\n    {{ if $transport_type | eq \"ws\"}}\n        {{ $transport_ws_path = tryGet . \"root_!link_host_!base64_!json_path\" \"root_!json_ws-opts_!json_path\" \"<default>\"}}\n    {{end}}\n\n{{ $security_type := tryGet . \"root_!link_host_!base64_!json_tls_!unquoted\" \"root_!json_tls\" \"<default>\"}}\n{{ $security_type = $security_type | unalias \"none\" \"\" \"false\" \"0\"}}\n\n{{if assertValueIsOneOf $security_type \"tls\" \"utls\" \"none\"| not }}\n    unknown security type {{end}}\n\n{{ $security_tlsmmon_sni := tryGet . \"root_!link_host_!base64_!json_sni\" \"<default>\"}}\n{{ $security_tlsmmon_sni = $security_tlsmmon_sni | unalias $server_address \"\"}}\n\n{\n \"protocol\": \"vmess\",\n \"settings\":{\n    \"address\":{{$server_address}},\n    \"port\":{{$server_port}},\n    \"uuid\":{{$server_uuid}}\n    },\n    \"streamSettings\":{\n        \"transport\":{{$transport_type|jsonEncode}},\n        \"security\":{{$security_type|jsonEncode}},\n        \"transportSettings\":{\n        {{ if $transport_type | eq \"grpc\"}}\n            \"serviceName\":{{$transport_grpc_service_name}}\n        {{end}}\n        {{ if $transport_type | eq \"ws\"}}\n            \"path\":{{$transport_ws_path}}\n        {{end}}\n        },\n\n        \"securitySettings\":{\n        {{ if $security_type | eq \"tls\"}}\n            \"serverName\":{{$security_tlsmmon_sni}}\n        {{end}}\n        }\n    },\n  \"metadata\":{\n    \"TagName\": {{print $name_annotation \"_\" $server_address | jsonEncode}},\n    \"DisplayName\": {{print $name_annotation | jsonEncode}}\n  }\n}\n"
  },
  {
    "path": "app/subscription/entries/nonnative/errors.generated.go",
    "content": "package nonnative\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/entries/nonnative/matchdef.go",
    "content": "package nonnative\n\nimport (\n\t\"bytes\"\n\t\"embed\"\n\t\"encoding/json\"\n\t\"io/fs\"\n\t\"strings\"\n\t\"text/template\"\n)\n\n//go:embed definitions/*\nvar embeddedDefinitions embed.FS\n\nfunc NewDefMatcher() *DefMatcher {\n\td := &DefMatcher{}\n\td.init()\n\treturn d\n}\n\ntype DefMatcher struct {\n\ttemplates *template.Template\n}\n\ntype ExecutionEnvironment struct {\n\tlink AbstractNonNativeLink\n}\n\nfunc (d *DefMatcher) createFuncMap() template.FuncMap {\n\treturn map[string]any{\n\t\t\"assertExists\": func(env *ExecutionEnvironment, names ...string) (bool, error) {\n\t\t\tlink := env.link\n\t\t\tfor _, v := range names {\n\t\t\t\t_, ok := link.Values[v]\n\t\t\t\tif !ok {\n\t\t\t\t\treturn false, newError(\"failed assertExists of \", v)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true, nil\n\t\t},\n\t\t\"assertIsOneOf\": func(env *ExecutionEnvironment, name string, values ...string) (bool, error) {\n\t\t\tlink := env.link\n\t\t\tactualValue, ok := link.Values[name]\n\t\t\tif !ok {\n\t\t\t\treturn false, newError(\"failed assertIs of non-exist \", name)\n\t\t\t}\n\t\t\tfound := false\n\t\t\tfor _, currentValue := range values {\n\t\t\t\tif currentValue == actualValue {\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\treturn false, newError(\"failed assertIsOneOf name = \", actualValue, \"is not one of \", values)\n\t\t\t}\n\t\t\treturn true, nil\n\t\t},\n\t\t\"assertValueIsOneOf\": func(value string, values ...string) (bool, error) {\n\t\t\tactualValue := value\n\t\t\tfound := false\n\t\t\tfor _, currentValue := range values {\n\t\t\t\tif currentValue == actualValue {\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\treturn false, newError(\"failed assertIsOneOf name = \", actualValue, \"is not one of \", values)\n\t\t\t}\n\t\t\treturn true, nil\n\t\t},\n\t\t\"tryGet\": func(env *ExecutionEnvironment, names ...string) (string, error) {\n\t\t\tlink := env.link\n\t\t\tfor _, currentName := range names {\n\t\t\t\tvalue, ok := link.Values[currentName]\n\t\t\t\tif ok {\n\t\t\t\t\treturn value, nil\n\t\t\t\t} else if currentName == \"<default>\" {\n\t\t\t\t\treturn \"\", nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn \"\", newError(\"failed tryGet exists none of \", names)\n\t\t},\n\t\t\"splitAndGetNth\": func(sep string, n int, content string) (string, error) {\n\t\t\tresult := strings.Split(content, sep)\n\t\t\tif n > len(result)-1 {\n\t\t\t\treturn \"\", newError(\"failed splitAndGetNth exists too short content:\", content, \"n = \", n, \"sep =\", sep)\n\t\t\t}\n\t\t\tif n < 0 {\n\t\t\t\tn = len(result) + n\n\t\t\t\tif n < 0 {\n\t\t\t\t\treturn \"\", newError(\"failed splitAndGetNth exists too short content:\", content, \"n = \", n, \"sep =\", sep)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result[n], nil\n\t\t},\n\t\t\"splitAndGetAfterNth\": func(sep string, n int, content string) ([]string, error) {\n\t\t\tresult := strings.Split(content, sep)\n\t\t\tif n < 0 {\n\t\t\t\tn = len(result) + n\n\t\t\t}\n\t\t\tif n > len(result)-1 {\n\t\t\t\treturn []string{}, newError(\"failed splitAndGetNth exists too short content:\", content)\n\t\t\t}\n\t\t\treturn result[n:], nil\n\t\t},\n\t\t\"splitAndGetBeforeNth\": func(sep string, n int, content string) ([]string, error) {\n\t\t\tresult := strings.Split(content, sep)\n\t\t\tif n < 0 {\n\t\t\t\tn = len(result) + n\n\t\t\t}\n\t\t\tif n > len(result)-1 {\n\t\t\t\treturn []string{}, newError(\"failed splitAndGetNth exists too short content:\", content)\n\t\t\t}\n\t\t\treturn result[:n], nil\n\t\t},\n\t\t\"jsonEncode\": func(content any) (string, error) {\n\t\t\tbuf := bytes.NewBuffer(nil)\n\t\t\terr := json.NewEncoder(buf).Encode(content)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", newError(\"unable to jsonQuote \", content).Base(err)\n\t\t\t}\n\t\t\treturn buf.String(), nil\n\t\t},\n\t\t\"stringCutSuffix\": func(suffix, content string) (string, error) {\n\t\t\tremaining, found := strings.CutSuffix(content, suffix)\n\t\t\tif !found {\n\t\t\t\treturn \"\", newError(\"suffix not found in content =\", suffix, \" suffix =\", suffix)\n\t\t\t}\n\t\t\treturn remaining, nil\n\t\t},\n\t\t\"unalias\": func(standardName string, names ...string) (string, error) {\n\t\t\tif len(names) == 0 {\n\t\t\t\treturn \"\", newError(\"no input value specified\")\n\t\t\t}\n\t\t\tactualInput := names[len(names)-1]\n\t\t\talias := names[:len(names)-1]\n\t\t\tfor _, v := range alias {\n\t\t\t\tif v == actualInput {\n\t\t\t\t\treturn standardName, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn actualInput, nil\n\t\t},\n\t}\n}\n\nfunc (d *DefMatcher) init() {\n\td.templates = template.New(\"root\").Funcs(d.createFuncMap())\n}\n\nfunc (d *DefMatcher) LoadEmbeddedDefinitions() error {\n\treturn d.LoadDefinitions(embeddedDefinitions)\n}\n\nfunc (d *DefMatcher) LoadDefinitions(fs fs.FS) error {\n\tvar err error\n\td.templates, err = d.templates.ParseFS(fs, \"definitions/*.jsont\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (d *DefMatcher) ExecuteNamed(link AbstractNonNativeLink, name string) ([]byte, error) {\n\toutputBuffer := bytes.NewBuffer(nil)\n\tenv := &ExecutionEnvironment{link: link}\n\terr := d.templates.ExecuteTemplate(outputBuffer, name, env)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to execute template\").Base(err)\n\t}\n\treturn outputBuffer.Bytes(), nil\n}\n\nfunc (d *DefMatcher) ExecuteAll(link AbstractNonNativeLink) ([]byte, error) {\n\toutputBuffer := bytes.NewBuffer(nil)\n\tfor _, loadedTemplates := range d.templates.Templates() {\n\t\tenv := &ExecutionEnvironment{link: link}\n\t\terr := loadedTemplates.Execute(outputBuffer, env)\n\t\tif err != nil {\n\t\t\toutputBuffer.Reset()\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\tif outputBuffer.Len() == 0 {\n\t\treturn nil, newError(\"failed to find a working template\")\n\t}\n\treturn outputBuffer.Bytes(), nil\n}\n"
  },
  {
    "path": "app/subscription/entries/nonnative/nonnative.go",
    "content": "package nonnative\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc ExtractAllValuesFromBytes(bytes []byte) AbstractNonNativeLink {\n\tlink := AbstractNonNativeLink{}\n\tlink.fromBytes(bytes)\n\treturn link\n}\n\ntype jsonDocument map[string]json.RawMessage\n\ntype AbstractNonNativeLink struct {\n\tValues map[string]string\n}\n\nfunc (a *AbstractNonNativeLink) fromBytes(bytes []byte) {\n\ta.Values = make(map[string]string)\n\tcontent := string(bytes)\n\tcontent = strings.Trim(content, \" \\n\\t\\r\")\n\ta.extractValue(content, \"root\")\n}\n\nfunc (a *AbstractNonNativeLink) extractValue(content, prefix string) {\n\tif content == \"\" {\n\t\treturn\n\t}\n\n\t{\n\t\t// check if the content is a link\n\t\tmatch, err := regexp.Match(\"[a-zA-Z0-9]+:((\\\\/\\\\/)|\\\\?)\", []byte(content))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif match {\n\t\t\t// if so, parse as link\n\t\t\tparsedURL, err := url.Parse(content)\n\t\t\t// if process is successful, then continue to parse every element of the link\n\t\t\tif err == nil {\n\t\t\t\ta.Values[prefix+\"_!kind\"] = \"link\"\n\t\t\t\ta.extractLink(parsedURL, prefix)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\t// check if it is base64\n\t\tcontent = strings.Trim(content, \"=\")\n\t\tdecoded, err := base64.RawStdEncoding.DecodeString(content)\n\t\tif err == nil {\n\t\t\ta.Values[prefix+\"_!kind\"] = \"base64\"\n\t\t\ta.Values[prefix+\"_!rawContent\"] = string(decoded)\n\t\t\ta.extractValue(string(decoded), prefix+\"_!base64\")\n\t\t\treturn\n\t\t}\n\t}\n\t{\n\t\t// check if it is base64url\n\t\tcontent = strings.Trim(content, \"=\")\n\t\tdecoded, err := base64.RawURLEncoding.DecodeString(content)\n\t\tif err == nil {\n\t\t\ta.Values[prefix+\"_!kind\"] = \"base64url\"\n\t\t\ta.Values[prefix+\"_!rawContent\"] = string(decoded)\n\t\t\ta.extractValue(string(decoded), prefix+\"_!base64\")\n\t\t\treturn\n\t\t}\n\t}\n\t{\n\t\t// check if it is json\n\t\tvar doc jsonDocument\n\t\tif err := json.Unmarshal([]byte(content), &doc); err == nil {\n\t\t\ta.Values[prefix+\"_!kind\"] = \"json\"\n\t\t\ta.extractJSON(&doc, prefix)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (a *AbstractNonNativeLink) extractLink(content *url.URL, prefix string) {\n\ta.Values[prefix+\"_!link\"] = content.String()\n\ta.Values[prefix+\"_!link_protocol\"] = content.Scheme\n\ta.Values[prefix+\"_!link_host\"] = content.Host\n\ta.extractValue(content.Host, prefix+\"_!link_host\")\n\ta.Values[prefix+\"_!link_path\"] = content.Path\n\ta.Values[prefix+\"_!link_query\"] = content.RawQuery\n\ta.Values[prefix+\"_!link_fragment\"] = content.Fragment\n\ta.Values[prefix+\"_!link_userinfo\"] = content.User.String()\n\ta.extractValue(content.User.String(), prefix+\"_!link_userinfo_!value\")\n\ta.Values[prefix+\"_!link_opaque\"] = content.Opaque\n}\n\nfunc (a *AbstractNonNativeLink) extractJSON(content *jsonDocument, prefix string) {\n\tfor key, value := range *content {\n\t\tswitch value[0] {\n\t\tcase '{':\n\t\t\ta.extractValue(string(value), prefix+\"_!json_\"+key)\n\t\tcase '\"':\n\t\t\tvar unquoted string\n\t\t\tif err := json.Unmarshal(value, &unquoted); err == nil {\n\t\t\t\ta.Values[prefix+\"_!json_\"+key+\"_!unquoted\"] = unquoted\n\t\t\t}\n\t\t\tfallthrough\n\t\tdefault:\n\t\t\ta.Values[prefix+\"_!json_\"+key] = string(value)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/subscription/entries/nonnative/nonnativeifce/nonnativeifce.go",
    "content": "package nonnativeifce\n\nimport (\n\t\"io/fs\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries\"\n)\n\ntype NonNativeConverterConstructorT func(fs fs.FS) (entries.Converter, error)\n\nvar NewNonNativeConverterConstructor NonNativeConverterConstructorT\n"
  },
  {
    "path": "app/subscription/entries/outbound/errors.generated.go",
    "content": "package outbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/entries/outbound/outbound.go",
    "content": "package outbound\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\n// NewOutboundEntriesParser internal api\nfunc NewOutboundEntriesParser() entries.Converter {\n\treturn newOutboundEntriesParser()\n}\n\nfunc newOutboundEntriesParser() entries.Converter {\n\treturn &outboundEntriesParser{}\n}\n\ntype outboundEntriesParser struct{}\n\nfunc (o *outboundEntriesParser) ConvertToAbstractServerConfig(rawConfig []byte, kindHint string) (*specs.SubscriptionServerConfig, error) {\n\tparser := specs.NewOutboundParser()\n\toutbound, err := parser.ParseOutboundConfig(rawConfig)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse outbound config\").Base(err).AtWarning()\n\t}\n\treturn parser.ToSubscriptionServerConfig(outbound)\n}\n\nfunc init() {\n\tcommon.Must(entries.RegisterConverter(\"outbound\", newOutboundEntriesParser()))\n}\n"
  },
  {
    "path": "app/subscription/entries/register.go",
    "content": "package entries\n\nimport \"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n\ntype ConverterRegistry struct {\n\tknownConverters map[string]Converter\n\tparent          *ConverterRegistry\n}\n\nvar globalConverterRegistry = &ConverterRegistry{knownConverters: map[string]Converter{}}\n\nfunc RegisterConverter(kind string, converter Converter) error {\n\treturn globalConverterRegistry.RegisterConverter(kind, converter)\n}\n\nfunc GetOverlayConverterRegistry() *ConverterRegistry {\n\treturn globalConverterRegistry.GetOverlayConverterRegistry()\n}\n\nfunc (c *ConverterRegistry) RegisterConverter(kind string, converter Converter) error {\n\tif _, found := c.knownConverters[kind]; found {\n\t\treturn newError(\"converter already registered for kind \", kind)\n\t}\n\tc.knownConverters[kind] = converter\n\treturn nil\n}\n\nfunc (c *ConverterRegistry) TryAllConverters(rawConfig []byte, prioritizedConverter, kindHint string) (*specs.SubscriptionServerConfig, error) {\n\tif prioritizedConverter != \"\" {\n\t\tif converter, found := c.knownConverters[prioritizedConverter]; found {\n\t\t\tserverConfig, err := converter.ConvertToAbstractServerConfig(rawConfig, kindHint)\n\t\t\tif err == nil {\n\t\t\t\treturn serverConfig, nil\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, converter := range c.knownConverters {\n\t\tserverConfig, err := converter.ConvertToAbstractServerConfig(rawConfig, kindHint)\n\t\tif err == nil {\n\t\t\treturn serverConfig, nil\n\t\t}\n\t}\n\tif c.parent != nil {\n\t\tif serverConfig, err := c.parent.TryAllConverters(rawConfig, prioritizedConverter, kindHint); err == nil {\n\t\t\treturn serverConfig, nil\n\t\t}\n\t}\n\treturn nil, newError(\"no converter found for config\")\n}\n\nfunc (c *ConverterRegistry) GetOverlayConverterRegistry() *ConverterRegistry {\n\treturn &ConverterRegistry{knownConverters: map[string]Converter{}, parent: c}\n}\n"
  },
  {
    "path": "app/subscription/errors.generated.go",
    "content": "package subscription\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/specs/abstract_spec.pb.go",
    "content": "package specs\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\tunsafe \"unsafe\"\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 ServerConfiguration struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tProtocol          string                 `protobuf:\"bytes,1,opt,name=protocol,proto3\" json:\"protocol,omitempty\"`\n\tProtocolSettings  *anypb.Any             `protobuf:\"bytes,2,opt,name=protocol_settings,json=protocolSettings,proto3\" json:\"protocol_settings,omitempty\"`\n\tTransport         string                 `protobuf:\"bytes,3,opt,name=transport,proto3\" json:\"transport,omitempty\"`\n\tTransportSettings *anypb.Any             `protobuf:\"bytes,4,opt,name=transport_settings,json=transportSettings,proto3\" json:\"transport_settings,omitempty\"`\n\tSecurity          string                 `protobuf:\"bytes,5,opt,name=security,proto3\" json:\"security,omitempty\"`\n\tSecuritySettings  *anypb.Any             `protobuf:\"bytes,6,opt,name=security_settings,json=securitySettings,proto3\" json:\"security_settings,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *ServerConfiguration) Reset() {\n\t*x = ServerConfiguration{}\n\tmi := &file_app_subscription_specs_abstract_spec_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfiguration) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfiguration) ProtoMessage() {}\n\nfunc (x *ServerConfiguration) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_specs_abstract_spec_proto_msgTypes[0]\n\tif 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 ServerConfiguration.ProtoReflect.Descriptor instead.\nfunc (*ServerConfiguration) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_specs_abstract_spec_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ServerConfiguration) GetProtocol() string {\n\tif x != nil {\n\t\treturn x.Protocol\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerConfiguration) GetProtocolSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.ProtocolSettings\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfiguration) GetTransport() string {\n\tif x != nil {\n\t\treturn x.Transport\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerConfiguration) GetTransportSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.TransportSettings\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfiguration) GetSecurity() string {\n\tif x != nil {\n\t\treturn x.Security\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerConfiguration) GetSecuritySettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.SecuritySettings\n\t}\n\treturn nil\n}\n\ntype SubscriptionServerConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tId            string                 `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tMetadata      map[string]string      `protobuf:\"bytes,2,rep,name=metadata,proto3\" json:\"metadata,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tConfiguration *ServerConfiguration   `protobuf:\"bytes,3,opt,name=configuration,proto3\" json:\"configuration,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SubscriptionServerConfig) Reset() {\n\t*x = SubscriptionServerConfig{}\n\tmi := &file_app_subscription_specs_abstract_spec_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SubscriptionServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SubscriptionServerConfig) ProtoMessage() {}\n\nfunc (x *SubscriptionServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_specs_abstract_spec_proto_msgTypes[1]\n\tif 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 SubscriptionServerConfig.ProtoReflect.Descriptor instead.\nfunc (*SubscriptionServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_specs_abstract_spec_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SubscriptionServerConfig) GetId() string {\n\tif x != nil {\n\t\treturn x.Id\n\t}\n\treturn \"\"\n}\n\nfunc (x *SubscriptionServerConfig) GetMetadata() map[string]string {\n\tif x != nil {\n\t\treturn x.Metadata\n\t}\n\treturn nil\n}\n\nfunc (x *SubscriptionServerConfig) GetConfiguration() *ServerConfiguration {\n\tif x != nil {\n\t\treturn x.Configuration\n\t}\n\treturn nil\n}\n\ntype SubscriptionDocument struct {\n\tstate         protoimpl.MessageState      `protogen:\"open.v1\"`\n\tMetadata      map[string]string           `protobuf:\"bytes,2,rep,name=metadata,proto3\" json:\"metadata,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tServer        []*SubscriptionServerConfig `protobuf:\"bytes,3,rep,name=server,proto3\" json:\"server,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SubscriptionDocument) Reset() {\n\t*x = SubscriptionDocument{}\n\tmi := &file_app_subscription_specs_abstract_spec_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SubscriptionDocument) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SubscriptionDocument) ProtoMessage() {}\n\nfunc (x *SubscriptionDocument) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_specs_abstract_spec_proto_msgTypes[2]\n\tif 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 SubscriptionDocument.ProtoReflect.Descriptor instead.\nfunc (*SubscriptionDocument) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_specs_abstract_spec_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SubscriptionDocument) GetMetadata() map[string]string {\n\tif x != nil {\n\t\treturn x.Metadata\n\t}\n\treturn nil\n}\n\nfunc (x *SubscriptionDocument) GetServer() []*SubscriptionServerConfig {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\nvar File_app_subscription_specs_abstract_spec_proto protoreflect.FileDescriptor\n\nconst file_app_subscription_specs_abstract_spec_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"*app/subscription/specs/abstract_spec.proto\\x12!v2ray.core.app.subscription.specs\\x1a\\x19google/protobuf/any.proto\\\"\\xb6\\x02\\n\" +\n\t\"\\x13ServerConfiguration\\x12\\x1a\\n\" +\n\t\"\\bprotocol\\x18\\x01 \\x01(\\tR\\bprotocol\\x12A\\n\" +\n\t\"\\x11protocol_settings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x10protocolSettings\\x12\\x1c\\n\" +\n\t\"\\ttransport\\x18\\x03 \\x01(\\tR\\ttransport\\x12C\\n\" +\n\t\"\\x12transport_settings\\x18\\x04 \\x01(\\v2\\x14.google.protobuf.AnyR\\x11transportSettings\\x12\\x1a\\n\" +\n\t\"\\bsecurity\\x18\\x05 \\x01(\\tR\\bsecurity\\x12A\\n\" +\n\t\"\\x11security_settings\\x18\\x06 \\x01(\\v2\\x14.google.protobuf.AnyR\\x10securitySettings\\\"\\xac\\x02\\n\" +\n\t\"\\x18SubscriptionServerConfig\\x12\\x0e\\n\" +\n\t\"\\x02id\\x18\\x01 \\x01(\\tR\\x02id\\x12e\\n\" +\n\t\"\\bmetadata\\x18\\x02 \\x03(\\v2I.v2ray.core.app.subscription.specs.SubscriptionServerConfig.MetadataEntryR\\bmetadata\\x12\\\\\\n\" +\n\t\"\\rconfiguration\\x18\\x03 \\x01(\\v26.v2ray.core.app.subscription.specs.ServerConfigurationR\\rconfiguration\\x1a;\\n\" +\n\t\"\\rMetadataEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01\\\"\\x8b\\x02\\n\" +\n\t\"\\x14SubscriptionDocument\\x12a\\n\" +\n\t\"\\bmetadata\\x18\\x02 \\x03(\\v2E.v2ray.core.app.subscription.specs.SubscriptionDocument.MetadataEntryR\\bmetadata\\x12S\\n\" +\n\t\"\\x06server\\x18\\x03 \\x03(\\v2;.v2ray.core.app.subscription.specs.SubscriptionServerConfigR\\x06server\\x1a;\\n\" +\n\t\"\\rMetadataEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01B\\x84\\x01\\n\" +\n\t\"%com.v2ray.core.app.subscription.specsP\\x01Z5github.com/v2fly/v2ray-core/v5/app/subscription/specs\\xaa\\x02!V2Ray.Core.App.Subscription.Specsb\\x06proto3\"\n\nvar (\n\tfile_app_subscription_specs_abstract_spec_proto_rawDescOnce sync.Once\n\tfile_app_subscription_specs_abstract_spec_proto_rawDescData []byte\n)\n\nfunc file_app_subscription_specs_abstract_spec_proto_rawDescGZIP() []byte {\n\tfile_app_subscription_specs_abstract_spec_proto_rawDescOnce.Do(func() {\n\t\tfile_app_subscription_specs_abstract_spec_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_subscription_specs_abstract_spec_proto_rawDesc), len(file_app_subscription_specs_abstract_spec_proto_rawDesc)))\n\t})\n\treturn file_app_subscription_specs_abstract_spec_proto_rawDescData\n}\n\nvar file_app_subscription_specs_abstract_spec_proto_msgTypes = make([]protoimpl.MessageInfo, 5)\nvar file_app_subscription_specs_abstract_spec_proto_goTypes = []any{\n\t(*ServerConfiguration)(nil),      // 0: v2ray.core.app.subscription.specs.ServerConfiguration\n\t(*SubscriptionServerConfig)(nil), // 1: v2ray.core.app.subscription.specs.SubscriptionServerConfig\n\t(*SubscriptionDocument)(nil),     // 2: v2ray.core.app.subscription.specs.SubscriptionDocument\n\tnil,                              // 3: v2ray.core.app.subscription.specs.SubscriptionServerConfig.MetadataEntry\n\tnil,                              // 4: v2ray.core.app.subscription.specs.SubscriptionDocument.MetadataEntry\n\t(*anypb.Any)(nil),                // 5: google.protobuf.Any\n}\nvar file_app_subscription_specs_abstract_spec_proto_depIdxs = []int32{\n\t5, // 0: v2ray.core.app.subscription.specs.ServerConfiguration.protocol_settings:type_name -> google.protobuf.Any\n\t5, // 1: v2ray.core.app.subscription.specs.ServerConfiguration.transport_settings:type_name -> google.protobuf.Any\n\t5, // 2: v2ray.core.app.subscription.specs.ServerConfiguration.security_settings:type_name -> google.protobuf.Any\n\t3, // 3: v2ray.core.app.subscription.specs.SubscriptionServerConfig.metadata:type_name -> v2ray.core.app.subscription.specs.SubscriptionServerConfig.MetadataEntry\n\t0, // 4: v2ray.core.app.subscription.specs.SubscriptionServerConfig.configuration:type_name -> v2ray.core.app.subscription.specs.ServerConfiguration\n\t4, // 5: v2ray.core.app.subscription.specs.SubscriptionDocument.metadata:type_name -> v2ray.core.app.subscription.specs.SubscriptionDocument.MetadataEntry\n\t1, // 6: v2ray.core.app.subscription.specs.SubscriptionDocument.server:type_name -> v2ray.core.app.subscription.specs.SubscriptionServerConfig\n\t7, // [7:7] is the sub-list for method output_type\n\t7, // [7:7] is the sub-list for method input_type\n\t7, // [7:7] is the sub-list for extension type_name\n\t7, // [7:7] is the sub-list for extension extendee\n\t0, // [0:7] is the sub-list for field type_name\n}\n\nfunc init() { file_app_subscription_specs_abstract_spec_proto_init() }\nfunc file_app_subscription_specs_abstract_spec_proto_init() {\n\tif File_app_subscription_specs_abstract_spec_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: unsafe.Slice(unsafe.StringData(file_app_subscription_specs_abstract_spec_proto_rawDesc), len(file_app_subscription_specs_abstract_spec_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   5,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_subscription_specs_abstract_spec_proto_goTypes,\n\t\tDependencyIndexes: file_app_subscription_specs_abstract_spec_proto_depIdxs,\n\t\tMessageInfos:      file_app_subscription_specs_abstract_spec_proto_msgTypes,\n\t}.Build()\n\tFile_app_subscription_specs_abstract_spec_proto = out.File\n\tfile_app_subscription_specs_abstract_spec_proto_goTypes = nil\n\tfile_app_subscription_specs_abstract_spec_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/subscription/specs/abstract_spec.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.subscription.specs;\n\noption csharp_namespace = \"V2Ray.Core.App.Subscription.Specs\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/subscription/specs\";\noption java_package = \"com.v2ray.core.app.subscription.specs\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\n\nmessage ServerConfiguration{\n  string protocol = 1;\n  google.protobuf.Any protocol_settings = 2;\n  string transport = 3;\n  google.protobuf.Any transport_settings = 4;\n  string security = 5;\n  google.protobuf.Any security_settings = 6;\n}\n\nmessage SubscriptionServerConfig{\n  string id = 1;\n  map<string, string> metadata = 2;\n  ServerConfiguration configuration = 3;\n}\n\nmessage SubscriptionDocument {\n  map<string, string> metadata = 2;\n  repeated SubscriptionServerConfig server = 3;\n}"
  },
  {
    "path": "app/subscription/specs/errors.generated.go",
    "content": "package specs\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/specs/outbound_parser.go",
    "content": "package specs\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/registry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc NewOutboundParser() *OutboundParser {\n\treturn &OutboundParser{}\n}\n\ntype OutboundParser struct{}\n\nfunc (p *OutboundParser) ParseOutboundConfig(rawConfig []byte) (*OutboundConfig, error) {\n\tskeleton := &OutboundConfig{}\n\tdecoder := json.NewDecoder(bytes.NewReader(rawConfig))\n\tdecoder.DisallowUnknownFields()\n\terr := decoder.Decode(skeleton)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse outbound config skeleton\").Base(err)\n\t}\n\treturn skeleton, nil\n}\n\nfunc (p *OutboundParser) toAbstractServerSpec(config *OutboundConfig) (*ServerConfiguration, error) {\n\tserverConfig := &ServerConfiguration{}\n\tserverConfig.Protocol = config.Protocol\n\t{\n\t\tprotocolSettings, err := loadHeterogeneousConfigFromRawJSONRestricted(\"outbound\", config.Protocol, config.Settings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse protocol settings\").Base(err)\n\t\t}\n\t\tserverConfig.ProtocolSettings = serial.ToTypedMessage(protocolSettings)\n\t}\n\n\tif config.StreamSetting != nil {\n\t\tif config.StreamSetting.Transport == \"\" {\n\t\t\tconfig.StreamSetting.Transport = \"tcp\"\n\t\t}\n\t\tif config.StreamSetting.Security == \"\" {\n\t\t\tconfig.StreamSetting.Security = \"none\"\n\t\t}\n\t\t{\n\t\t\tserverConfig.Transport = config.StreamSetting.Transport\n\t\t\ttransportSettings, err := loadHeterogeneousConfigFromRawJSONRestricted(\n\t\t\t\t\"transport\", config.StreamSetting.Transport, config.StreamSetting.TransportSettings)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse transport settings\").Base(err)\n\t\t\t}\n\t\t\tserverConfig.TransportSettings = serial.ToTypedMessage(transportSettings)\n\t\t}\n\t\tif config.StreamSetting.Security != \"none\" {\n\t\t\tsecuritySettings, err := loadHeterogeneousConfigFromRawJSONRestricted(\n\t\t\t\t\"security\", config.StreamSetting.Security, config.StreamSetting.SecuritySettings)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse security settings\").Base(err)\n\t\t\t}\n\n\t\t\tserverConfig.SecuritySettings = serial.ToTypedMessage(securitySettings)\n\t\t\tserverConfig.Security = serial.V2Type(serverConfig.SecuritySettings)\n\t\t}\n\t}\n\treturn serverConfig, nil\n}\n\nfunc (p *OutboundParser) ToSubscriptionServerConfig(config *OutboundConfig) (*SubscriptionServerConfig, error) {\n\tserverSpec, err := p.toAbstractServerSpec(config)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to parse server specification\").Base(err)\n\t}\n\treturn &SubscriptionServerConfig{\n\t\tConfiguration: serverSpec,\n\t\tMetadata:      config.Metadata,\n\t}, nil\n}\n\nfunc loadHeterogeneousConfigFromRawJSONRestricted(interfaceType, name string, rawJSON json.RawMessage) (proto.Message, error) {\n\tctx := context.TODO()\n\tctx = registry.CreateRestrictedModeContext(ctx)\n\tif len(rawJSON) == 0 {\n\t\trawJSON = []byte(\"{}\")\n\t}\n\treturn registry.LoadImplementationByAlias(ctx, interfaceType, name, []byte(rawJSON))\n}\n"
  },
  {
    "path": "app/subscription/specs/skeleton.go",
    "content": "package specs\n\nimport (\n\t\"encoding/json\"\n)\n\ntype OutboundConfig struct {\n\tProtocol      string            `json:\"protocol\"`\n\tSettings      json.RawMessage   `json:\"settings\"`\n\tStreamSetting *StreamConfig     `json:\"streamSettings\"`\n\tMetadata      map[string]string `json:\"metadata\"`\n}\n\ntype StreamConfig struct {\n\tTransport         string          `json:\"transport\"`\n\tTransportSettings json.RawMessage `json:\"transportSettings\"`\n\tSecurity          string          `json:\"security\"`\n\tSecuritySettings  json.RawMessage `json:\"securitySettings\"`\n}\n"
  },
  {
    "path": "app/subscription/specs/specs.go",
    "content": "package specs\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/subscription/subscription.go",
    "content": "package subscription\n\nimport \"github.com/v2fly/v2ray-core/v5/features\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype SubscriptionManager interface {\n\tfeatures.Feature\n\tAddTrackedSubscriptionFromImportSource(importSource *ImportSource) error\n\tRemoveTrackedSubscription(name string) error\n\tListTrackedSubscriptions() []string\n\tGetTrackedSubscriptionStatus(name string) (*TrackedSubscriptionStatus, error)\n\tUpdateTrackedSubscription(name string) error\n}\n\nfunc SubscriptionManagerType() interface{} {\n\treturn (*SubscriptionManager)(nil)\n}\n"
  },
  {
    "path": "app/subscription/subscription_rpc.pb.go",
    "content": "package subscription\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 SubscriptionServer struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tServerMetadata map[string]string      `protobuf:\"bytes,2,rep,name=serverMetadata,proto3\" json:\"serverMetadata,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tTag            string                 `protobuf:\"bytes,3,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *SubscriptionServer) Reset() {\n\t*x = SubscriptionServer{}\n\tmi := &file_app_subscription_subscription_rpc_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SubscriptionServer) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SubscriptionServer) ProtoMessage() {}\n\nfunc (x *SubscriptionServer) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscription_rpc_proto_msgTypes[0]\n\tif 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 SubscriptionServer.ProtoReflect.Descriptor instead.\nfunc (*SubscriptionServer) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscription_rpc_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *SubscriptionServer) GetServerMetadata() map[string]string {\n\tif x != nil {\n\t\treturn x.ServerMetadata\n\t}\n\treturn nil\n}\n\nfunc (x *SubscriptionServer) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\ntype TrackedSubscriptionStatus struct {\n\tstate            protoimpl.MessageState         `protogen:\"open.v1\"`\n\tServers          map[string]*SubscriptionServer `protobuf:\"bytes,1,rep,name=servers,proto3\" json:\"servers,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tDocumentMetadata map[string]string              `protobuf:\"bytes,2,rep,name=documentMetadata,proto3\" json:\"documentMetadata,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tImportSource     *ImportSource                  `protobuf:\"bytes,3,opt,name=importSource,proto3\" json:\"importSource,omitempty\"`\n\tAddedByApi       bool                           `protobuf:\"varint,4,opt,name=added_by_api,json=addedByApi,proto3\" json:\"added_by_api,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *TrackedSubscriptionStatus) Reset() {\n\t*x = TrackedSubscriptionStatus{}\n\tmi := &file_app_subscription_subscription_rpc_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TrackedSubscriptionStatus) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TrackedSubscriptionStatus) ProtoMessage() {}\n\nfunc (x *TrackedSubscriptionStatus) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscription_rpc_proto_msgTypes[1]\n\tif 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 TrackedSubscriptionStatus.ProtoReflect.Descriptor instead.\nfunc (*TrackedSubscriptionStatus) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscription_rpc_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *TrackedSubscriptionStatus) GetServers() map[string]*SubscriptionServer {\n\tif x != nil {\n\t\treturn x.Servers\n\t}\n\treturn nil\n}\n\nfunc (x *TrackedSubscriptionStatus) GetDocumentMetadata() map[string]string {\n\tif x != nil {\n\t\treturn x.DocumentMetadata\n\t}\n\treturn nil\n}\n\nfunc (x *TrackedSubscriptionStatus) GetImportSource() *ImportSource {\n\tif x != nil {\n\t\treturn x.ImportSource\n\t}\n\treturn nil\n}\n\nfunc (x *TrackedSubscriptionStatus) GetAddedByApi() bool {\n\tif x != nil {\n\t\treturn x.AddedByApi\n\t}\n\treturn false\n}\n\nvar File_app_subscription_subscription_rpc_proto protoreflect.FileDescriptor\n\nconst file_app_subscription_subscription_rpc_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"'app/subscription/subscription_rpc.proto\\x12\\x1bv2ray.core.app.subscription\\x1a\\x1dapp/subscription/config.proto\\\"\\xd6\\x01\\n\" +\n\t\"\\x12SubscriptionServer\\x12k\\n\" +\n\t\"\\x0eserverMetadata\\x18\\x02 \\x03(\\v2C.v2ray.core.app.subscription.SubscriptionServer.ServerMetadataEntryR\\x0eserverMetadata\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x03 \\x01(\\tR\\x03tag\\x1aA\\n\" +\n\t\"\\x13ServerMetadataEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01\\\"\\x97\\x04\\n\" +\n\t\"\\x19TrackedSubscriptionStatus\\x12]\\n\" +\n\t\"\\aservers\\x18\\x01 \\x03(\\v2C.v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntryR\\aservers\\x12x\\n\" +\n\t\"\\x10documentMetadata\\x18\\x02 \\x03(\\v2L.v2ray.core.app.subscription.TrackedSubscriptionStatus.DocumentMetadataEntryR\\x10documentMetadata\\x12M\\n\" +\n\t\"\\fimportSource\\x18\\x03 \\x01(\\v2).v2ray.core.app.subscription.ImportSourceR\\fimportSource\\x12 \\n\" +\n\t\"\\fadded_by_api\\x18\\x04 \\x01(\\bR\\n\" +\n\t\"addedByApi\\x1ak\\n\" +\n\t\"\\fServersEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12E\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\v2/.v2ray.core.app.subscription.SubscriptionServerR\\x05value:\\x028\\x01\\x1aC\\n\" +\n\t\"\\x15DocumentMetadataEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01Br\\n\" +\n\t\"\\x1fcom.v2ray.core.app.subscriptionP\\x01Z/github.com/v2fly/v2ray-core/v5/app/subscription\\xaa\\x02\\x1bV2Ray.Core.App.Subscriptionb\\x06proto3\"\n\nvar (\n\tfile_app_subscription_subscription_rpc_proto_rawDescOnce sync.Once\n\tfile_app_subscription_subscription_rpc_proto_rawDescData []byte\n)\n\nfunc file_app_subscription_subscription_rpc_proto_rawDescGZIP() []byte {\n\tfile_app_subscription_subscription_rpc_proto_rawDescOnce.Do(func() {\n\t\tfile_app_subscription_subscription_rpc_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_subscription_subscription_rpc_proto_rawDesc), len(file_app_subscription_subscription_rpc_proto_rawDesc)))\n\t})\n\treturn file_app_subscription_subscription_rpc_proto_rawDescData\n}\n\nvar file_app_subscription_subscription_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 5)\nvar file_app_subscription_subscription_rpc_proto_goTypes = []any{\n\t(*SubscriptionServer)(nil),        // 0: v2ray.core.app.subscription.SubscriptionServer\n\t(*TrackedSubscriptionStatus)(nil), // 1: v2ray.core.app.subscription.TrackedSubscriptionStatus\n\tnil,                               // 2: v2ray.core.app.subscription.SubscriptionServer.ServerMetadataEntry\n\tnil,                               // 3: v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntry\n\tnil,                               // 4: v2ray.core.app.subscription.TrackedSubscriptionStatus.DocumentMetadataEntry\n\t(*ImportSource)(nil),              // 5: v2ray.core.app.subscription.ImportSource\n}\nvar file_app_subscription_subscription_rpc_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.app.subscription.SubscriptionServer.serverMetadata:type_name -> v2ray.core.app.subscription.SubscriptionServer.ServerMetadataEntry\n\t3, // 1: v2ray.core.app.subscription.TrackedSubscriptionStatus.servers:type_name -> v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntry\n\t4, // 2: v2ray.core.app.subscription.TrackedSubscriptionStatus.documentMetadata:type_name -> v2ray.core.app.subscription.TrackedSubscriptionStatus.DocumentMetadataEntry\n\t5, // 3: v2ray.core.app.subscription.TrackedSubscriptionStatus.importSource:type_name -> v2ray.core.app.subscription.ImportSource\n\t0, // 4: v2ray.core.app.subscription.TrackedSubscriptionStatus.ServersEntry.value:type_name -> v2ray.core.app.subscription.SubscriptionServer\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_app_subscription_subscription_rpc_proto_init() }\nfunc file_app_subscription_subscription_rpc_proto_init() {\n\tif File_app_subscription_subscription_rpc_proto != nil {\n\t\treturn\n\t}\n\tfile_app_subscription_config_proto_init()\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: unsafe.Slice(unsafe.StringData(file_app_subscription_subscription_rpc_proto_rawDesc), len(file_app_subscription_subscription_rpc_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   5,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_subscription_subscription_rpc_proto_goTypes,\n\t\tDependencyIndexes: file_app_subscription_subscription_rpc_proto_depIdxs,\n\t\tMessageInfos:      file_app_subscription_subscription_rpc_proto_msgTypes,\n\t}.Build()\n\tFile_app_subscription_subscription_rpc_proto = out.File\n\tfile_app_subscription_subscription_rpc_proto_goTypes = nil\n\tfile_app_subscription_subscription_rpc_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/subscription/subscription_rpc.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.subscription;\n\noption csharp_namespace = \"V2Ray.Core.App.Subscription\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/subscription\";\noption java_package = \"com.v2ray.core.app.subscription\";\noption java_multiple_files = true;\n\nimport \"app/subscription/config.proto\";\n\nmessage SubscriptionServer {\n  map<string, string> serverMetadata = 2;\n  string tag = 3;\n}\n\nmessage TrackedSubscriptionStatus {\n  map<string, SubscriptionServer> servers = 1;\n  map<string, string> documentMetadata = 2;\n  v2ray.core.app.subscription.ImportSource importSource = 3;\n\n  bool added_by_api = 4;\n}"
  },
  {
    "path": "app/subscription/subscriptionmanager/command/command.go",
    "content": "package command\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\n\t\"google.golang.org/grpc\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype SubscriptionManagerService struct {\n\tUnimplementedSubscriptionManagerServiceServer\n\tmanager subscription.SubscriptionManager\n}\n\nfunc (s *SubscriptionManagerService) UpdateTrackedSubscription(ctx context.Context, request *UpdateTrackedSubscriptionRequest) (*UpdateTrackedSubscriptionResponse, error) {\n\tif s.manager == nil {\n\t\treturn nil, newError(\"subscription manager is not available\")\n\t}\n\terr := s.manager.UpdateTrackedSubscription(request.Name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &UpdateTrackedSubscriptionResponse{}, nil\n}\n\nfunc NewSubscriptionManagerService(manager subscription.SubscriptionManager) *SubscriptionManagerService {\n\treturn &SubscriptionManagerService{manager: manager}\n}\n\nfunc (s *SubscriptionManagerService) ListTrackedSubscription(ctx context.Context, req *ListTrackedSubscriptionRequest) (*ListTrackedSubscriptionResponse, error) {\n\tif s.manager == nil {\n\t\treturn nil, newError(\"subscription manager is not available\")\n\t}\n\tnames := s.manager.ListTrackedSubscriptions()\n\treturn &ListTrackedSubscriptionResponse{Names: names}, nil\n}\n\nfunc (s *SubscriptionManagerService) AddTrackedSubscription(ctx context.Context, req *AddTrackedSubscriptionRequest) (*AddTrackedSubscriptionResponse, error) {\n\tif s.manager == nil {\n\t\treturn nil, newError(\"subscription manager is not available\")\n\t}\n\terr := s.manager.AddTrackedSubscriptionFromImportSource(req.Source)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &AddTrackedSubscriptionResponse{}, nil\n}\n\nfunc (s *SubscriptionManagerService) RemoveTrackedSubscription(ctx context.Context, req *RemoveTrackedSubscriptionRequest) (*RemoveTrackedSubscriptionResponse, error) {\n\tif s.manager == nil {\n\t\treturn nil, newError(\"subscription manager is not available\")\n\t}\n\terr := s.manager.RemoveTrackedSubscription(req.Name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &RemoveTrackedSubscriptionResponse{}, nil\n}\n\nfunc (s *SubscriptionManagerService) GetTrackedSubscriptionStatus(ctx context.Context, req *GetTrackedSubscriptionStatusRequest) (*GetTrackedSubscriptionStatusResponse, error) {\n\tif s.manager == nil {\n\t\treturn nil, newError(\"subscription manager is not available\")\n\t}\n\tstatus, err := s.manager.GetTrackedSubscriptionStatus(req.Name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &GetTrackedSubscriptionStatusResponse{Status: status}, nil\n}\n\nfunc (s *SubscriptionManagerService) Register(server *grpc.Server) {\n\tRegisterSubscriptionManagerServiceServer(server, s)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {\n\t\tvar manager subscription.SubscriptionManager\n\t\tcommon.Must(core.RequireFeatures(ctx, func(m subscription.SubscriptionManager) {\n\t\t\tmanager = m\n\t\t}))\n\t\tservice := NewSubscriptionManagerService(manager)\n\t\treturn service, nil\n\t}))\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/command/command.pb.go",
    "content": "package command\n\nimport (\n\tsubscription \"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ListTrackedSubscriptionRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ListTrackedSubscriptionRequest) Reset() {\n\t*x = ListTrackedSubscriptionRequest{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ListTrackedSubscriptionRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListTrackedSubscriptionRequest) ProtoMessage() {}\n\nfunc (x *ListTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[0]\n\tif 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 ListTrackedSubscriptionRequest.ProtoReflect.Descriptor instead.\nfunc (*ListTrackedSubscriptionRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{0}\n}\n\ntype ListTrackedSubscriptionResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tNames         []string               `protobuf:\"bytes,1,rep,name=names,proto3\" json:\"names,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ListTrackedSubscriptionResponse) Reset() {\n\t*x = ListTrackedSubscriptionResponse{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ListTrackedSubscriptionResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListTrackedSubscriptionResponse) ProtoMessage() {}\n\nfunc (x *ListTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[1]\n\tif 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 ListTrackedSubscriptionResponse.ProtoReflect.Descriptor instead.\nfunc (*ListTrackedSubscriptionResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ListTrackedSubscriptionResponse) GetNames() []string {\n\tif x != nil {\n\t\treturn x.Names\n\t}\n\treturn nil\n}\n\ntype AddTrackedSubscriptionRequest struct {\n\tstate         protoimpl.MessageState     `protogen:\"open.v1\"`\n\tSource        *subscription.ImportSource `protobuf:\"bytes,1,opt,name=source,proto3\" json:\"source,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddTrackedSubscriptionRequest) Reset() {\n\t*x = AddTrackedSubscriptionRequest{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddTrackedSubscriptionRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddTrackedSubscriptionRequest) ProtoMessage() {}\n\nfunc (x *AddTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[2]\n\tif 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 AddTrackedSubscriptionRequest.ProtoReflect.Descriptor instead.\nfunc (*AddTrackedSubscriptionRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *AddTrackedSubscriptionRequest) GetSource() *subscription.ImportSource {\n\tif x != nil {\n\t\treturn x.Source\n\t}\n\treturn nil\n}\n\ntype AddTrackedSubscriptionResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *AddTrackedSubscriptionResponse) Reset() {\n\t*x = AddTrackedSubscriptionResponse{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *AddTrackedSubscriptionResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AddTrackedSubscriptionResponse) ProtoMessage() {}\n\nfunc (x *AddTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[3]\n\tif 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 AddTrackedSubscriptionResponse.ProtoReflect.Descriptor instead.\nfunc (*AddTrackedSubscriptionResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{3}\n}\n\ntype RemoveTrackedSubscriptionRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveTrackedSubscriptionRequest) Reset() {\n\t*x = RemoveTrackedSubscriptionRequest{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveTrackedSubscriptionRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveTrackedSubscriptionRequest) ProtoMessage() {}\n\nfunc (x *RemoveTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[4]\n\tif 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 RemoveTrackedSubscriptionRequest.ProtoReflect.Descriptor instead.\nfunc (*RemoveTrackedSubscriptionRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *RemoveTrackedSubscriptionRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype RemoveTrackedSubscriptionResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RemoveTrackedSubscriptionResponse) Reset() {\n\t*x = RemoveTrackedSubscriptionResponse{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RemoveTrackedSubscriptionResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RemoveTrackedSubscriptionResponse) ProtoMessage() {}\n\nfunc (x *RemoveTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[5]\n\tif 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 RemoveTrackedSubscriptionResponse.ProtoReflect.Descriptor instead.\nfunc (*RemoveTrackedSubscriptionResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{5}\n}\n\ntype UpdateTrackedSubscriptionRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *UpdateTrackedSubscriptionRequest) Reset() {\n\t*x = UpdateTrackedSubscriptionRequest{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *UpdateTrackedSubscriptionRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*UpdateTrackedSubscriptionRequest) ProtoMessage() {}\n\nfunc (x *UpdateTrackedSubscriptionRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[6]\n\tif 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 UpdateTrackedSubscriptionRequest.ProtoReflect.Descriptor instead.\nfunc (*UpdateTrackedSubscriptionRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *UpdateTrackedSubscriptionRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype UpdateTrackedSubscriptionResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *UpdateTrackedSubscriptionResponse) Reset() {\n\t*x = UpdateTrackedSubscriptionResponse{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *UpdateTrackedSubscriptionResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*UpdateTrackedSubscriptionResponse) ProtoMessage() {}\n\nfunc (x *UpdateTrackedSubscriptionResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[7]\n\tif 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 UpdateTrackedSubscriptionResponse.ProtoReflect.Descriptor instead.\nfunc (*UpdateTrackedSubscriptionResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{7}\n}\n\ntype GetTrackedSubscriptionStatusRequest struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetTrackedSubscriptionStatusRequest) Reset() {\n\t*x = GetTrackedSubscriptionStatusRequest{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetTrackedSubscriptionStatusRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetTrackedSubscriptionStatusRequest) ProtoMessage() {}\n\nfunc (x *GetTrackedSubscriptionStatusRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[8]\n\tif 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 GetTrackedSubscriptionStatusRequest.ProtoReflect.Descriptor instead.\nfunc (*GetTrackedSubscriptionStatusRequest) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *GetTrackedSubscriptionStatusRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype GetTrackedSubscriptionStatusResponse struct {\n\tstate         protoimpl.MessageState                  `protogen:\"open.v1\"`\n\tStatus        *subscription.TrackedSubscriptionStatus `protobuf:\"bytes,1,opt,name=status,proto3\" json:\"status,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *GetTrackedSubscriptionStatusResponse) Reset() {\n\t*x = GetTrackedSubscriptionStatusResponse{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[9]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *GetTrackedSubscriptionStatusResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetTrackedSubscriptionStatusResponse) ProtoMessage() {}\n\nfunc (x *GetTrackedSubscriptionStatusResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[9]\n\tif 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 GetTrackedSubscriptionStatusResponse.ProtoReflect.Descriptor instead.\nfunc (*GetTrackedSubscriptionStatusResponse) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *GetTrackedSubscriptionStatusResponse) GetStatus() *subscription.TrackedSubscriptionStatus {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn nil\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[10]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_subscription_subscriptionmanager_command_command_proto_msgTypes[10]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP(), []int{10}\n}\n\nvar File_app_subscription_subscriptionmanager_command_command_proto protoreflect.FileDescriptor\n\nconst file_app_subscription_subscriptionmanager_command_command_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\":app/subscription/subscriptionmanager/command/command.proto\\x127v2ray.core.app.subscription.subscriptionmanager.command\\x1a common/protoext/extensions.proto\\x1a\\x1dapp/subscription/config.proto\\x1a'app/subscription/subscription_rpc.proto\\\" \\n\" +\n\t\"\\x1eListTrackedSubscriptionRequest\\\"7\\n\" +\n\t\"\\x1fListTrackedSubscriptionResponse\\x12\\x14\\n\" +\n\t\"\\x05names\\x18\\x01 \\x03(\\tR\\x05names\\\"b\\n\" +\n\t\"\\x1dAddTrackedSubscriptionRequest\\x12A\\n\" +\n\t\"\\x06source\\x18\\x01 \\x01(\\v2).v2ray.core.app.subscription.ImportSourceR\\x06source\\\" \\n\" +\n\t\"\\x1eAddTrackedSubscriptionResponse\\\"6\\n\" +\n\t\" RemoveTrackedSubscriptionRequest\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\\"#\\n\" +\n\t\"!RemoveTrackedSubscriptionResponse\\\"6\\n\" +\n\t\" UpdateTrackedSubscriptionRequest\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\\"#\\n\" +\n\t\"!UpdateTrackedSubscriptionResponse\\\"9\\n\" +\n\t\"#GetTrackedSubscriptionStatusRequest\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\\"v\\n\" +\n\t\"$GetTrackedSubscriptionStatusResponse\\x12N\\n\" +\n\t\"\\x06status\\x18\\x01 \\x01(\\v26.v2ray.core.app.subscription.TrackedSubscriptionStatusR\\x06status\\\"0\\n\" +\n\t\"\\x06Config:&\\x82\\xb5\\x18\\\"\\n\" +\n\t\"\\vgrpcservice\\x12\\x13subscriptionmanager2\\xc9\\b\\n\" +\n\t\"\\x1aSubscriptionManagerService\\x12\\xce\\x01\\n\" +\n\t\"\\x17ListTrackedSubscription\\x12W.v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionRequest\\x1aX.v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionResponse\\\"\\x00\\x12\\xcb\\x01\\n\" +\n\t\"\\x16AddTrackedSubscription\\x12V.v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest\\x1aW.v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionResponse\\\"\\x00\\x12\\xd4\\x01\\n\" +\n\t\"\\x19RemoveTrackedSubscription\\x12Y.v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionRequest\\x1aZ.v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionResponse\\\"\\x00\\x12\\xdd\\x01\\n\" +\n\t\"\\x1cGetTrackedSubscriptionStatus\\x12\\\\.v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusRequest\\x1a].v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse\\\"\\x00\\x12\\xd4\\x01\\n\" +\n\t\"\\x19UpdateTrackedSubscription\\x12Y.v2ray.core.app.subscription.subscriptionmanager.command.UpdateTrackedSubscriptionRequest\\x1aZ.v2ray.core.app.subscription.subscriptionmanager.command.UpdateTrackedSubscriptionResponse\\\"\\x00B\\xc2\\x01\\n\" +\n\t\"7com.v2ray.core.subscription.subscriptionmanager.commandP\\x01ZKgithub.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager/command\\xaa\\x027V2Ray.Core.App.Subscription.Subscriptionmanager.Commandb\\x06proto3\"\n\nvar (\n\tfile_app_subscription_subscriptionmanager_command_command_proto_rawDescOnce sync.Once\n\tfile_app_subscription_subscriptionmanager_command_command_proto_rawDescData []byte\n)\n\nfunc file_app_subscription_subscriptionmanager_command_command_proto_rawDescGZIP() []byte {\n\tfile_app_subscription_subscriptionmanager_command_command_proto_rawDescOnce.Do(func() {\n\t\tfile_app_subscription_subscriptionmanager_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_subscription_subscriptionmanager_command_command_proto_rawDesc), len(file_app_subscription_subscriptionmanager_command_command_proto_rawDesc)))\n\t})\n\treturn file_app_subscription_subscriptionmanager_command_command_proto_rawDescData\n}\n\nvar file_app_subscription_subscriptionmanager_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 11)\nvar file_app_subscription_subscriptionmanager_command_command_proto_goTypes = []any{\n\t(*ListTrackedSubscriptionRequest)(nil),       // 0: v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionRequest\n\t(*ListTrackedSubscriptionResponse)(nil),      // 1: v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionResponse\n\t(*AddTrackedSubscriptionRequest)(nil),        // 2: v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest\n\t(*AddTrackedSubscriptionResponse)(nil),       // 3: v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionResponse\n\t(*RemoveTrackedSubscriptionRequest)(nil),     // 4: v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionRequest\n\t(*RemoveTrackedSubscriptionResponse)(nil),    // 5: v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionResponse\n\t(*UpdateTrackedSubscriptionRequest)(nil),     // 6: v2ray.core.app.subscription.subscriptionmanager.command.UpdateTrackedSubscriptionRequest\n\t(*UpdateTrackedSubscriptionResponse)(nil),    // 7: v2ray.core.app.subscription.subscriptionmanager.command.UpdateTrackedSubscriptionResponse\n\t(*GetTrackedSubscriptionStatusRequest)(nil),  // 8: v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusRequest\n\t(*GetTrackedSubscriptionStatusResponse)(nil), // 9: v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse\n\t(*Config)(nil),                                 // 10: v2ray.core.app.subscription.subscriptionmanager.command.Config\n\t(*subscription.ImportSource)(nil),              // 11: v2ray.core.app.subscription.ImportSource\n\t(*subscription.TrackedSubscriptionStatus)(nil), // 12: v2ray.core.app.subscription.TrackedSubscriptionStatus\n}\nvar file_app_subscription_subscriptionmanager_command_command_proto_depIdxs = []int32{\n\t11, // 0: v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest.source:type_name -> v2ray.core.app.subscription.ImportSource\n\t12, // 1: v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse.status:type_name -> v2ray.core.app.subscription.TrackedSubscriptionStatus\n\t0,  // 2: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.ListTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionRequest\n\t2,  // 3: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.AddTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionRequest\n\t4,  // 4: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.RemoveTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionRequest\n\t8,  // 5: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.GetTrackedSubscriptionStatus:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusRequest\n\t6,  // 6: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.UpdateTrackedSubscription:input_type -> v2ray.core.app.subscription.subscriptionmanager.command.UpdateTrackedSubscriptionRequest\n\t1,  // 7: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.ListTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.ListTrackedSubscriptionResponse\n\t3,  // 8: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.AddTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.AddTrackedSubscriptionResponse\n\t5,  // 9: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.RemoveTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.RemoveTrackedSubscriptionResponse\n\t9,  // 10: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.GetTrackedSubscriptionStatus:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.GetTrackedSubscriptionStatusResponse\n\t7,  // 11: v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService.UpdateTrackedSubscription:output_type -> v2ray.core.app.subscription.subscriptionmanager.command.UpdateTrackedSubscriptionResponse\n\t7,  // [7:12] is the sub-list for method output_type\n\t2,  // [2:7] is the sub-list for method input_type\n\t2,  // [2:2] is the sub-list for extension type_name\n\t2,  // [2:2] is the sub-list for extension extendee\n\t0,  // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_app_subscription_subscriptionmanager_command_command_proto_init() }\nfunc file_app_subscription_subscriptionmanager_command_command_proto_init() {\n\tif File_app_subscription_subscriptionmanager_command_command_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: unsafe.Slice(unsafe.StringData(file_app_subscription_subscriptionmanager_command_command_proto_rawDesc), len(file_app_subscription_subscriptionmanager_command_command_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   11,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_app_subscription_subscriptionmanager_command_command_proto_goTypes,\n\t\tDependencyIndexes: file_app_subscription_subscriptionmanager_command_command_proto_depIdxs,\n\t\tMessageInfos:      file_app_subscription_subscriptionmanager_command_command_proto_msgTypes,\n\t}.Build()\n\tFile_app_subscription_subscriptionmanager_command_command_proto = out.File\n\tfile_app_subscription_subscriptionmanager_command_command_proto_goTypes = nil\n\tfile_app_subscription_subscriptionmanager_command_command_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/command/command.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.subscription.subscriptionmanager.command;\noption csharp_namespace = \"V2Ray.Core.App.Subscription.Subscriptionmanager.Command\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager/command\";\noption java_package = \"com.v2ray.core.subscription.subscriptionmanager.command\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"app/subscription/config.proto\";\nimport \"app/subscription/subscription_rpc.proto\";\n\nmessage ListTrackedSubscriptionRequest {\n}\n\nmessage ListTrackedSubscriptionResponse {\n  repeated string names = 1;\n}\n\nmessage AddTrackedSubscriptionRequest{\n  v2ray.core.app.subscription.ImportSource source = 1;\n}\nmessage AddTrackedSubscriptionResponse{\n\n}\n\nmessage RemoveTrackedSubscriptionRequest{\n  string name = 1;\n}\nmessage RemoveTrackedSubscriptionResponse{\n\n}\n\nmessage UpdateTrackedSubscriptionRequest{\n  string name = 1;\n}\nmessage UpdateTrackedSubscriptionResponse{\n\n}\n\nmessage GetTrackedSubscriptionStatusRequest {\n  string name = 1;\n}\n\nmessage GetTrackedSubscriptionStatusResponse {\n  v2ray.core.app.subscription.TrackedSubscriptionStatus status = 1;\n}\n\n\nservice SubscriptionManagerService {\n  rpc ListTrackedSubscription(ListTrackedSubscriptionRequest)\n      returns (ListTrackedSubscriptionResponse) {}\n  rpc AddTrackedSubscription(AddTrackedSubscriptionRequest)\n      returns (AddTrackedSubscriptionResponse) {}\n  rpc RemoveTrackedSubscription(RemoveTrackedSubscriptionRequest)\n      returns (RemoveTrackedSubscriptionResponse) {}\n  rpc GetTrackedSubscriptionStatus(GetTrackedSubscriptionStatusRequest)\n      returns (GetTrackedSubscriptionStatusResponse) {}\n  rpc UpdateTrackedSubscription(UpdateTrackedSubscriptionRequest)\n      returns (UpdateTrackedSubscriptionResponse) {}\n}\n\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"grpcservice\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"subscriptionmanager\";\n}"
  },
  {
    "path": "app/subscription/subscriptionmanager/command/command_grpc.pb.go",
    "content": "package command\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tSubscriptionManagerService_ListTrackedSubscription_FullMethodName      = \"/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/ListTrackedSubscription\"\n\tSubscriptionManagerService_AddTrackedSubscription_FullMethodName       = \"/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/AddTrackedSubscription\"\n\tSubscriptionManagerService_RemoveTrackedSubscription_FullMethodName    = \"/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/RemoveTrackedSubscription\"\n\tSubscriptionManagerService_GetTrackedSubscriptionStatus_FullMethodName = \"/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/GetTrackedSubscriptionStatus\"\n\tSubscriptionManagerService_UpdateTrackedSubscription_FullMethodName    = \"/v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService/UpdateTrackedSubscription\"\n)\n\n// SubscriptionManagerServiceClient is the client API for SubscriptionManagerService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype SubscriptionManagerServiceClient interface {\n\tListTrackedSubscription(ctx context.Context, in *ListTrackedSubscriptionRequest, opts ...grpc.CallOption) (*ListTrackedSubscriptionResponse, error)\n\tAddTrackedSubscription(ctx context.Context, in *AddTrackedSubscriptionRequest, opts ...grpc.CallOption) (*AddTrackedSubscriptionResponse, error)\n\tRemoveTrackedSubscription(ctx context.Context, in *RemoveTrackedSubscriptionRequest, opts ...grpc.CallOption) (*RemoveTrackedSubscriptionResponse, error)\n\tGetTrackedSubscriptionStatus(ctx context.Context, in *GetTrackedSubscriptionStatusRequest, opts ...grpc.CallOption) (*GetTrackedSubscriptionStatusResponse, error)\n\tUpdateTrackedSubscription(ctx context.Context, in *UpdateTrackedSubscriptionRequest, opts ...grpc.CallOption) (*UpdateTrackedSubscriptionResponse, error)\n}\n\ntype subscriptionManagerServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewSubscriptionManagerServiceClient(cc grpc.ClientConnInterface) SubscriptionManagerServiceClient {\n\treturn &subscriptionManagerServiceClient{cc}\n}\n\nfunc (c *subscriptionManagerServiceClient) ListTrackedSubscription(ctx context.Context, in *ListTrackedSubscriptionRequest, opts ...grpc.CallOption) (*ListTrackedSubscriptionResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(ListTrackedSubscriptionResponse)\n\terr := c.cc.Invoke(ctx, SubscriptionManagerService_ListTrackedSubscription_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *subscriptionManagerServiceClient) AddTrackedSubscription(ctx context.Context, in *AddTrackedSubscriptionRequest, opts ...grpc.CallOption) (*AddTrackedSubscriptionResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(AddTrackedSubscriptionResponse)\n\terr := c.cc.Invoke(ctx, SubscriptionManagerService_AddTrackedSubscription_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *subscriptionManagerServiceClient) RemoveTrackedSubscription(ctx context.Context, in *RemoveTrackedSubscriptionRequest, opts ...grpc.CallOption) (*RemoveTrackedSubscriptionResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(RemoveTrackedSubscriptionResponse)\n\terr := c.cc.Invoke(ctx, SubscriptionManagerService_RemoveTrackedSubscription_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *subscriptionManagerServiceClient) GetTrackedSubscriptionStatus(ctx context.Context, in *GetTrackedSubscriptionStatusRequest, opts ...grpc.CallOption) (*GetTrackedSubscriptionStatusResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(GetTrackedSubscriptionStatusResponse)\n\terr := c.cc.Invoke(ctx, SubscriptionManagerService_GetTrackedSubscriptionStatus_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *subscriptionManagerServiceClient) UpdateTrackedSubscription(ctx context.Context, in *UpdateTrackedSubscriptionRequest, opts ...grpc.CallOption) (*UpdateTrackedSubscriptionResponse, error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tout := new(UpdateTrackedSubscriptionResponse)\n\terr := c.cc.Invoke(ctx, SubscriptionManagerService_UpdateTrackedSubscription_FullMethodName, in, out, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// SubscriptionManagerServiceServer is the server API for SubscriptionManagerService service.\n// All implementations must embed UnimplementedSubscriptionManagerServiceServer\n// for forward compatibility.\ntype SubscriptionManagerServiceServer interface {\n\tListTrackedSubscription(context.Context, *ListTrackedSubscriptionRequest) (*ListTrackedSubscriptionResponse, error)\n\tAddTrackedSubscription(context.Context, *AddTrackedSubscriptionRequest) (*AddTrackedSubscriptionResponse, error)\n\tRemoveTrackedSubscription(context.Context, *RemoveTrackedSubscriptionRequest) (*RemoveTrackedSubscriptionResponse, error)\n\tGetTrackedSubscriptionStatus(context.Context, *GetTrackedSubscriptionStatusRequest) (*GetTrackedSubscriptionStatusResponse, error)\n\tUpdateTrackedSubscription(context.Context, *UpdateTrackedSubscriptionRequest) (*UpdateTrackedSubscriptionResponse, error)\n\tmustEmbedUnimplementedSubscriptionManagerServiceServer()\n}\n\n// UnimplementedSubscriptionManagerServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedSubscriptionManagerServiceServer struct{}\n\nfunc (UnimplementedSubscriptionManagerServiceServer) ListTrackedSubscription(context.Context, *ListTrackedSubscriptionRequest) (*ListTrackedSubscriptionResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method ListTrackedSubscription not implemented\")\n}\nfunc (UnimplementedSubscriptionManagerServiceServer) AddTrackedSubscription(context.Context, *AddTrackedSubscriptionRequest) (*AddTrackedSubscriptionResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method AddTrackedSubscription not implemented\")\n}\nfunc (UnimplementedSubscriptionManagerServiceServer) RemoveTrackedSubscription(context.Context, *RemoveTrackedSubscriptionRequest) (*RemoveTrackedSubscriptionResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method RemoveTrackedSubscription not implemented\")\n}\nfunc (UnimplementedSubscriptionManagerServiceServer) GetTrackedSubscriptionStatus(context.Context, *GetTrackedSubscriptionStatusRequest) (*GetTrackedSubscriptionStatusResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method GetTrackedSubscriptionStatus not implemented\")\n}\nfunc (UnimplementedSubscriptionManagerServiceServer) UpdateTrackedSubscription(context.Context, *UpdateTrackedSubscriptionRequest) (*UpdateTrackedSubscriptionResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method UpdateTrackedSubscription not implemented\")\n}\nfunc (UnimplementedSubscriptionManagerServiceServer) mustEmbedUnimplementedSubscriptionManagerServiceServer() {\n}\nfunc (UnimplementedSubscriptionManagerServiceServer) testEmbeddedByValue() {}\n\n// UnsafeSubscriptionManagerServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to SubscriptionManagerServiceServer will\n// result in compilation errors.\ntype UnsafeSubscriptionManagerServiceServer interface {\n\tmustEmbedUnimplementedSubscriptionManagerServiceServer()\n}\n\nfunc RegisterSubscriptionManagerServiceServer(s grpc.ServiceRegistrar, srv SubscriptionManagerServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedSubscriptionManagerServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&SubscriptionManagerService_ServiceDesc, srv)\n}\n\nfunc _SubscriptionManagerService_ListTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListTrackedSubscriptionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(SubscriptionManagerServiceServer).ListTrackedSubscription(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: SubscriptionManagerService_ListTrackedSubscription_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(SubscriptionManagerServiceServer).ListTrackedSubscription(ctx, req.(*ListTrackedSubscriptionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _SubscriptionManagerService_AddTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddTrackedSubscriptionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(SubscriptionManagerServiceServer).AddTrackedSubscription(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: SubscriptionManagerService_AddTrackedSubscription_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(SubscriptionManagerServiceServer).AddTrackedSubscription(ctx, req.(*AddTrackedSubscriptionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _SubscriptionManagerService_RemoveTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(RemoveTrackedSubscriptionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(SubscriptionManagerServiceServer).RemoveTrackedSubscription(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: SubscriptionManagerService_RemoveTrackedSubscription_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(SubscriptionManagerServiceServer).RemoveTrackedSubscription(ctx, req.(*RemoveTrackedSubscriptionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _SubscriptionManagerService_GetTrackedSubscriptionStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetTrackedSubscriptionStatusRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(SubscriptionManagerServiceServer).GetTrackedSubscriptionStatus(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: SubscriptionManagerService_GetTrackedSubscriptionStatus_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(SubscriptionManagerServiceServer).GetTrackedSubscriptionStatus(ctx, req.(*GetTrackedSubscriptionStatusRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _SubscriptionManagerService_UpdateTrackedSubscription_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(UpdateTrackedSubscriptionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(SubscriptionManagerServiceServer).UpdateTrackedSubscription(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: SubscriptionManagerService_UpdateTrackedSubscription_FullMethodName,\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(SubscriptionManagerServiceServer).UpdateTrackedSubscription(ctx, req.(*UpdateTrackedSubscriptionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// SubscriptionManagerService_ServiceDesc is the grpc.ServiceDesc for SubscriptionManagerService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar SubscriptionManagerService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.app.subscription.subscriptionmanager.command.SubscriptionManagerService\",\n\tHandlerType: (*SubscriptionManagerServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListTrackedSubscription\",\n\t\t\tHandler:    _SubscriptionManagerService_ListTrackedSubscription_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"AddTrackedSubscription\",\n\t\t\tHandler:    _SubscriptionManagerService_AddTrackedSubscription_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"RemoveTrackedSubscription\",\n\t\t\tHandler:    _SubscriptionManagerService_RemoveTrackedSubscription_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetTrackedSubscriptionStatus\",\n\t\t\tHandler:    _SubscriptionManagerService_GetTrackedSubscriptionStatus_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"UpdateTrackedSubscription\",\n\t\t\tHandler:    _SubscriptionManagerService_UpdateTrackedSubscription_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"app/subscription/subscriptionmanager/command/command.proto\",\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/command/errors.generated.go",
    "content": "package command\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/delta.go",
    "content": "package subscriptionmanager\n\ntype changedDocument struct {\n\tremoved   []string\n\tadded     []string\n\tmodified  []string\n\tunchanged []string\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/errors.generated.go",
    "content": "package subscriptionmanager\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/known_metadata.go",
    "content": "package subscriptionmanager\n\nconst (\n\tServerMetadataID                 = \"ID\"\n\tServerMetadataTagName            = \"TagName\"\n\tServerMetadataFullyQualifiedName = \"FullyQualifiedName\"\n)\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/manager.go",
    "content": "package subscriptionmanager\n\nimport (\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/persistentstorage\"\n\t\"github.com/v2fly/v2ray-core/v5/app/persistentstorage/protostorage\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries/nonnative/nonnativeifce\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype SubscriptionManagerImpl struct {\n\tsync.Mutex\n\tconfig *subscription.Config\n\tctx    context.Context\n\n\ts         *core.Instance\n\tconverter *entries.ConverterRegistry\n\n\ttrackedSubscriptions map[string]*trackedSubscription\n\n\trefreshTask *task.Periodic\n\n\tpersistentStorage               persistentstorage.ScopedPersistentStorage\n\tpersistImportStorage            persistentstorage.ScopedPersistentStorage\n\tpersistImportSourceProtoStorage protostorage.ProtoPersistentStorage\n}\n\nfunc (s *SubscriptionManagerImpl) Type() interface{} {\n\treturn subscription.SubscriptionManagerType()\n}\n\nfunc (s *SubscriptionManagerImpl) housekeeping() error {\n\tfor subscriptionName := range s.trackedSubscriptions {\n\t\ts.Lock()\n\t\tif err := s.checkupSubscription(subscriptionName); err != nil {\n\t\t\tnewError(\"failed to checkup subscription: \", err).AtWarning().WriteToLog()\n\t\t}\n\t\ts.Unlock()\n\t}\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) Start() error {\n\tif s.config.Persistence {\n\t\tappEnvironment := envctx.EnvironmentFromContext(s.ctx).(environment.AppEnvironment)\n\t\ts.persistentStorage = appEnvironment.PersistentStorage()\n\n\t\timportsStorage, err := s.persistentStorage.NarrowScope(s.ctx, []byte(\"imports\"))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get persistent storage for imports\").Base(err)\n\t\t}\n\t\ts.persistImportStorage = importsStorage\n\t\ts.persistImportSourceProtoStorage = importsStorage.(protostorage.ProtoPersistentStorage)\n\t\tif err = s.loadAllFromPersistentStorage(); err != nil {\n\t\t\tnewError(\"failed to load all from persistent storage: \", err).WriteToLog()\n\t\t}\n\t}\n\tgo func() {\n\t\tif err := s.refreshTask.Start(); err != nil {\n\t\t\treturn\n\t\t}\n\t}()\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) Close() error {\n\tif err := s.refreshTask.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) addTrackedSubscriptionFromImportSource(importSource *subscription.ImportSource,\n\taddedByAPI bool,\n) error {\n\tif s.config.Persistence && addedByAPI {\n\t\terr := s.persistImportSourceProtoStorage.PutProto(s.ctx, importSource.Name, importSource)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to persist import source: \", err)\n\t\t}\n\t}\n\n\ttracked, err := newTrackedSubscription(importSource)\n\tif err != nil {\n\t\treturn newError(\"failed to init subscription \", importSource.Name, \": \", err)\n\t}\n\ttracked.addedByAPI = addedByAPI\n\ts.trackedSubscriptions[importSource.Name] = tracked\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) removeTrackedSubscription(subscriptionName string) error {\n\tif s.config.Persistence {\n\t\terr := s.persistImportStorage.Put(s.ctx, []byte(subscriptionName), nil)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to delete import source: \", err)\n\t\t}\n\t}\n\tif _, ok := s.trackedSubscriptions[subscriptionName]; ok {\n\t\terr := s.applySubscriptionTo(subscriptionName, &specs.SubscriptionDocument{Server: make([]*specs.SubscriptionServerConfig, 0)})\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to apply empty subscription: \", err)\n\t\t}\n\t\tdelete(s.trackedSubscriptions, subscriptionName)\n\t}\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) init() error {\n\ts.refreshTask = &task.Periodic{\n\t\tInterval: time.Duration(60) * time.Second,\n\t\tExecute:  s.housekeeping,\n\t}\n\ts.trackedSubscriptions = make(map[string]*trackedSubscription)\n\ts.converter = entries.GetOverlayConverterRegistry()\n\tif s.config.NonnativeConverterOverlay != nil {\n\t\tzipReader, err := zip.NewReader(bytes.NewReader(s.config.NonnativeConverterOverlay), int64(len(s.config.NonnativeConverterOverlay)))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to read nonnative converter overlay: \", err)\n\t\t}\n\t\tconverter, err := nonnativeifce.NewNonNativeConverterConstructor(zipReader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to construct nonnative converter: \", err)\n\t\t}\n\t\tif err := s.converter.RegisterConverter(\"user_nonnative\", converter); err != nil {\n\t\t\treturn newError(\"failed to register user nonnative converter: \", err)\n\t\t}\n\t}\n\n\tfor _, v := range s.config.Imports {\n\t\tif err := s.addTrackedSubscriptionFromImportSource(v, false); err != nil {\n\t\t\treturn newError(\"failed to add tracked subscription: \", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) loadAllFromPersistentStorage() error {\n\tif !s.config.Persistence {\n\t\treturn nil\n\t}\n\tprotoImportSources, err := s.persistImportStorage.List(s.ctx, []byte(\"\"))\n\tif err != nil {\n\t\treturn newError(\"failed to list import sources: \", err)\n\t}\n\tfor _, protoImportSource := range protoImportSources {\n\t\tvar importSource subscription.ImportSource\n\t\terr := s.persistImportSourceProtoStorage.GetProto(s.ctx, string(protoImportSource), &importSource)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get import source: \", err)\n\t\t}\n\t\tif err := s.addTrackedSubscriptionFromImportSource(&importSource, false); err != nil {\n\t\t\treturn newError(\"failed to add tracked subscription: \", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc NewSubscriptionManager(ctx context.Context, config *subscription.Config) (*SubscriptionManagerImpl, error) {\n\tinstance := core.MustFromContext(ctx)\n\timpl := &SubscriptionManagerImpl{ctx: ctx, s: instance, config: config}\n\tif err := impl.init(); err != nil {\n\t\treturn nil, newError(\"failed to init subscription manager: \", err)\n\t}\n\treturn impl, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*subscription.Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewSubscriptionManager(ctx, config.(*subscription.Config))\n\t}))\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/manager_rpc.go",
    "content": "package subscriptionmanager\n\nimport \"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\nfunc (s *SubscriptionManagerImpl) AddTrackedSubscriptionFromImportSource(importSource *subscription.ImportSource) error {\n\ts.Lock()\n\tdefer s.Unlock()\n\treturn s.addTrackedSubscriptionFromImportSource(importSource, true)\n}\n\nfunc (s *SubscriptionManagerImpl) RemoveTrackedSubscription(name string) error {\n\ts.Lock()\n\tdefer s.Unlock()\n\treturn s.removeTrackedSubscription(name)\n}\n\nfunc (s *SubscriptionManagerImpl) UpdateTrackedSubscription(name string) error {\n\ts.Lock()\n\tdefer s.Unlock()\n\treturn s.updateSubscription(name)\n}\n\nfunc (s *SubscriptionManagerImpl) ListTrackedSubscriptions() []string {\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tvar names []string\n\tfor name := range s.trackedSubscriptions {\n\t\tnames = append(names, name)\n\t}\n\treturn names\n}\n\nfunc (s *SubscriptionManagerImpl) GetTrackedSubscriptionStatus(name string) (*subscription.TrackedSubscriptionStatus, error) {\n\ts.Lock()\n\tdefer s.Unlock()\n\tif trackedSubscriptionItem, ok := s.trackedSubscriptions[name]; ok {\n\t\tresult := &subscription.TrackedSubscriptionStatus{}\n\t\tif err := trackedSubscriptionItem.fillStatus(result); err != nil {\n\t\t\treturn nil, newError(\"failed to fill status\").Base(err)\n\t\t}\n\t\tresult.ImportSource = trackedSubscriptionItem.importSource\n\t\treturn result, nil\n\t} else {\n\t\treturn nil, newError(\"unable to locate\")\n\t}\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/serverspec_materialize.go",
    "content": "package subscriptionmanager\n\nimport (\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc (s *SubscriptionManagerImpl) materialize(subscriptionName, tagName string, serverSpec *specs.SubscriptionServerConfig) (*core.OutboundHandlerConfig, error) {\n\toutboundConf, err := s.getOutboundTemplateForSubscriptionName(subscriptionName)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get outbound template for subscription name: \", err)\n\t}\n\n\tsenderSettingsIfcd, err := serial.GetInstanceOf(outboundConf.SenderSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get sender settings: \", err)\n\t}\n\tsenderSettings := senderSettingsIfcd.(*proxyman.SenderConfig)\n\n\tif serverSpec.Configuration.Transport != \"\" {\n\t\tsenderSettings.StreamSettings.ProtocolName = serverSpec.Configuration.Transport\n\t\tsenderSettings.StreamSettings.TransportSettings = append(senderSettings.StreamSettings.TransportSettings,\n\t\t\t&internet.TransportConfig{ProtocolName: serverSpec.Configuration.Transport, Settings: serverSpec.Configuration.TransportSettings})\n\t}\n\n\tif serverSpec.Configuration.Security != \"\" {\n\t\tsenderSettings.StreamSettings.SecurityType = serverSpec.Configuration.Security\n\t\tsenderSettings.StreamSettings.SecuritySettings = append(senderSettings.StreamSettings.SecuritySettings,\n\t\t\tserverSpec.Configuration.SecuritySettings)\n\t}\n\n\toutboundConf.SenderSettings = serial.ToTypedMessage(senderSettings)\n\n\toutboundConf.ProxySettings = serverSpec.Configuration.ProtocolSettings\n\n\toutboundConf.Tag = tagName\n\n\treturn outboundConf, nil\n}\n\nfunc (s *SubscriptionManagerImpl) getOutboundTemplateForSubscriptionName(subscriptionName string) (*core.OutboundHandlerConfig, error) { //nolint: unparam\n\tsenderSetting := &proxyman.SenderConfig{\n\t\tDomainStrategy: proxyman.SenderConfig_AS_IS, StreamSettings: &internet.StreamConfig{},\n\t}\n\n\treturn &core.OutboundHandlerConfig{SenderSettings: serial.ToTypedMessage(senderSetting)}, nil\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/subdocapplier.go",
    "content": "package subscriptionmanager\n\nimport (\n\t\"fmt\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n)\n\nfunc (s *SubscriptionManagerImpl) applySubscriptionTo(name string, document *specs.SubscriptionDocument) error {\n\tvar trackedSub *trackedSubscription\n\tif trackedSubFound, found := s.trackedSubscriptions[name]; !found {\n\t\treturn newError(\"not found\")\n\t} else {\n\t\ttrackedSub = trackedSubFound\n\t}\n\n\tdelta, err := trackedSub.diff(document)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnameToServerConfig := make(map[string]*specs.SubscriptionServerConfig)\n\tfor _, server := range document.Server {\n\t\tnameToServerConfig[server.Id] = server\n\t}\n\n\tfor _, serverName := range delta.removed {\n\t\tif err := s.removeManagedServer(name, serverName); err != nil {\n\t\t\tnewError(\"failed to remove managed server: \", err).AtWarning().WriteToLog()\n\t\t\tcontinue\n\t\t}\n\t\ttrackedSub.recordRemovedServer(serverName)\n\t}\n\n\tfor _, serverName := range delta.modified {\n\t\tserverConfig := nameToServerConfig[serverName]\n\t\tif err := s.updateManagedServer(name, serverName, serverConfig); err != nil {\n\t\t\tnewError(\"failed to update managed server: \", err).AtWarning().WriteToLog()\n\t\t\tcontinue\n\t\t}\n\t\ttrackedSub.recordUpdatedServer(serverName, serverConfig.Metadata[ServerMetadataTagName], serverConfig)\n\t}\n\n\tfor _, serverName := range delta.added {\n\t\tserverConfig := nameToServerConfig[serverName]\n\t\tif err := s.addManagedServer(name, serverName, serverConfig); err != nil {\n\t\t\tnewError(\"failed to add managed server: \", err).AtWarning().WriteToLog()\n\t\t\tcontinue\n\t\t}\n\t\ttrackedSub.recordUpdatedServer(serverName, serverConfig.Metadata[ServerMetadataTagName], serverConfig)\n\t}\n\n\tnewError(\"finished applying subscription, \", name, \"; \", fmt.Sprintf(\n\t\t\"%v updated, %v added, %v removed, %v unchanged\",\n\t\tlen(delta.modified), len(delta.added), len(delta.removed), len(delta.unchanged))).AtInfo().WriteToLog()\n\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) removeManagedServer(subscriptionName, serverName string) error {\n\tvar trackedSub *trackedSubscription\n\tif trackedSubFound, found := s.trackedSubscriptions[subscriptionName]; !found {\n\t\treturn newError(\"not found\")\n\t} else {\n\t\ttrackedSub = trackedSubFound\n\t}\n\n\tvar trackedServer *materializedServer\n\tif trackedServerFound, err := trackedSub.getCurrentServer(serverName); err != nil {\n\t\treturn err\n\t} else {\n\t\ttrackedServer = trackedServerFound\n\t}\n\n\ttagName := fmt.Sprintf(\"%s_%s\", trackedSub.importSource.TagPrefix, trackedServer.tagPostfix)\n\n\tif err := core.RemoveOutboundHandler(s.s, tagName); err != nil {\n\t\treturn newError(\"failed to remove handler: \", err)\n\t}\n\ttrackedSub.recordRemovedServer(serverName)\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) addManagedServer(subscriptionName, serverName string,\n\tserverSpec *specs.SubscriptionServerConfig,\n) error {\n\tvar trackedSub *trackedSubscription\n\tif trackedSubFound, found := s.trackedSubscriptions[subscriptionName]; !found {\n\t\treturn newError(\"not found\")\n\t} else {\n\t\ttrackedSub = trackedSubFound\n\t}\n\ttagPostfix := serverSpec.Metadata[ServerMetadataTagName]\n\ttagName := fmt.Sprintf(\"%s_%s\", trackedSub.importSource.TagPrefix, tagPostfix)\n\n\tmaterialized, err := s.materialize(subscriptionName, tagName, serverSpec)\n\tif err != nil {\n\t\treturn newError(\"failed to materialize server: \", err)\n\t}\n\n\tif err := core.AddOutboundHandler(s.s, materialized); err != nil {\n\t\treturn newError(\"failed to add handler: \", err)\n\t}\n\n\ttrackedSub.recordUpdatedServer(serverName, tagPostfix, serverSpec)\n\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) updateManagedServer(subscriptionName, serverName string,\n\tserverSpec *specs.SubscriptionServerConfig,\n) error {\n\tif err := s.removeManagedServer(subscriptionName, serverName); err != nil {\n\t\treturn newError(\"failed to update managed server: \", err).AtWarning()\n\t}\n\tif err := s.addManagedServer(subscriptionName, serverName, serverSpec); err != nil {\n\t\treturn newError(\"failed to update managed server : \", err).AtWarning()\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/subdocchecker.go",
    "content": "package subscriptionmanager\n\nimport \"time\"\n\nfunc (s *SubscriptionManagerImpl) checkupSubscription(subscriptionName string) error {\n\tvar trackedSub *trackedSubscription\n\tif trackedSubFound, found := s.trackedSubscriptions[subscriptionName]; !found {\n\t\treturn newError(\"not found\")\n\t} else {\n\t\ttrackedSub = trackedSubFound\n\t}\n\n\tshouldUpdate := false\n\n\tif trackedSub.currentDocumentExpireTime.Before(time.Now()) {\n\t\tshouldUpdate = true\n\t}\n\n\tif shouldUpdate {\n\t\tif err := s.updateSubscription(subscriptionName); err != nil {\n\t\t\treturn newError(\"failed to update subscription: \", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/subdocupdater.go",
    "content": "package subscriptionmanager\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode\"\n\n\t\"golang.org/x/crypto/sha3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n)\n\nfunc (s *SubscriptionManagerImpl) updateSubscription(subscriptionName string) error {\n\tvar trackedSub *trackedSubscription\n\tif trackedSubFound, found := s.trackedSubscriptions[subscriptionName]; !found {\n\t\treturn newError(\"not found\")\n\t} else {\n\t\ttrackedSub = trackedSubFound\n\t}\n\timportSource := trackedSub.importSource\n\tdocFetcher, err := documentfetcher.GetFetcher(\"http\")\n\tif err != nil {\n\t\treturn newError(\"failed to get fetcher: \", err)\n\t}\n\tif strings.HasPrefix(importSource.Url, \"data:\") {\n\t\tdocFetcher, err = documentfetcher.GetFetcher(\"dataurl\")\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get fetcher: \", err)\n\t\t}\n\t}\n\n\tdownloadedDocument, err := docFetcher.DownloadDocument(s.ctx, importSource)\n\tif err != nil {\n\t\treturn newError(\"failed to download document: \", err)\n\t}\n\n\ttrackedSub.originalDocument = downloadedDocument\n\n\tcontainer, err := containers.TryAllParsers(trackedSub.originalDocument, \"\")\n\tif err != nil {\n\t\treturn newError(\"failed to parse document: \", err)\n\t}\n\n\ttrackedSub.originalContainer = container\n\n\tparsedDocument := &specs.SubscriptionDocument{}\n\tparsedDocument.Metadata = container.Metadata\n\n\ttrackedSub.originalServerConfig = make(map[string]*originalServerConfig)\n\n\tfor _, server := range trackedSub.originalContainer.ServerSpecs {\n\t\tdocumentHash := sha3.Sum256(server.Content)\n\t\tserverConfigHashName := fmt.Sprintf(\"%x\", documentHash)\n\t\tparsed, err := s.converter.TryAllConverters(server.Content, \"outbound\", server.KindHint)\n\t\tif err != nil {\n\t\t\ttrackedSub.originalServerConfig[\"!!!\"+serverConfigHashName] = &originalServerConfig{data: server.Content}\n\t\t\tcontinue\n\t\t}\n\t\ts.polyfillServerConfig(parsed, serverConfigHashName)\n\t\tparsedDocument.Server = append(parsedDocument.Server, parsed)\n\t\ttrackedSub.originalServerConfig[parsed.Id] = &originalServerConfig{data: server.Content}\n\t}\n\tnewError(\"new subscription document fetched and parsed from \", subscriptionName).AtInfo().WriteToLog()\n\tif err := s.applySubscriptionTo(subscriptionName, parsedDocument); err != nil {\n\t\treturn newError(\"failed to apply subscription: \", err)\n\t}\n\ttrackedSub.currentDocument = parsedDocument\n\ttrackedSub.currentDocumentExpireTime = time.Now().Add(time.Second * time.Duration(importSource.DefaultExpireSeconds))\n\treturn nil\n}\n\nfunc (s *SubscriptionManagerImpl) polyfillServerConfig(document *specs.SubscriptionServerConfig, hash string) {\n\tdocument.Id = hash\n\n\tif document.Metadata == nil {\n\t\tdocument.Metadata = make(map[string]string)\n\t}\n\n\tif id, ok := document.Metadata[ServerMetadataID]; !ok || id == \"\" {\n\t\tdocument.Metadata[ServerMetadataID] = document.Id\n\t} else {\n\t\tdocument.Id = document.Metadata[ServerMetadataID]\n\t}\n\n\tif fqn, ok := document.Metadata[ServerMetadataFullyQualifiedName]; !ok || fqn == \"\" {\n\t\tdocument.Metadata[ServerMetadataFullyQualifiedName] = hash\n\t}\n\n\tif tagName, ok := document.Metadata[ServerMetadataTagName]; !ok || tagName == \"\" {\n\t\tdocument.Metadata[ServerMetadataTagName] = document.Metadata[ServerMetadataID]\n\t}\n\tdocument.Metadata[ServerMetadataTagName] = s.restrictTagName(document.Metadata[ServerMetadataTagName])\n}\n\nfunc (s *SubscriptionManagerImpl) restrictTagName(tagName string) string {\n\tnewTagName := &strings.Builder{}\n\tsomethingRemoved := false\n\tfor _, c := range tagName {\n\t\tif (unicode.IsLetter(c) || unicode.IsNumber(c)) && c < 128 {\n\t\t\tnewTagName.WriteRune(c)\n\t\t} else {\n\t\t\tsomethingRemoved = true\n\t\t}\n\t}\n\tnewTagNameString := newTagName.String()\n\tif len(newTagNameString) > 24 {\n\t\tnewTagNameString = newTagNameString[:15]\n\t\tsomethingRemoved = true\n\t}\n\tif somethingRemoved {\n\t\thashedTagName := sha3.Sum256([]byte(tagName))\n\t\thashedTagNameString := fmt.Sprintf(\"%x\", hashedTagName)\n\t\tnewTagNameString = newTagNameString + \"_\" + hashedTagNameString[:8]\n\t}\n\treturn newTagNameString\n}\n"
  },
  {
    "path": "app/subscription/subscriptionmanager/tracked_subscription.go",
    "content": "package subscriptionmanager\n\nimport (\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/specs\"\n)\n\nfunc newTrackedSubscription(importSource *subscription.ImportSource) (*trackedSubscription, error) { //nolint: unparam\n\treturn &trackedSubscription{importSource: importSource, materialized: map[string]*materializedServer{}}, nil\n}\n\ntype trackedSubscription struct {\n\timportSource *subscription.ImportSource\n\n\tcurrentDocumentExpireTime time.Time\n\tcurrentDocument           *specs.SubscriptionDocument\n\n\tmaterialized map[string]*materializedServer\n\n\toriginalDocument     []byte\n\toriginalContainer    *containers.Container\n\toriginalServerConfig map[string]*originalServerConfig\n\n\taddedByAPI bool\n}\n\ntype originalServerConfig struct {\n\tdata []byte\n}\n\nfunc (s *trackedSubscription) diff(newDocument *specs.SubscriptionDocument) (changedDocument, error) { //nolint: unparam\n\tdelta := changedDocument{}\n\tseen := make(map[string]bool)\n\n\tfor _, server := range newDocument.Server {\n\t\tif currentMaterialized, found := s.materialized[server.Id]; found {\n\t\t\tif currentMaterialized.serverConfig.Metadata[ServerMetadataFullyQualifiedName] == server.Metadata[ServerMetadataFullyQualifiedName] {\n\t\t\t\tdelta.unchanged = append(delta.unchanged, server.Id)\n\t\t\t} else {\n\t\t\t\tdelta.modified = append(delta.modified, server.Id)\n\t\t\t}\n\t\t\tseen[server.Id] = true\n\t\t} else {\n\t\t\tdelta.added = append(delta.added, server.Id)\n\t\t}\n\t}\n\n\tfor name := range s.materialized {\n\t\tif _, ok := seen[name]; !ok {\n\t\t\tdelta.removed = append(delta.removed, name)\n\t\t}\n\t}\n\n\treturn delta, nil\n}\n\nfunc (s *trackedSubscription) recordRemovedServer(name string) {\n\tdelete(s.materialized, name)\n}\n\nfunc (s *trackedSubscription) recordUpdatedServer(name, tagPostfix string, serverConfig *specs.SubscriptionServerConfig) {\n\ts.materialized[name] = &materializedServer{tagPostfix: tagPostfix, serverConfig: serverConfig}\n}\n\nfunc (s *trackedSubscription) getCurrentServer(name string) (*materializedServer, error) {\n\tif materialized, found := s.materialized[name]; found {\n\t\treturn materialized, nil\n\t} else {\n\t\treturn nil, newError(\"not found\")\n\t}\n}\n\ntype materializedServer struct {\n\ttagPostfix string\n\n\tserverConfig *specs.SubscriptionServerConfig\n}\n\nfunc (s *trackedSubscription) fillStatus(status *subscription.TrackedSubscriptionStatus) error { //nolint: unparam\n\tstatus.ImportSource = s.importSource\n\tif s.currentDocument == nil {\n\t\treturn nil\n\t}\n\tstatus.DocumentMetadata = s.currentDocument.Metadata\n\tstatus.Servers = make(map[string]*subscription.SubscriptionServer)\n\tfor _, v := range s.currentDocument.Server {\n\t\tstatus.Servers[v.Id] = &subscription.SubscriptionServer{\n\t\t\tServerMetadata: v.Metadata,\n\t\t}\n\t\tif materializedInstance, ok := s.materialized[v.Id]; ok {\n\t\t\tstatus.Servers[v.Id].Tag = materializedInstance.tagPostfix\n\t\t}\n\t}\n\tstatus.AddedByApi = s.addedByAPI\n\treturn nil\n}\n"
  },
  {
    "path": "app/tun/config.pb.go",
    "content": "package tun\n\nimport (\n\tproxyman \"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\troutercommon \"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tinternet \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate                 protoimpl.MessageState    `protogen:\"open.v1\"`\n\tName                  string                    `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tMtu                   uint32                    `protobuf:\"varint,2,opt,name=mtu,proto3\" json:\"mtu,omitempty\"`\n\tUserLevel             uint32                    `protobuf:\"varint,3,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tPacketEncoding        packetaddr.PacketAddrType `protobuf:\"varint,4,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tTag                   string                    `protobuf:\"bytes,5,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tIps                   []*routercommon.CIDR      `protobuf:\"bytes,6,rep,name=ips,proto3\" json:\"ips,omitempty\"`\n\tRoutes                []*routercommon.CIDR      `protobuf:\"bytes,7,rep,name=routes,proto3\" json:\"routes,omitempty\"`\n\tEnablePromiscuousMode bool                      `protobuf:\"varint,8,opt,name=enable_promiscuous_mode,json=enablePromiscuousMode,proto3\" json:\"enable_promiscuous_mode,omitempty\"`\n\tEnableSpoofing        bool                      `protobuf:\"varint,9,opt,name=enable_spoofing,json=enableSpoofing,proto3\" json:\"enable_spoofing,omitempty\"`\n\tSocketSettings        *internet.SocketConfig    `protobuf:\"bytes,10,opt,name=socket_settings,json=socketSettings,proto3\" json:\"socket_settings,omitempty\"`\n\tSniffingSettings      *proxyman.SniffingConfig  `protobuf:\"bytes,11,opt,name=sniffing_settings,json=sniffingSettings,proto3\" json:\"sniffing_settings,omitempty\"`\n\tunknownFields         protoimpl.UnknownFields\n\tsizeCache             protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_app_tun_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_app_tun_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_app_tun_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetMtu() uint32 {\n\tif x != nil {\n\t\treturn x.Mtu\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\nfunc (x *Config) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetIps() []*routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.Ips\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetRoutes() []*routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.Routes\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetEnablePromiscuousMode() bool {\n\tif x != nil {\n\t\treturn x.EnablePromiscuousMode\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetEnableSpoofing() bool {\n\tif x != nil {\n\t\treturn x.EnableSpoofing\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetSocketSettings() *internet.SocketConfig {\n\tif x != nil {\n\t\treturn x.SocketSettings\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetSniffingSettings() *proxyman.SniffingConfig {\n\tif x != nil {\n\t\treturn x.SniffingSettings\n\t}\n\treturn nil\n}\n\nvar File_app_tun_config_proto protoreflect.FileDescriptor\n\nconst file_app_tun_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x14app/tun/config.proto\\x12\\x12v2ray.core.app.tun\\x1a\\x19app/proxyman/config.proto\\x1a$app/router/routercommon/common.proto\\x1a common/protoext/extensions.proto\\x1a\\\"common/net/packetaddr/config.proto\\x1a\\x1ftransport/internet/config.proto\\\"\\xd2\\x04\\n\" +\n\t\"\\x06Config\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x10\\n\" +\n\t\"\\x03mtu\\x18\\x02 \\x01(\\rR\\x03mtu\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x03 \\x01(\\rR\\tuserLevel\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\x04 \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x05 \\x01(\\tR\\x03tag\\x12:\\n\" +\n\t\"\\x03ips\\x18\\x06 \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRR\\x03ips\\x12@\\n\" +\n\t\"\\x06routes\\x18\\a \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRR\\x06routes\\x126\\n\" +\n\t\"\\x17enable_promiscuous_mode\\x18\\b \\x01(\\bR\\x15enablePromiscuousMode\\x12'\\n\" +\n\t\"\\x0fenable_spoofing\\x18\\t \\x01(\\bR\\x0eenableSpoofing\\x12T\\n\" +\n\t\"\\x0fsocket_settings\\x18\\n\" +\n\t\" \\x01(\\v2+.v2ray.core.transport.internet.SocketConfigR\\x0esocketSettings\\x12T\\n\" +\n\t\"\\x11sniffing_settings\\x18\\v \\x01(\\v2'.v2ray.core.app.proxyman.SniffingConfigR\\x10sniffingSettings:\\x12\\x82\\xb5\\x18\\x0e\\n\" +\n\t\"\\aservice\\x12\\x03tunBW\\n\" +\n\t\"\\x16com.v2ray.core.app.tunP\\x01Z&github.com/v2fly/v2ray-core/v5/app/tun\\xaa\\x02\\x12V2Ray.Core.App.Tunb\\x06proto3\"\n\nvar (\n\tfile_app_tun_config_proto_rawDescOnce sync.Once\n\tfile_app_tun_config_proto_rawDescData []byte\n)\n\nfunc file_app_tun_config_proto_rawDescGZIP() []byte {\n\tfile_app_tun_config_proto_rawDescOnce.Do(func() {\n\t\tfile_app_tun_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_tun_config_proto_rawDesc), len(file_app_tun_config_proto_rawDesc)))\n\t})\n\treturn file_app_tun_config_proto_rawDescData\n}\n\nvar file_app_tun_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_app_tun_config_proto_goTypes = []any{\n\t(*Config)(nil),                  // 0: v2ray.core.app.tun.Config\n\t(packetaddr.PacketAddrType)(0),  // 1: v2ray.core.net.packetaddr.PacketAddrType\n\t(*routercommon.CIDR)(nil),       // 2: v2ray.core.app.router.routercommon.CIDR\n\t(*internet.SocketConfig)(nil),   // 3: v2ray.core.transport.internet.SocketConfig\n\t(*proxyman.SniffingConfig)(nil), // 4: v2ray.core.app.proxyman.SniffingConfig\n}\nvar file_app_tun_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.app.tun.Config.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t2, // 1: v2ray.core.app.tun.Config.ips:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t2, // 2: v2ray.core.app.tun.Config.routes:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t3, // 3: v2ray.core.app.tun.Config.socket_settings:type_name -> v2ray.core.transport.internet.SocketConfig\n\t4, // 4: v2ray.core.app.tun.Config.sniffing_settings:type_name -> v2ray.core.app.proxyman.SniffingConfig\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_app_tun_config_proto_init() }\nfunc file_app_tun_config_proto_init() {\n\tif File_app_tun_config_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: unsafe.Slice(unsafe.StringData(file_app_tun_config_proto_rawDesc), len(file_app_tun_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_app_tun_config_proto_goTypes,\n\t\tDependencyIndexes: file_app_tun_config_proto_depIdxs,\n\t\tMessageInfos:      file_app_tun_config_proto_msgTypes,\n\t}.Build()\n\tFile_app_tun_config_proto = out.File\n\tfile_app_tun_config_proto_goTypes = nil\n\tfile_app_tun_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "app/tun/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.app.tun;\noption csharp_namespace = \"V2Ray.Core.App.Tun\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/app/tun\";\noption java_package = \"com.v2ray.core.app.tun\";\noption java_multiple_files = true;\n\nimport \"app/proxyman/config.proto\";\nimport \"app/router/routercommon/common.proto\";\nimport \"common/protoext/extensions.proto\";\nimport \"common/net/packetaddr/config.proto\";\nimport \"transport/internet/config.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"service\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"tun\";\n\n  string name = 1;\n  uint32 mtu = 2;\n  uint32 user_level = 3;\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 4;\n  string tag = 5;\n  repeated v2ray.core.app.router.routercommon.CIDR ips = 6;\n  repeated v2ray.core.app.router.routercommon.CIDR routes = 7;\n  bool enable_promiscuous_mode = 8;\n  bool enable_spoofing = 9;\n  v2ray.core.transport.internet.SocketConfig socket_settings = 10;\n  v2ray.core.app.proxyman.SniffingConfig sniffing_settings = 11;\n}"
  },
  {
    "path": "app/tun/device/device.go",
    "content": "package device\n\nimport \"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype Device interface {\n\tstack.LinkEndpoint\n}\n\ntype Options struct {\n\tName string\n\tMTU  uint32\n}\n\ntype DeviceConstructor func(Options) (Device, error)\n"
  },
  {
    "path": "app/tun/device/errors.generated.go",
    "content": "package device\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/tun/device/gvisor/errors.generated.go",
    "content": "package gvisor\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/tun/device/gvisor/gvisor.go",
    "content": "package gvisor\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/tun/device/gvisor/gvisor_linux.go",
    "content": "//go:build linux && ((linux && amd64) || (linux && arm64))\n// +build linux\n// +build linux,amd64 linux,arm64\n\npackage gvisor\n\nimport (\n\t\"fmt\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n\t\"gvisor.dev/gvisor/pkg/rawfile\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/device\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip/link/fdbased\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/link/tun\"\n)\n\nconst (\n\tifReqSize = unix.IFNAMSIZ + 64\n)\n\ntype GvisorTUN struct {\n\tstack.LinkEndpoint\n\n\toptions device.Options\n\n\tfd  int\n\tmtu uint32 // real MTU\n}\n\nfunc New(options device.Options) (device.Device, error) {\n\tt := &GvisorTUN{options: options}\n\n\tif len(options.Name) > unix.IFNAMSIZ {\n\t\treturn nil, newError(\"name too long\").AtError()\n\t}\n\n\tfd, err := tun.Open(options.Name)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to open tun device\").Base(err).AtError()\n\t}\n\tt.fd = fd\n\n\tif options.MTU > 0 {\n\t\t_ = setMTU(options.Name, int(options.MTU))\n\t}\n\n\tmtu, err := rawfile.GetMTU(options.Name)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get mtu\").Base(err).AtError()\n\t}\n\tt.mtu = mtu\n\n\tlinkEndpoint, err := fdbased.New(&fdbased.Options{\n\t\tFDs: []int{fd},\n\t\tMTU: mtu,\n\t\t// TUN is not need to process ethernet header.\n\t\tEthernetHeader: false,\n\t\t// Readv is the default dispatch mode and is the least performant of the\n\t\t// dispatch options but the one that is supported by all underlying FD\n\t\t// types.\n\t\tPacketDispatchMode:    fdbased.Readv,\n\t\tMaxSyscallHeaderBytes: 0x00,\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create link endpoint\").Base(err).AtError()\n\t}\n\tt.LinkEndpoint = linkEndpoint\n\n\treturn t, nil\n}\n\nfunc (t *GvisorTUN) Close() {\n\t_ = unix.Close(t.fd)\n}\n\n// Modified from golang.zx2c4.com/wireguard/tun/tun_linux.go\nfunc setMTU(name string, n int) error {\n\t// open datagram socket\n\tfd, err := unix.Socket(\n\t\tunix.AF_INET,\n\t\tunix.SOCK_DGRAM|unix.SOCK_CLOEXEC,\n\t\t0,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() { _ = unix.Close(fd) }()\n\n\t// do ioctl call\n\tvar ifr [ifReqSize]byte\n\tcopy(ifr[:], name)\n\t*(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n)\n\t_, _, errno := unix.Syscall(\n\t\tunix.SYS_IOCTL,\n\t\tuintptr(fd),\n\t\tuintptr(unix.SIOCSIFMTU),\n\t\tuintptr(unsafe.Pointer(&ifr[0])),\n\t)\n\n\tif errno != 0 {\n\t\treturn fmt.Errorf(\"failed to set MTU of TUN device: %w\", errno)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "app/tun/device/gvisor/gvisor_others.go",
    "content": "//go:build !linux || (linux && !(amd64 || arm64))\n// +build !linux linux,!amd64,!arm64\n\npackage gvisor\n\nimport \"github.com/v2fly/v2ray-core/v5/app/tun/device\"\n\nfunc New(options device.Options) (device.Device, error) {\n\treturn nil, newError(\"not supported\").AtError()\n}\n"
  },
  {
    "path": "app/tun/device/linkWriterToWriter.go",
    "content": "package device\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\n\t\"gvisor.dev/gvisor/pkg/buffer\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n)\n\nfunc NewLinkWriterToWriter(writer stack.LinkWriter) io.Writer {\n\treturn &linkWriterToWriter{writer: writer}\n}\n\ntype linkWriterToWriter struct {\n\twriter stack.LinkWriter\n}\n\nfunc (l linkWriterToWriter) Write(p []byte) (n int, err error) {\n\tbuffer := buffer.MakeWithData(p)\n\tpacketBufferPtr := stack.NewPacketBuffer(stack.PacketBufferOptions{\n\t\tPayload: buffer,\n\t\tOnRelease: func() {\n\t\t\tbuffer.Release()\n\t\t},\n\t})\n\tpacketList := stack.PacketBufferList{}\n\tpacketList.PushBack(packetBufferPtr)\n\t_, terr := l.writer.WritePackets(packetList)\n\tif terr != nil {\n\t\treturn 0, newError(\"failed to write packet\").Base(errors.New(terr.String())).AtError()\n\t}\n\treturn len(p), nil\n}\n"
  },
  {
    "path": "app/tun/errors.generated.go",
    "content": "package tun\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/tun/handler.go",
    "content": "package tun\n"
  },
  {
    "path": "app/tun/handler_tcp.go",
    "content": "package tun\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/header\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/tcp\"\n\t\"gvisor.dev/gvisor/pkg/waiter\"\n\n\ttun_net \"github.com/v2fly/v2ray-core/v5/app/tun/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\tinternet \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst (\n\trcvWnd      = 0 // default settings\n\tmaxInFlight = 2 << 10\n)\n\ntype tcpConn struct {\n\t*gonet.TCPConn\n\tid stack.TransportEndpointID\n}\n\nfunc (c *tcpConn) ID() *stack.TransportEndpointID {\n\treturn &c.id\n}\n\ntype TCPHandler struct {\n\tctx           context.Context\n\tdispatcher    routing.Dispatcher\n\tpolicyManager policy.Manager\n\tconfig        *Config\n}\n\nfunc SetTCPHandler(ctx context.Context, dispatcher routing.Dispatcher, policyManager policy.Manager, config *Config) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\ttcpForwarder := tcp.NewForwarder(s, rcvWnd, maxInFlight, func(r *tcp.ForwarderRequest) {\n\t\t\twg := new(waiter.Queue)\n\t\t\tlinkedEndpoint, err := r.CreateEndpoint(wg)\n\t\t\tif err != nil {\n\t\t\t\tr.Complete(true)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer r.Complete(false)\n\n\t\t\tif config.SocketSettings != nil {\n\t\t\t\tif err := applySocketOptions(s, linkedEndpoint, config.SocketSettings); err != nil {\n\t\t\t\t\tnewError(\"failed to apply socket options: \", err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconn := &tcpConn{\n\t\t\t\tTCPConn: gonet.NewTCPConn(wg, linkedEndpoint),\n\t\t\t\tid:      r.ID(),\n\t\t\t}\n\n\t\t\thandler := &TCPHandler{\n\t\t\t\tctx:           ctx,\n\t\t\t\tdispatcher:    dispatcher,\n\t\t\t\tpolicyManager: policyManager,\n\t\t\t\tconfig:        config,\n\t\t\t}\n\n\t\t\tgo handler.Handle(conn)\n\t\t})\n\n\t\ts.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)\n\n\t\treturn nil\n\t}\n}\n\nfunc (h *TCPHandler) Handle(conn tun_net.TCPConn) error {\n\tdefer conn.Close()\n\tid := conn.ID()\n\tctx := session.ContextWithInbound(h.ctx, &session.Inbound{Tag: h.config.Tag})\n\tsessionPolicy := h.policyManager.ForLevel(h.config.UserLevel)\n\n\tdest := net.TCPDestination(tun_net.AddressFromTCPIPAddr(id.LocalAddress), net.Port(id.LocalPort))\n\tsrc := net.TCPDestination(tun_net.AddressFromTCPIPAddr(id.RemoteAddress), net.Port(id.RemotePort))\n\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\tFrom:   src,\n\t\tTo:     dest,\n\t\tStatus: log.AccessAccepted,\n\t\tReason: \"\",\n\t})\n\tcontent := new(session.Content)\n\tif h.config.SniffingSettings != nil {\n\t\tcontent.SniffingRequest.Enabled = h.config.SniffingSettings.Enabled\n\t\tcontent.SniffingRequest.OverrideDestinationForProtocol = h.config.SniffingSettings.DestinationOverride\n\t\tcontent.SniffingRequest.MetadataOnly = h.config.SniffingSettings.MetadataOnly\n\t}\n\tctx = session.ContextWithContent(ctx, content)\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\tlink, err := h.dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn newError(\"failed to dispatch\").Base(err)\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tif err := buf.Copy(link.Reader, buf.NewWriter(conn), buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport all TCP response\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tif err := buf.Copy(buf.NewReader(conn), link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport all TCP request\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\trequestDoneAndCloseWriter := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(h.ctx, requestDoneAndCloseWriter, responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc applySocketOptions(s *stack.Stack, endpoint tcpip.Endpoint, config *internet.SocketConfig) tcpip.Error {\n\tif config.TcpKeepAliveInterval > 0 {\n\t\tinterval := tcpip.KeepaliveIntervalOption(time.Duration(config.TcpKeepAliveInterval) * time.Second)\n\t\tif err := endpoint.SetSockOpt(&interval); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif config.TcpKeepAliveIdle > 0 {\n\t\tidle := tcpip.KeepaliveIdleOption(time.Duration(config.TcpKeepAliveIdle) * time.Second)\n\t\tif err := endpoint.SetSockOpt(&idle); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {\n\t\tendpoint.SocketOptions().SetKeepAlive(true)\n\t}\n\t{\n\t\tvar sendBufferSizeRangeOption tcpip.TCPSendBufferSizeRangeOption\n\t\tif err := s.TransportProtocolOption(header.TCPProtocolNumber, &sendBufferSizeRangeOption); err == nil {\n\t\t\tendpoint.SocketOptions().SetReceiveBufferSize(int64(sendBufferSizeRangeOption.Default), false)\n\t\t}\n\n\t\tvar receiveBufferSizeRangeOption tcpip.TCPReceiveBufferSizeRangeOption\n\t\tif err := s.TransportProtocolOption(header.TCPProtocolNumber, &receiveBufferSizeRangeOption); err == nil {\n\t\t\tendpoint.SocketOptions().SetSendBufferSize(int64(receiveBufferSizeRangeOption.Default), false)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "app/tun/handler_udp.go",
    "content": "package tun\n\nimport (\n\t\"context\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\tgvisor_udp \"gvisor.dev/gvisor/pkg/tcpip/transport/udp\"\n\t\"gvisor.dev/gvisor/pkg/waiter\"\n\n\ttun_net \"github.com/v2fly/v2ray-core/v5/app/tun/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tudp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\ntype UDPHandler struct {\n\tctx           context.Context\n\tdispatcher    routing.Dispatcher\n\tpolicyManager policy.Manager\n\tconfig        *Config\n}\n\ntype udpConn struct {\n\t*gonet.UDPConn\n\tid stack.TransportEndpointID\n}\n\nfunc (c *udpConn) ID() *stack.TransportEndpointID {\n\treturn &c.id\n}\n\nfunc SetUDPHandler(ctx context.Context, dispatcher routing.Dispatcher, policyManager policy.Manager, config *Config) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\tudpForwarder := gvisor_udp.NewForwarder(s, func(r *gvisor_udp.ForwarderRequest) bool {\n\t\t\twg := new(waiter.Queue)\n\t\t\tlinkedEndpoint, err := r.CreateEndpoint(wg)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to create endpoint: \", err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tconn := &udpConn{\n\t\t\t\tUDPConn: gonet.NewUDPConn(wg, linkedEndpoint),\n\t\t\t\tid:      r.ID(),\n\t\t\t}\n\n\t\t\thandler := &UDPHandler{\n\t\t\t\tctx:           ctx,\n\t\t\t\tdispatcher:    dispatcher,\n\t\t\t\tpolicyManager: policyManager,\n\t\t\t\tconfig:        config,\n\t\t\t}\n\t\t\tgo handler.Handle(conn)\n\t\t\treturn true\n\t\t})\n\t\ts.SetTransportProtocolHandler(gvisor_udp.ProtocolNumber, udpForwarder.HandlePacket)\n\t\treturn nil\n\t}\n}\n\nfunc (h *UDPHandler) Handle(conn tun_net.UDPConn) error {\n\tdefer conn.Close()\n\tid := conn.ID()\n\tctx := session.ContextWithInbound(h.ctx, &session.Inbound{Tag: h.config.Tag})\n\tcontent := new(session.Content)\n\tif h.config.SniffingSettings != nil {\n\t\tcontent.SniffingRequest.Enabled = h.config.SniffingSettings.Enabled\n\t\tcontent.SniffingRequest.OverrideDestinationForProtocol = h.config.SniffingSettings.DestinationOverride\n\t\tcontent.SniffingRequest.MetadataOnly = h.config.SniffingSettings.MetadataOnly\n\t}\n\tctx = session.ContextWithContent(ctx, content)\n\n\tudpDispatcherConstructor := udp.NewSplitDispatcher\n\n\tdest := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.LocalAddress), net.Port(id.LocalPort))\n\tsrc := net.UDPDestination(tun_net.AddressFromTCPIPAddr(id.RemoteAddress), net.Port(id.RemotePort))\n\n\tudpServer := udpDispatcherConstructor(h.dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {\n\t\tif _, err := conn.WriteTo(packet.Payload.Bytes(), &net.UDPAddr{\n\t\t\tIP:   src.Address.IP(),\n\t\t\tPort: int(src.Port),\n\t\t}); err != nil {\n\t\t\tnewError(\"failed to write UDP packet\").Base(err).WriteToLog()\n\t\t}\n\t})\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil\n\t\tdefault:\n\t\t\tvar buffer [2048]byte\n\t\t\tn, _, err := conn.ReadFrom(buffer[:])\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to read UDP packet\").Base(err)\n\t\t\t}\n\t\t\tcurrentPacketCtx := ctx\n\n\t\t\tudpServer.Dispatch(currentPacketCtx, dest, buf.FromBytes(buffer[:n]))\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/tun/net/net.go",
    "content": "package net\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n)\n\ntype TCPConn interface {\n\tnet.Conn\n\n\tID() *stack.TransportEndpointID\n}\n\ntype UDPConn interface {\n\tnet.Conn\n\tnet.PacketConn\n\n\tID() *stack.TransportEndpointID\n}\n\nfunc AddressFromTCPIPAddr(addr tcpip.Address) net.Address {\n\treturn net.IPAddress(addr.AsSlice())\n}\n"
  },
  {
    "path": "app/tun/option.go",
    "content": "package tun\n\nimport (\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/tcp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n)\n\nfunc CreateNIC(id tcpip.NICID, linkEndpoint stack.LinkEndpoint) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\tif err := s.CreateNICWithOptions(id, linkEndpoint,\n\t\t\tstack.NICOptions{\n\t\t\t\tDisabled: false,\n\t\t\t\tQDisc:    nil,\n\t\t\t}); err != nil {\n\t\t\treturn newError(\"failed to create NIC:\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc SetPromiscuousMode(id tcpip.NICID, enable bool) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\tif err := s.SetPromiscuousMode(id, enable); err != nil {\n\t\t\treturn newError(\"failed to set promiscuous mode:\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc SetSpoofing(id tcpip.NICID, enable bool) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\tif err := s.SetSpoofing(id, enable); err != nil {\n\t\t\treturn newError(\"failed to set spoofing:\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc AddProtocolAddress(id tcpip.NICID, ips []*routercommon.CIDR) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\tfor _, ip := range ips {\n\t\t\ttcpIPAddr := tcpip.AddrFromSlice(ip.Ip)\n\t\t\tprotocolAddress := tcpip.ProtocolAddress{\n\t\t\t\tAddressWithPrefix: tcpip.AddressWithPrefix{\n\t\t\t\t\tAddress:   tcpIPAddr,\n\t\t\t\t\tPrefixLen: int(ip.Prefix),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tswitch tcpIPAddr.Len() {\n\t\t\tcase 4:\n\t\t\t\tprotocolAddress.Protocol = ipv4.ProtocolNumber\n\t\t\tcase 16:\n\t\t\t\tprotocolAddress.Protocol = ipv6.ProtocolNumber\n\t\t\tdefault:\n\t\t\t\treturn newError(\"invalid IP address length:\", tcpIPAddr.Len())\n\t\t\t}\n\n\t\t\tif err := s.AddProtocolAddress(id, protocolAddress, stack.AddressProperties{}); err != nil {\n\t\t\t\treturn newError(\"failed to add protocol address:\", err)\n\t\t\t}\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\nfunc SetRouteTable(id tcpip.NICID, routes []*routercommon.CIDR) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\ts.SetRouteTable(func() (table []tcpip.Route) {\n\t\t\tfor _, cidrs := range routes {\n\t\t\t\tsubnet := tcpip.AddressWithPrefix{\n\t\t\t\t\tAddress:   tcpip.AddrFromSlice(cidrs.Ip),\n\t\t\t\t\tPrefixLen: int(cidrs.Prefix),\n\t\t\t\t}.Subnet()\n\t\t\t\troute := tcpip.Route{\n\t\t\t\t\tDestination: subnet,\n\t\t\t\t\tNIC:         id,\n\t\t\t\t}\n\t\t\t\ttable = append(table, route)\n\t\t\t}\n\t\t\treturn\n\t\t}())\n\n\t\treturn nil\n\t}\n}\n\nfunc SetTCPSendBufferSize(size int) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\tsendBufferSizeRangeOption := tcpip.TCPSendBufferSizeRangeOption{Min: tcp.MinBufferSize, Default: size, Max: tcp.MaxBufferSize}\n\t\tif err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &sendBufferSizeRangeOption); err != nil {\n\t\t\treturn newError(\"failed to set tcp send buffer size:\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc SetTCPReceiveBufferSize(size int) StackOption {\n\treturn func(s *stack.Stack) error {\n\t\treceiveBufferSizeRangeOption := tcpip.TCPReceiveBufferSizeRangeOption{Min: tcp.MinBufferSize, Default: size, Max: tcp.MaxBufferSize}\n\t\tif err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &receiveBufferSizeRangeOption); err != nil {\n\t\t\treturn newError(\"failed to set tcp receive buffer size:\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "app/tun/packetaddradaptar.go",
    "content": "package tun\n\nimport (\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/device\"\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/tunsorter\"\n)\n\nfunc NewDeviceWithSorter(overlay device.Device, sorter *tunsorter.TunSorter) device.Device {\n\treturn &packetAddrDevice{\n\t\tDevice: overlay,\n\t\tsorter: sorter,\n\t}\n}\n\ntype packetAddrDevice struct {\n\tdevice.Device\n\tsorter *tunsorter.TunSorter\n\n\tsecondaryDispatcher stack.NetworkDispatcher\n}\n\nfunc (p *packetAddrDevice) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {\n\tbuf := pkt.ToBuffer()\n\t_, err := p.sorter.OnPacketReceived(buf.Flatten())\n\tif err != nil {\n\t\tp.secondaryDispatcher.DeliverNetworkPacket(protocol, pkt)\n\t}\n}\n\nfunc (p *packetAddrDevice) DeliverLinkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {\n\t// TODO implement me\n\tpanic(\"implement me\")\n}\n\nfunc (p *packetAddrDevice) Attach(dispatcher stack.NetworkDispatcher) {\n\tp.secondaryDispatcher = dispatcher\n\tp.Device.Attach(p)\n}\n"
  },
  {
    "path": "app/tun/packetparse/errors.generated.go",
    "content": "package packetparse\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/tun/packetparse/packetParse.go",
    "content": "package packetparse\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "app/tun/packetparse/udp.go",
    "content": "package packetparse\n\nimport (\n\t\"github.com/google/gopacket\"\n\t\"github.com/google/gopacket/layers\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nvar (\n\terrNotIPPacket  = newError(\"not an IP packet\")\n\terrNotUDPPacket = newError(\"not a UDP packet\")\n)\n\nvar nullDestination = net.UnixDestination(net.DomainAddress(\"null\"))\n\nfunc TryParseAsUDPPacket(packet []byte) (src, dst net.Destination, data []byte, err error) {\n\tparsedPacket := gopacket.NewPacket(packet, layers.LayerTypeIPv4, gopacket.DecodeOptions{\n\t\tLazy:                     true,\n\t\tNoCopy:                   false,\n\t\tSkipDecodeRecovery:       false,\n\t\tDecodeStreamsAsDatagrams: false,\n\t})\n\n\tvar srcIP net.Address\n\tvar dstIP net.Address\n\tipv4Layer := parsedPacket.Layer(layers.LayerTypeIPv4)\n\n\tif ipv4Layer == nil {\n\t\tparsedPacketAsIPv6 := gopacket.NewPacket(packet, layers.LayerTypeIPv6, gopacket.DecodeOptions{\n\t\t\tLazy:                     true,\n\t\t\tNoCopy:                   false,\n\t\t\tSkipDecodeRecovery:       false,\n\t\t\tDecodeStreamsAsDatagrams: false,\n\t\t})\n\t\tipv6Layer := parsedPacketAsIPv6.Layer(layers.LayerTypeIPv6)\n\t\tif ipv6Layer == nil {\n\t\t\treturn nullDestination, nullDestination, nil, errNotIPPacket\n\t\t}\n\t\tipv6 := ipv6Layer.(*layers.IPv6)\n\t\tsrcIP = net.IPAddress(ipv6.SrcIP)\n\t\tdstIP = net.IPAddress(ipv6.DstIP)\n\n\t\tparsedPacket = parsedPacketAsIPv6\n\t} else {\n\t\tipv4 := ipv4Layer.(*layers.IPv4)\n\t\tsrcIP = net.IPAddress(ipv4.SrcIP)\n\t\tdstIP = net.IPAddress(ipv4.DstIP)\n\t}\n\n\tudpLayer := parsedPacket.Layer(layers.LayerTypeUDP)\n\tif udpLayer == nil {\n\t\treturn nullDestination, nullDestination, nil, errNotUDPPacket\n\t}\n\tudp := udpLayer.(*layers.UDP)\n\tsrcPort := net.Port(udp.SrcPort)\n\tdstPort := net.Port(udp.DstPort)\n\n\tsrc = net.UDPDestination(srcIP, srcPort)\n\tdst = net.UDPDestination(dstIP, dstPort)\n\tdata = udp.Payload\n\treturn // nolint: nakedret\n}\n\nfunc TryConstructUDPPacket(src, dst net.Destination, data []byte) ([]byte, error) {\n\tif src.Address.Family().IsIPv4() && dst.Address.Family().IsIPv4() {\n\t\treturn constructIPv4UDPPacket(src, dst, data)\n\t}\n\tif src.Address.Family().IsIPv6() && dst.Address.Family().IsIPv6() {\n\t\treturn constructIPv6UDPPacket(src, dst, data)\n\t}\n\treturn nil, newError(\"not supported\")\n}\n\nfunc constructIPv4UDPPacket(src, dst net.Destination, data []byte) ([]byte, error) {\n\tipv4 := &layers.IPv4{\n\t\tVersion:  4,\n\t\tProtocol: layers.IPProtocolUDP,\n\t\tSrcIP:    src.Address.IP(),\n\t\tDstIP:    dst.Address.IP(),\n\t\tTTL:      64, // set TTL to a reasonable non-zero value to allow non-local routing\n\t}\n\tudp := &layers.UDP{\n\t\tSrcPort: layers.UDPPort(src.Port),\n\t\tDstPort: layers.UDPPort(dst.Port),\n\t}\n\terr := udp.SetNetworkLayerForChecksum(ipv4)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbuffer := gopacket.NewSerializeBuffer()\n\tif err := gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{\n\t\tFixLengths:       true,\n\t\tComputeChecksums: true,\n\t}, ipv4, udp, gopacket.Payload(data)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buffer.Bytes(), nil\n}\n\nfunc constructIPv6UDPPacket(src, dst net.Destination, data []byte) ([]byte, error) {\n\tipv6 := &layers.IPv6{\n\t\tVersion:    6,\n\t\tNextHeader: layers.IPProtocolUDP,\n\t\tSrcIP:      src.Address.IP(),\n\t\tDstIP:      dst.Address.IP(),\n\t\tHopLimit:   64,\n\t}\n\tudp := &layers.UDP{\n\t\tSrcPort: layers.UDPPort(src.Port),\n\t\tDstPort: layers.UDPPort(dst.Port),\n\t}\n\terr := udp.SetNetworkLayerForChecksum(ipv6)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbuffer := gopacket.NewSerializeBuffer()\n\tif err := gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{\n\t\tFixLengths:       true,\n\t\tComputeChecksums: true,\n\t}, ipv6, udp, gopacket.Payload(data)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buffer.Bytes(), nil\n}\n"
  },
  {
    "path": "app/tun/stack.go",
    "content": "package tun\n\nimport (\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/icmp\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/tcp\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/udp\"\n)\n\ntype StackOption func(*stack.Stack) error\n\nfunc (t *TUN) CreateStack(linkedEndpoint stack.LinkEndpoint) (*stack.Stack, error) {\n\ts := stack.New(stack.Options{\n\t\tNetworkProtocols: []stack.NetworkProtocolFactory{\n\t\t\tipv4.NewProtocol,\n\t\t\tipv6.NewProtocol,\n\t\t},\n\t\tTransportProtocols: []stack.TransportProtocolFactory{\n\t\t\ttcp.NewProtocol,\n\t\t\tudp.NewProtocol,\n\t\t\ticmp.NewProtocol4,\n\t\t\ticmp.NewProtocol6,\n\t\t},\n\t})\n\n\tnicID := s.NextNICID()\n\n\topts := []StackOption{\n\t\tSetTCPHandler(t.ctx, t.dispatcher, t.policyManager, t.config),\n\t\tSetUDPHandler(t.ctx, t.dispatcher, t.policyManager, t.config),\n\n\t\tCreateNIC(nicID, linkedEndpoint),\n\t\tAddProtocolAddress(nicID, t.config.Ips),\n\t\tSetRouteTable(nicID, t.config.Routes),\n\t\tSetPromiscuousMode(nicID, t.config.EnablePromiscuousMode),\n\t\tSetSpoofing(nicID, t.config.EnableSpoofing),\n\t}\n\n\tif t.config.SocketSettings != nil {\n\t\tif size := t.config.SocketSettings.TxBufSize; size != 0 {\n\t\t\topts = append(opts, SetTCPSendBufferSize(int(size)))\n\t\t}\n\n\t\tif size := t.config.SocketSettings.RxBufSize; size != 0 {\n\t\t\topts = append(opts, SetTCPReceiveBufferSize(int(size)))\n\t\t}\n\t}\n\n\tfor _, opt := range opts {\n\t\tif err := opt(s); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn s, nil\n}\n"
  },
  {
    "path": "app/tun/tun.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage tun\n\nimport (\n\t\"context\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/device\"\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/device/gvisor\"\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/tunsorter\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype TUN struct {\n\tctx           context.Context\n\tdispatcher    routing.Dispatcher\n\tpolicyManager policy.Manager\n\tconfig        *Config\n\n\tstack *stack.Stack\n}\n\nfunc (t *TUN) Type() interface{} {\n\treturn (*TUN)(nil)\n}\n\nfunc (t *TUN) Start() error {\n\tDeviceConstructor := gvisor.New\n\ttunDevice, err := DeviceConstructor(device.Options{\n\t\tName: t.config.Name,\n\t\tMTU:  t.config.Mtu,\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to create device\").Base(err).AtError()\n\t}\n\n\tif t.config.PacketEncoding != packetaddr.PacketAddrType_None {\n\t\twriter := device.NewLinkWriterToWriter(tunDevice)\n\t\tsorter := tunsorter.NewTunSorter(writer, t.dispatcher, t.config.PacketEncoding, t.ctx)\n\t\ttunDeviceLayered := NewDeviceWithSorter(tunDevice, sorter)\n\t\ttunDevice = tunDeviceLayered\n\t}\n\n\tstack, err := t.CreateStack(tunDevice)\n\tif err != nil {\n\t\treturn newError(\"failed to create stack\").Base(err).AtError()\n\t}\n\tt.stack = stack\n\n\treturn nil\n}\n\nfunc (t *TUN) Close() error {\n\tif t.stack != nil {\n\t\tt.stack.Close()\n\t\tt.stack.Wait()\n\t}\n\treturn nil\n}\n\nfunc (t *TUN) Init(ctx context.Context, config *Config, dispatcher routing.Dispatcher, policyManager policy.Manager) error {\n\tt.ctx = ctx\n\tt.config = config\n\tt.dispatcher = dispatcher\n\tt.policyManager = policyManager\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\ttun := new(TUN)\n\t\terr := core.RequireFeatures(ctx, func(d routing.Dispatcher, p policy.Manager) error {\n\t\t\treturn tun.Init(ctx, config.(*Config), d, p)\n\t\t})\n\t\treturn tun, err\n\t}))\n}\n"
  },
  {
    "path": "app/tun/tunsorter/errors.generated.go",
    "content": "package tunsorter\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "app/tun/tunsorter/tunsorter.go",
    "content": "package tunsorter\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/tun/packetparse\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tvudp \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc NewTunSorter(tunWriter io.Writer, dispatcher routing.Dispatcher, packetAddrType packetaddr.PacketAddrType, ctx context.Context) *TunSorter {\n\treturn &TunSorter{\n\t\ttunWriter:      tunWriter,\n\t\tdispatcher:     dispatcher,\n\t\tpacketAddrType: packetAddrType,\n\t\tctx:            ctx,\n\t}\n}\n\ntype TunSorter struct {\n\ttunWriter      io.Writer\n\tdispatcher     routing.Dispatcher\n\tpacketAddrType packetaddr.PacketAddrType\n\n\ttrackedConnections sync.Map\n\tctx                context.Context\n}\n\nfunc (t *TunSorter) OnPacketReceived(b []byte) (n int, err error) {\n\tsrc, dst, data, err := packetparse.TryParseAsUDPPacket(b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tconn := newTrackedUDPConnection(src, t)\n\ttrackedConnection, loaded := t.trackedConnections.LoadOrStore(src.String(), conn)\n\tconn = trackedConnection.(*trackedUDPConnection)\n\tif !loaded {\n\t\tt.onNewConnection(conn)\n\t}\n\tconn.onNewPacket(dst, data)\n\treturn len(b), nil\n}\n\nfunc (t *TunSorter) onNewConnection(connection *trackedUDPConnection) {\n\tudpDispatcherConstructor := udp.NewSplitDispatcher\n\tswitch t.packetAddrType { // nolint: gocritic\n\tcase packetaddr.PacketAddrType_Packet:\n\t\tctx := context.WithValue(t.ctx, udp.DispatcherConnectionTerminationSignalReceiverMark, connection) // nolint:staticcheck\n\t\tpacketAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)\n\t\tudpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher\n\t}\n\tudpDispatcher := udpDispatcherConstructor(t.dispatcher, func(ctx context.Context, packet *vudp.Packet) {\n\t\tconnection.onWritePacket(packet.Source, packet.Payload.Bytes())\n\t})\n\tconnection.packetDispatcher = udpDispatcher\n}\n\nfunc (t *TunSorter) onWritePacket(src net.Destination, dest net.Destination, data []byte) {\n\tdata, err := packetparse.TryConstructUDPPacket(src, dest, data)\n\tif err != nil {\n\t\tnewError(\"failed to construct udp packet\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\t_, err = t.tunWriter.Write(data)\n\tif err != nil {\n\t\tnewError(\"failed to write udp packet to tun\").Base(err).WriteToLog()\n\t\treturn\n\t}\n}\n\nfunc newTrackedUDPConnection(src net.Destination, tunSorter *TunSorter) *trackedUDPConnection {\n\treturn &trackedUDPConnection{\n\t\ttunSorter: tunSorter,\n\t\tsrc:       src,\n\t}\n}\n\ntype trackedUDPConnection struct {\n\tpacketDispatcher udp.DispatcherI\n\ttunSorter        *TunSorter\n\tsrc              net.Destination\n}\n\nfunc (t *trackedUDPConnection) onNewPacket(dst net.Destination, data []byte) {\n\tt.packetDispatcher.Dispatch(context.Background(), dst, buf.FromBytes(data))\n}\n\nfunc (t *trackedUDPConnection) onWritePacket(src net.Destination, data []byte) {\n\tt.tunSorter.onWritePacket(src, t.src, data)\n}\n\nfunc (t *trackedUDPConnection) Close() error {\n\tt.tunSorter.trackedConnections.Delete(t.src.String())\n\treturn nil\n}\n"
  },
  {
    "path": "common/antireplay/antireplay.go",
    "content": "package antireplay\n\ntype GeneralizedReplayFilter interface {\n\tInterval() int64\n\tCheck(sum []byte) bool\n}\n"
  },
  {
    "path": "common/antireplay/bloomring.go",
    "content": "package antireplay\n\nimport (\n\t\"sync\"\n\n\tss_bloomring \"github.com/v2fly/ss-bloomring\"\n)\n\ntype BloomRing struct {\n\t*ss_bloomring.BloomRing\n\tlock *sync.Mutex\n}\n\nfunc (b BloomRing) Interval() int64 {\n\treturn 9999999\n}\n\nfunc (b BloomRing) Check(sum []byte) bool {\n\tb.lock.Lock()\n\tdefer b.lock.Unlock()\n\tif b.Test(sum) {\n\t\treturn false\n\t}\n\tb.Add(sum)\n\treturn true\n}\n\nfunc NewBloomRing() BloomRing {\n\tconst (\n\t\tDefaultSFCapacity = 1e6\n\t\t// FalsePositiveRate\n\t\tDefaultSFFPR  = 1e-6\n\t\tDefaultSFSlot = 10\n\t)\n\treturn BloomRing{ss_bloomring.NewBloomRing(DefaultSFSlot, DefaultSFCapacity, DefaultSFFPR), &sync.Mutex{}}\n}\n"
  },
  {
    "path": "common/antireplay/replayfilter.go",
    "content": "package antireplay\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\tcuckoo \"github.com/seiflotfy/cuckoofilter\"\n)\n\nconst replayFilterCapacity = 100000\n\n// ReplayFilter checks for replay attacks.\ntype ReplayFilter struct {\n\tlock     sync.Mutex\n\tpoolA    *cuckoo.Filter\n\tpoolB    *cuckoo.Filter\n\tpoolSwap bool\n\tlastSwap int64\n\tinterval int64\n}\n\n// NewReplayFilter creates a new filter with specifying the expiration time interval in seconds.\nfunc NewReplayFilter(interval int64) *ReplayFilter {\n\tfilter := &ReplayFilter{}\n\tfilter.interval = interval\n\treturn filter\n}\n\n// Interval in second for expiration time for duplicate records.\nfunc (filter *ReplayFilter) Interval() int64 {\n\treturn filter.interval\n}\n\n// Check determines if there are duplicate records.\nfunc (filter *ReplayFilter) Check(sum []byte) bool {\n\tfilter.lock.Lock()\n\tdefer filter.lock.Unlock()\n\n\tnow := time.Now().Unix()\n\tif filter.lastSwap == 0 {\n\t\tfilter.lastSwap = now\n\t\tfilter.poolA = cuckoo.NewFilter(replayFilterCapacity)\n\t\tfilter.poolB = cuckoo.NewFilter(replayFilterCapacity)\n\t}\n\n\telapsed := now - filter.lastSwap\n\tif elapsed >= filter.Interval() {\n\t\tif filter.poolSwap {\n\t\t\tfilter.poolA.Reset()\n\t\t} else {\n\t\t\tfilter.poolB.Reset()\n\t\t}\n\t\tfilter.poolSwap = !filter.poolSwap\n\t\tfilter.lastSwap = now\n\t}\n\n\treturn filter.poolA.InsertUnique(sum) && filter.poolB.InsertUnique(sum)\n}\n"
  },
  {
    "path": "common/bitmask/byte.go",
    "content": "package bitmask\n\n// Byte is a bitmask in byte.\ntype Byte byte\n\n// Has returns true if this bitmask contains another bitmask.\nfunc (b Byte) Has(bb Byte) bool {\n\treturn (b & bb) != 0\n}\n\nfunc (b *Byte) Set(bb Byte) {\n\t*b |= bb\n}\n\nfunc (b *Byte) Clear(bb Byte) {\n\t*b &= ^bb\n}\n\nfunc (b *Byte) Toggle(bb Byte) {\n\t*b ^= bb\n}\n"
  },
  {
    "path": "common/bitmask/byte_test.go",
    "content": "package bitmask_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/bitmask\"\n)\n\nfunc TestBitmaskByte(t *testing.T) {\n\tb := Byte(0)\n\tb.Set(Byte(1))\n\tif !b.Has(1) {\n\t\tt.Fatal(\"expected \", b, \" to contain 1, but actually not\")\n\t}\n\n\tb.Set(Byte(2))\n\tif !b.Has(2) {\n\t\tt.Fatal(\"expected \", b, \" to contain 2, but actually not\")\n\t}\n\tif !b.Has(1) {\n\t\tt.Fatal(\"expected \", b, \" to contain 1, but actually not\")\n\t}\n\n\tb.Clear(Byte(1))\n\tif !b.Has(2) {\n\t\tt.Fatal(\"expected \", b, \" to contain 2, but actually not\")\n\t}\n\tif b.Has(1) {\n\t\tt.Fatal(\"expected \", b, \" to not contain 1, but actually did\")\n\t}\n\n\tb.Toggle(Byte(2))\n\tif b.Has(2) {\n\t\tt.Fatal(\"expected \", b, \" to not contain 2, but actually did\")\n\t}\n}\n"
  },
  {
    "path": "common/buf/buf.go",
    "content": "// Package buf provides a light-weight memory allocation mechanism.\npackage buf\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/buf/buffer.go",
    "content": "package buf\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/bytespool\"\n)\n\nconst (\n\t// Size of a regular buffer.\n\tSize = 2048\n)\n\nvar pool = bytespool.GetPool(Size)\n\n// ownership represents the data owner of the buffer.\ntype ownership uint8\n\nconst (\n\tmanaged    ownership = 0\n\tunmanaged  ownership = 1\n\tbytespools ownership = 2\n)\n\n// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles\n// the buffer into an internal buffer pool, in order to recreate a buffer more\n// quickly.\ntype Buffer struct {\n\tv         []byte\n\tstart     int32\n\tend       int32\n\townership ownership\n}\n\n// New creates a Buffer with 0 length and 2K capacity.\nfunc New() *Buffer {\n\treturn &Buffer{\n\t\tv: pool.Get().([]byte),\n\t}\n}\n\n// NewWithSize creates a Buffer with 0 length and capacity with at least the given size.\nfunc NewWithSize(size int32) *Buffer {\n\treturn &Buffer{\n\t\tv:         bytespool.Alloc(size),\n\t\townership: bytespools,\n\t}\n}\n\n// FromBytes creates a Buffer with an existed bytearray\nfunc FromBytes(data []byte) *Buffer {\n\treturn &Buffer{\n\t\tv:         data,\n\t\tend:       int32(len(data)),\n\t\townership: unmanaged,\n\t}\n}\n\n// StackNew creates a new Buffer object on stack.\n// This method is for buffers that is released in the same function.\nfunc StackNew() Buffer {\n\treturn Buffer{\n\t\tv: pool.Get().([]byte),\n\t}\n}\n\n// Release recycles the buffer into an internal buffer pool.\nfunc (b *Buffer) Release() {\n\tif b == nil || b.v == nil || b.ownership == unmanaged {\n\t\treturn\n\t}\n\n\tp := b.v\n\tb.v = nil\n\tb.Clear()\n\tswitch b.ownership {\n\tcase managed:\n\t\tpool.Put(p) // nolint: staticcheck\n\tcase bytespools:\n\t\tbytespool.Free(p) // nolint: staticcheck\n\t}\n}\n\n// Clear clears the content of the buffer, results an empty buffer with\n// Len() = 0.\nfunc (b *Buffer) Clear() {\n\tb.start = 0\n\tb.end = 0\n}\n\n// Byte returns the bytes at index.\nfunc (b *Buffer) Byte(index int32) byte {\n\treturn b.v[b.start+index]\n}\n\n// SetByte sets the byte value at index.\nfunc (b *Buffer) SetByte(index int32, value byte) {\n\tb.v[b.start+index] = value\n}\n\n// Bytes returns the content bytes of this Buffer.\nfunc (b *Buffer) Bytes() []byte {\n\treturn b.v[b.start:b.end]\n}\n\n// Extend increases the buffer size by n bytes, and returns the extended part.\n// It panics if result size is larger than buf.Size.\nfunc (b *Buffer) Extend(n int32) []byte {\n\tend := b.end + n\n\tif end > int32(len(b.v)) {\n\t\tpanic(\"extending out of bound\")\n\t}\n\text := b.v[b.end:end]\n\tb.end = end\n\treturn ext\n}\n\n// BytesRange returns a slice of this buffer with given from and to boundary.\nfunc (b *Buffer) BytesRange(from, to int32) []byte {\n\tif from < 0 {\n\t\tfrom += b.Len()\n\t}\n\tif to < 0 {\n\t\tto += b.Len()\n\t}\n\treturn b.v[b.start+from : b.start+to]\n}\n\n// BytesFrom returns a slice of this Buffer starting from the given position.\nfunc (b *Buffer) BytesFrom(from int32) []byte {\n\tif from < 0 {\n\t\tfrom += b.Len()\n\t}\n\treturn b.v[b.start+from : b.end]\n}\n\n// BytesTo returns a slice of this Buffer from start to the given position.\nfunc (b *Buffer) BytesTo(to int32) []byte {\n\tif to < 0 {\n\t\tto += b.Len()\n\t}\n\treturn b.v[b.start : b.start+to]\n}\n\n// Resize cuts the buffer at the given position.\nfunc (b *Buffer) Resize(from, to int32) {\n\tif from < 0 {\n\t\tfrom += b.Len()\n\t}\n\tif to < 0 {\n\t\tto += b.Len()\n\t}\n\tif to < from {\n\t\tpanic(\"Invalid slice\")\n\t}\n\tb.end = b.start + to\n\tb.start += from\n}\n\n// Advance cuts the buffer at the given position.\nfunc (b *Buffer) Advance(from int32) {\n\tif from < 0 {\n\t\tfrom += b.Len()\n\t}\n\tb.start += from\n}\n\n// Len returns the length of the buffer content.\nfunc (b *Buffer) Len() int32 {\n\tif b == nil {\n\t\treturn 0\n\t}\n\treturn b.end - b.start\n}\n\n// Cap returns the capacity of the buffer content.\nfunc (b *Buffer) Cap() int32 {\n\tif b == nil {\n\t\treturn 0\n\t}\n\treturn int32(len(b.v))\n}\n\n// IsEmpty returns true if the buffer is empty.\nfunc (b *Buffer) IsEmpty() bool {\n\treturn b.Len() == 0\n}\n\n// IsFull returns true if the buffer has no more room to grow.\nfunc (b *Buffer) IsFull() bool {\n\treturn b != nil && b.end == int32(len(b.v))\n}\n\n// Write implements Write method in io.Writer.\nfunc (b *Buffer) Write(data []byte) (int, error) {\n\tnBytes := copy(b.v[b.end:], data)\n\tb.end += int32(nBytes)\n\treturn nBytes, nil\n}\n\n// WriteByte writes a single byte into the buffer.\nfunc (b *Buffer) WriteByte(v byte) error {\n\tif b.IsFull() {\n\t\treturn newError(\"buffer full\")\n\t}\n\tb.v[b.end] = v\n\tb.end++\n\treturn nil\n}\n\n// WriteString implements io.StringWriter.\nfunc (b *Buffer) WriteString(s string) (int, error) {\n\treturn b.Write([]byte(s))\n}\n\n// ReadByte implements io.ByteReader\nfunc (b *Buffer) ReadByte() (byte, error) {\n\tif b.start == b.end {\n\t\treturn 0, io.EOF\n\t}\n\n\tnb := b.v[b.start]\n\tb.start++\n\treturn nb, nil\n}\n\n// ReadBytes implements bufio.Reader.ReadBytes\nfunc (b *Buffer) ReadBytes(length int32) ([]byte, error) {\n\tif b.end-b.start < length {\n\t\treturn nil, io.EOF\n\t}\n\n\tnb := b.v[b.start : b.start+length]\n\tb.start += length\n\treturn nb, nil\n}\n\n// Read implements io.Reader.Read().\nfunc (b *Buffer) Read(data []byte) (int, error) {\n\tif b.Len() == 0 {\n\t\treturn 0, io.EOF\n\t}\n\tnBytes := copy(data, b.v[b.start:b.end])\n\tif int32(nBytes) == b.Len() {\n\t\tb.Clear()\n\t} else {\n\t\tb.start += int32(nBytes)\n\t}\n\treturn nBytes, nil\n}\n\n// ReadFrom implements io.ReaderFrom.\nfunc (b *Buffer) ReadFrom(reader io.Reader) (int64, error) {\n\tn, err := reader.Read(b.v[b.end:])\n\tb.end += int32(n)\n\treturn int64(n), err\n}\n\n// ReadFullFrom reads exact size of bytes from given reader, or until error occurs.\nfunc (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) {\n\tend := b.end + size\n\tif end > int32(len(b.v)) {\n\t\tv := end\n\t\treturn 0, newError(\"out of bound: \", v)\n\t}\n\tn, err := io.ReadFull(reader, b.v[b.end:end])\n\tb.end += int32(n)\n\treturn int64(n), err\n}\n\n// String returns the string form of this Buffer.\nfunc (b *Buffer) String() string {\n\treturn string(b.Bytes())\n}\n"
  },
  {
    "path": "common/buf/buffer_test.go",
    "content": "package buf_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\nfunc TestBufferClear(t *testing.T) {\n\tbuffer := New()\n\tdefer buffer.Release()\n\n\tpayload := \"Bytes\"\n\tbuffer.Write([]byte(payload))\n\tif diff := cmp.Diff(buffer.Bytes(), []byte(payload)); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n\n\tbuffer.Clear()\n\tif buffer.Len() != 0 {\n\t\tt.Error(\"expect 0 length, but got \", buffer.Len())\n\t}\n}\n\nfunc TestBufferIsEmpty(t *testing.T) {\n\tbuffer := New()\n\tdefer buffer.Release()\n\n\tif buffer.IsEmpty() != true {\n\t\tt.Error(\"expect empty buffer, but not\")\n\t}\n}\n\nfunc TestBufferString(t *testing.T) {\n\tbuffer := New()\n\tdefer buffer.Release()\n\n\tconst payload = \"Test String\"\n\tcommon.Must2(buffer.WriteString(payload))\n\tif buffer.String() != payload {\n\t\tt.Error(\"expect buffer content as \", payload, \" but actually \", buffer.String())\n\t}\n}\n\nfunc TestBufferByte(t *testing.T) {\n\t{\n\t\tbuffer := New()\n\t\tcommon.Must(buffer.WriteByte('m'))\n\t\tif buffer.String() != \"m\" {\n\t\t\tt.Error(\"expect buffer content as \", \"m\", \" but actually \", buffer.String())\n\t\t}\n\t\tbuffer.Release()\n\t}\n\t{\n\t\tbuffer := StackNew()\n\t\tcommon.Must(buffer.WriteByte('n'))\n\t\tif buffer.String() != \"n\" {\n\t\t\tt.Error(\"expect buffer content as \", \"n\", \" but actually \", buffer.String())\n\t\t}\n\t\tbuffer.Release()\n\t}\n\t{\n\t\tbuffer := StackNew()\n\t\tcommon.Must2(buffer.WriteString(\"HELLOWORLD\"))\n\t\tif b := buffer.Byte(5); b != 'W' {\n\t\t\tt.Error(\"unexpected byte \", b)\n\t\t}\n\n\t\tbuffer.SetByte(5, 'M')\n\t\tif buffer.String() != \"HELLOMORLD\" {\n\t\t\tt.Error(\"expect buffer content as \", \"n\", \" but actually \", buffer.String())\n\t\t}\n\t\tbuffer.Release()\n\t}\n}\n\nfunc TestBufferResize(t *testing.T) {\n\tbuffer := New()\n\tdefer buffer.Release()\n\n\tconst payload = \"Test String\"\n\tcommon.Must2(buffer.WriteString(payload))\n\tif buffer.String() != payload {\n\t\tt.Error(\"expect buffer content as \", payload, \" but actually \", buffer.String())\n\t}\n\n\tbuffer.Resize(-6, -3)\n\tif l := buffer.Len(); int(l) != 3 {\n\t\tt.Error(\"len error \", l)\n\t}\n\n\tif s := buffer.String(); s != \"Str\" {\n\t\tt.Error(\"unexpect buffer \", s)\n\t}\n\n\tbuffer.Resize(int32(len(payload)), 200)\n\tif l := buffer.Len(); int(l) != 200-len(payload) {\n\t\tt.Error(\"len error \", l)\n\t}\n}\n\nfunc TestBufferSlice(t *testing.T) {\n\t{\n\t\tb := New()\n\t\tcommon.Must2(b.Write([]byte(\"abcd\")))\n\t\tbytes := b.BytesFrom(-2)\n\t\tif diff := cmp.Diff(bytes, []byte{'c', 'd'}); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n\n\t{\n\t\tb := New()\n\t\tcommon.Must2(b.Write([]byte(\"abcd\")))\n\t\tbytes := b.BytesTo(-2)\n\t\tif diff := cmp.Diff(bytes, []byte{'a', 'b'}); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n\n\t{\n\t\tb := New()\n\t\tcommon.Must2(b.Write([]byte(\"abcd\")))\n\t\tbytes := b.BytesRange(-3, -1)\n\t\tif diff := cmp.Diff(bytes, []byte{'b', 'c'}); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n}\n\nfunc TestBufferReadFullFrom(t *testing.T) {\n\tpayload := make([]byte, 1024)\n\tcommon.Must2(rand.Read(payload))\n\n\treader := bytes.NewReader(payload)\n\tb := New()\n\tn, err := b.ReadFullFrom(reader, 1024)\n\tcommon.Must(err)\n\tif n != 1024 {\n\t\tt.Error(\"expect reading 1024 bytes, but actually \", n)\n\t}\n\n\tif diff := cmp.Diff(payload, b.Bytes()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n\nfunc BenchmarkNewBuffer(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tbuffer := New()\n\t\tbuffer.Release()\n\t}\n}\n\nfunc BenchmarkNewBufferStack(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tbuffer := StackNew()\n\t\tbuffer.Release()\n\t}\n}\n\nfunc BenchmarkWrite2(b *testing.B) {\n\tbuffer := New()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _ = buffer.Write([]byte{'a', 'b'})\n\t\tbuffer.Clear()\n\t}\n}\n\nfunc BenchmarkWrite8(b *testing.B) {\n\tbuffer := New()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _ = buffer.Write([]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'})\n\t\tbuffer.Clear()\n\t}\n}\n\nfunc BenchmarkWrite32(b *testing.B) {\n\tbuffer := New()\n\tpayload := make([]byte, 32)\n\trand.Read(payload)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _ = buffer.Write(payload)\n\t\tbuffer.Clear()\n\t}\n}\n\nfunc BenchmarkWriteByte2(b *testing.B) {\n\tbuffer := New()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = buffer.WriteByte('a')\n\t\t_ = buffer.WriteByte('b')\n\t\tbuffer.Clear()\n\t}\n}\n\nfunc BenchmarkWriteByte8(b *testing.B) {\n\tbuffer := New()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = buffer.WriteByte('a')\n\t\t_ = buffer.WriteByte('b')\n\t\t_ = buffer.WriteByte('c')\n\t\t_ = buffer.WriteByte('d')\n\t\t_ = buffer.WriteByte('e')\n\t\t_ = buffer.WriteByte('f')\n\t\t_ = buffer.WriteByte('g')\n\t\t_ = buffer.WriteByte('h')\n\t\tbuffer.Clear()\n\t}\n}\n"
  },
  {
    "path": "common/buf/copy.go",
    "content": "package buf\n\nimport (\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n)\n\ntype dataHandler func(MultiBuffer)\n\ntype copyHandler struct {\n\tonData []dataHandler\n}\n\n// SizeCounter is for counting bytes copied by Copy().\ntype SizeCounter struct {\n\tSize int64\n}\n\n// CopyOption is an option for copying data.\ntype CopyOption func(*copyHandler)\n\n// UpdateActivity is a CopyOption to update activity on each data copy operation.\nfunc UpdateActivity(timer signal.ActivityUpdater) CopyOption {\n\treturn func(handler *copyHandler) {\n\t\thandler.onData = append(handler.onData, func(MultiBuffer) {\n\t\t\ttimer.Update()\n\t\t})\n\t}\n}\n\n// CountSize is a CopyOption that sums the total size of data copied into the given SizeCounter.\nfunc CountSize(sc *SizeCounter) CopyOption {\n\treturn func(handler *copyHandler) {\n\t\thandler.onData = append(handler.onData, func(b MultiBuffer) {\n\t\t\tsc.Size += int64(b.Len())\n\t\t})\n\t}\n}\n\ntype readError struct {\n\terror\n}\n\nfunc (e readError) Error() string {\n\treturn e.error.Error()\n}\n\nfunc (e readError) Inner() error {\n\treturn e.error\n}\n\n// IsReadError returns true if the error in Copy() comes from reading.\nfunc IsReadError(err error) bool {\n\t_, ok := err.(readError)\n\treturn ok\n}\n\ntype writeError struct {\n\terror\n}\n\nfunc (e writeError) Error() string {\n\treturn e.error.Error()\n}\n\nfunc (e writeError) Inner() error {\n\treturn e.error\n}\n\n// IsWriteError returns true if the error in Copy() comes from writing.\nfunc IsWriteError(err error) bool {\n\t_, ok := err.(writeError)\n\treturn ok\n}\n\nfunc copyInternal(reader Reader, writer Writer, handler *copyHandler) error {\n\tfor {\n\t\tbuffer, err := reader.ReadMultiBuffer()\n\t\tif !buffer.IsEmpty() {\n\t\t\tfor _, handler := range handler.onData {\n\t\t\t\thandler(buffer)\n\t\t\t}\n\n\t\t\tif werr := writer.WriteMultiBuffer(buffer); werr != nil {\n\t\t\t\treturn writeError{werr}\n\t\t\t}\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn readError{err}\n\t\t}\n\t}\n}\n\n// Copy dumps all payload from reader to writer or stops when an error occurs. It returns nil when EOF.\nfunc Copy(reader Reader, writer Writer, options ...CopyOption) error {\n\tvar handler copyHandler\n\tfor _, option := range options {\n\t\toption(&handler)\n\t}\n\terr := copyInternal(reader, writer, &handler)\n\tif err != nil && errors.Cause(err) != io.EOF {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nvar ErrNotTimeoutReader = newError(\"not a TimeoutReader\")\n\nfunc CopyOnceTimeout(reader Reader, writer Writer, timeout time.Duration) error {\n\ttimeoutReader, ok := reader.(TimeoutReader)\n\tif !ok {\n\t\treturn ErrNotTimeoutReader\n\t}\n\tmb, err := timeoutReader.ReadMultiBufferTimeout(timeout)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn writer.WriteMultiBuffer(mb)\n}\n"
  },
  {
    "path": "common/buf/copy_test.go",
    "content": "package buf_test\n\nimport (\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/golang/mock/gomock\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/mocks\"\n)\n\nfunc TestReadError(t *testing.T) {\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockReader := mocks.NewReader(mockCtl)\n\tmockReader.EXPECT().Read(gomock.Any()).Return(0, errors.New(\"error\"))\n\n\terr := buf.Copy(buf.NewReader(mockReader), buf.Discard)\n\tif err == nil {\n\t\tt.Fatal(\"expected error, but nil\")\n\t}\n\n\tif !buf.IsReadError(err) {\n\t\tt.Error(\"expected to be ReadError, but not\")\n\t}\n\n\tif err.Error() != \"error\" {\n\t\tt.Fatal(\"unexpected error message: \", err.Error())\n\t}\n}\n\nfunc TestWriteError(t *testing.T) {\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockWriter := mocks.NewWriter(mockCtl)\n\tmockWriter.EXPECT().Write(gomock.Any()).Return(0, errors.New(\"error\"))\n\n\terr := buf.Copy(buf.NewReader(rand.Reader), buf.NewWriter(mockWriter))\n\tif err == nil {\n\t\tt.Fatal(\"expected error, but nil\")\n\t}\n\n\tif !buf.IsWriteError(err) {\n\t\tt.Error(\"expected to be WriteError, but not\")\n\t}\n\n\tif err.Error() != \"error\" {\n\t\tt.Fatal(\"unexpected error message: \", err.Error())\n\t}\n}\n\ntype TestReader struct{}\n\nfunc (TestReader) Read(b []byte) (int, error) {\n\treturn len(b), nil\n}\n\nfunc BenchmarkCopy(b *testing.B) {\n\treader := buf.NewReader(io.LimitReader(TestReader{}, 10240))\n\twriter := buf.Discard\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = buf.Copy(reader, writer)\n\t}\n}\n"
  },
  {
    "path": "common/buf/errors.generated.go",
    "content": "package buf\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/buf/io.go",
    "content": "package buf\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// Reader extends io.Reader with MultiBuffer.\ntype Reader interface {\n\t// ReadMultiBuffer reads content from underlying reader, and put it into a MultiBuffer.\n\tReadMultiBuffer() (MultiBuffer, error)\n}\n\n// ErrReadTimeout is an error that happens with IO timeout.\nvar ErrReadTimeout = newError(\"IO timeout\")\n\n// TimeoutReader is a reader that returns error if Read() operation takes longer than the given timeout.\ntype TimeoutReader interface {\n\tReadMultiBufferTimeout(time.Duration) (MultiBuffer, error)\n}\n\n// Writer extends io.Writer with MultiBuffer.\ntype Writer interface {\n\t// WriteMultiBuffer writes a MultiBuffer into underlying writer.\n\t// Caller relinquish the ownership of MultiBuffer after calling this method.\n\tWriteMultiBuffer(MultiBuffer) error\n}\n\n// WriteAllBytes ensures all bytes are written into the given writer.\nfunc WriteAllBytes(writer io.Writer, payload []byte) error {\n\tfor len(payload) > 0 {\n\t\tn, err := writer.Write(payload)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpayload = payload[n:]\n\t}\n\treturn nil\n}\n\nfunc isPacketReader(reader io.Reader) bool {\n\t_, ok := reader.(net.PacketConn)\n\treturn ok\n}\n\n// NewReader creates a new Reader.\n// The Reader instance doesn't take the ownership of reader.\nfunc NewReader(reader io.Reader) Reader {\n\tif mr, ok := reader.(Reader); ok {\n\t\treturn mr\n\t}\n\n\tif isPacketReader(reader) {\n\t\treturn &PacketReader{\n\t\t\tReader: reader,\n\t\t}\n\t}\n\n\t_, isFile := reader.(*os.File)\n\tif !isFile && useReadv {\n\t\tif sc, ok := reader.(syscall.Conn); ok {\n\t\t\trawConn, err := sc.SyscallConn()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get sysconn\").Base(err).WriteToLog()\n\t\t\t} else {\n\t\t\t\treturn NewReadVReader(reader, rawConn)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &SingleReader{\n\t\tReader: reader,\n\t}\n}\n\n// NewPacketReader creates a new PacketReader based on the given reader.\nfunc NewPacketReader(reader io.Reader) Reader {\n\tif mr, ok := reader.(Reader); ok {\n\t\treturn mr\n\t}\n\n\treturn &PacketReader{\n\t\tReader: reader,\n\t}\n}\n\nfunc isPacketWriter(writer io.Writer) bool {\n\tif _, ok := writer.(net.PacketConn); ok {\n\t\treturn true\n\t}\n\n\t// If the writer doesn't implement syscall.Conn, it is probably not a TCP connection.\n\tif _, ok := writer.(syscall.Conn); !ok {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// NewWriter creates a new Writer.\nfunc NewWriter(writer io.Writer) Writer {\n\tif mw, ok := writer.(Writer); ok {\n\t\treturn mw\n\t}\n\n\tif isPacketWriter(writer) {\n\t\treturn &SequentialWriter{\n\t\t\tWriter: writer,\n\t\t}\n\t}\n\n\treturn &BufferToBytesWriter{\n\t\tWriter: writer,\n\t}\n}\n"
  },
  {
    "path": "common/buf/io_test.go",
    "content": "package buf_test\n\nimport (\n\t\"crypto/tls\"\n\t\"io\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestWriterCreation(t *testing.T) {\n\ttcpServer := tcp.Server{}\n\tdest, err := tcpServer.Start()\n\tif err != nil {\n\t\tt.Fatal(\"failed to start tcp server: \", err)\n\t}\n\tdefer tcpServer.Close()\n\n\tconn, err := net.Dial(\"tcp\", dest.NetAddr())\n\tif err != nil {\n\t\tt.Fatal(\"failed to dial a TCP connection: \", err)\n\t}\n\tdefer conn.Close()\n\n\t{\n\t\twriter := NewWriter(conn)\n\t\tif _, ok := writer.(*BufferToBytesWriter); !ok {\n\t\t\tt.Fatal(\"writer is not a BufferToBytesWriter\")\n\t\t}\n\n\t\twriter2 := NewWriter(writer.(io.Writer))\n\t\tif writer2 != writer {\n\t\t\tt.Fatal(\"writer is not reused\")\n\t\t}\n\t}\n\n\ttlsConn := tls.Client(conn, &tls.Config{\n\t\tInsecureSkipVerify: true,\n\t})\n\tdefer tlsConn.Close()\n\n\t{\n\t\twriter := NewWriter(tlsConn)\n\t\tif _, ok := writer.(*SequentialWriter); !ok {\n\t\t\tt.Fatal(\"writer is not a SequentialWriter\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/buf/multi_buffer.go",
    "content": "package buf\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\n// ReadAllToBytes reads all content from the reader into a byte array, until EOF.\nfunc ReadAllToBytes(reader io.Reader) ([]byte, error) {\n\tmb, err := ReadFrom(reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif mb.Len() == 0 {\n\t\treturn nil, nil\n\t}\n\tb := make([]byte, mb.Len())\n\tmb, _ = SplitBytes(mb, b)\n\tReleaseMulti(mb)\n\treturn b, nil\n}\n\n// MultiBuffer is a list of Buffers. The order of Buffer matters.\ntype MultiBuffer []*Buffer\n\n// MergeMulti merges content from src to dest, and returns the new address of dest and src\nfunc MergeMulti(dest MultiBuffer, src MultiBuffer) (MultiBuffer, MultiBuffer) {\n\tdest = append(dest, src...)\n\tfor idx := range src {\n\t\tsrc[idx] = nil\n\t}\n\treturn dest, src[:0]\n}\n\n// MergeBytes merges the given bytes into MultiBuffer and return the new address of the merged MultiBuffer.\nfunc MergeBytes(dest MultiBuffer, src []byte) MultiBuffer {\n\tn := len(dest)\n\tif n > 0 && !(dest)[n-1].IsFull() {\n\t\tnBytes, _ := (dest)[n-1].Write(src)\n\t\tsrc = src[nBytes:]\n\t}\n\n\tfor len(src) > 0 {\n\t\tb := New()\n\t\tnBytes, _ := b.Write(src)\n\t\tsrc = src[nBytes:]\n\t\tdest = append(dest, b)\n\t}\n\n\treturn dest\n}\n\n// ReleaseMulti releases all content of the MultiBuffer, and returns an empty MultiBuffer.\nfunc ReleaseMulti(mb MultiBuffer) MultiBuffer {\n\tfor i := range mb {\n\t\tmb[i].Release()\n\t\tmb[i] = nil\n\t}\n\treturn mb[:0]\n}\n\n// Copy copied the beginning part of the MultiBuffer into the given byte array.\nfunc (mb MultiBuffer) Copy(b []byte) int {\n\ttotal := 0\n\tfor _, bb := range mb {\n\t\tnBytes := copy(b[total:], bb.Bytes())\n\t\ttotal += nBytes\n\t\tif int32(nBytes) < bb.Len() {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn total\n}\n\n// ReadFrom reads all content from reader until EOF.\nfunc ReadFrom(reader io.Reader) (MultiBuffer, error) {\n\tmb := make(MultiBuffer, 0, 16)\n\tfor {\n\t\tb := New()\n\t\t_, err := b.ReadFullFrom(reader, Size)\n\t\tif b.IsEmpty() {\n\t\t\tb.Release()\n\t\t} else {\n\t\t\tmb = append(mb, b)\n\t\t}\n\t\tif err != nil {\n\t\t\tif errors.Cause(err) == io.EOF || errors.Cause(err) == io.ErrUnexpectedEOF {\n\t\t\t\treturn mb, nil\n\t\t\t}\n\t\t\treturn mb, err\n\t\t}\n\t}\n}\n\n// SplitBytes splits the given amount of bytes from the beginning of the MultiBuffer.\n// It returns the new address of MultiBuffer leftover, and number of bytes written into the input byte slice.\nfunc SplitBytes(mb MultiBuffer, b []byte) (MultiBuffer, int) {\n\ttotalBytes := 0\n\tendIndex := -1\n\tfor i := range mb {\n\t\tpBuffer := mb[i]\n\t\tnBytes, _ := pBuffer.Read(b)\n\t\ttotalBytes += nBytes\n\t\tb = b[nBytes:]\n\t\tif !pBuffer.IsEmpty() {\n\t\t\tendIndex = i\n\t\t\tbreak\n\t\t}\n\t\tpBuffer.Release()\n\t\tmb[i] = nil\n\t}\n\n\tif endIndex == -1 {\n\t\tmb = mb[:0]\n\t} else {\n\t\tmb = mb[endIndex:]\n\t}\n\n\treturn mb, totalBytes\n}\n\n// SplitFirstBytes splits the first buffer from MultiBuffer, and then copy its content into the given slice.\nfunc SplitFirstBytes(mb MultiBuffer, p []byte) (MultiBuffer, int) {\n\tmb, b := SplitFirst(mb)\n\tif b == nil {\n\t\treturn mb, 0\n\t}\n\tn := copy(p, b.Bytes())\n\tb.Release()\n\treturn mb, n\n}\n\n// Compact returns another MultiBuffer by merging all content of the given one together.\nfunc Compact(mb MultiBuffer) MultiBuffer {\n\tif len(mb) == 0 {\n\t\treturn mb\n\t}\n\n\tmb2 := make(MultiBuffer, 0, len(mb))\n\tlast := mb[0]\n\n\tfor i := 1; i < len(mb); i++ {\n\t\tcurr := mb[i]\n\t\tif last.Len()+curr.Len() > Size {\n\t\t\tmb2 = append(mb2, last)\n\t\t\tlast = curr\n\t\t} else {\n\t\t\tcommon.Must2(last.ReadFrom(curr))\n\t\t\tcurr.Release()\n\t\t}\n\t}\n\n\tmb2 = append(mb2, last)\n\treturn mb2\n}\n\n// SplitFirst splits the first Buffer from the beginning of the MultiBuffer.\nfunc SplitFirst(mb MultiBuffer) (MultiBuffer, *Buffer) {\n\tif len(mb) == 0 {\n\t\treturn mb, nil\n\t}\n\n\tb := mb[0]\n\tmb[0] = nil\n\tmb = mb[1:]\n\treturn mb, b\n}\n\n// SplitSize splits the beginning of the MultiBuffer into another one, for at most size bytes.\nfunc SplitSize(mb MultiBuffer, size int32) (MultiBuffer, MultiBuffer) {\n\tif len(mb) == 0 {\n\t\treturn mb, nil\n\t}\n\n\tif mb[0].Len() > size {\n\t\tb := New()\n\t\tcopy(b.Extend(size), mb[0].BytesTo(size))\n\t\tmb[0].Advance(size)\n\t\treturn mb, MultiBuffer{b}\n\t}\n\n\ttotalBytes := int32(0)\n\tvar r MultiBuffer\n\tendIndex := -1\n\tfor i := range mb {\n\t\tif totalBytes+mb[i].Len() > size {\n\t\t\tendIndex = i\n\t\t\tbreak\n\t\t}\n\t\ttotalBytes += mb[i].Len()\n\t\tr = append(r, mb[i])\n\t\tmb[i] = nil\n\t}\n\tif endIndex == -1 {\n\t\t// To reuse mb array\n\t\tmb = mb[:0]\n\t} else {\n\t\tmb = mb[endIndex:]\n\t}\n\treturn mb, r\n}\n\n// WriteMultiBuffer writes all buffers from the MultiBuffer to the Writer one by one, and return error if any, with leftover MultiBuffer.\nfunc WriteMultiBuffer(writer io.Writer, mb MultiBuffer) (MultiBuffer, error) {\n\tfor {\n\t\tmb2, b := SplitFirst(mb)\n\t\tmb = mb2\n\t\tif b == nil {\n\t\t\tbreak\n\t\t}\n\n\t\t_, err := writer.Write(b.Bytes())\n\t\tb.Release()\n\t\tif err != nil {\n\t\t\treturn mb, err\n\t\t}\n\t}\n\n\treturn nil, nil\n}\n\n// Len returns the total number of bytes in the MultiBuffer.\nfunc (mb MultiBuffer) Len() int32 {\n\tif mb == nil {\n\t\treturn 0\n\t}\n\n\tsize := int32(0)\n\tfor _, b := range mb {\n\t\tsize += b.Len()\n\t}\n\treturn size\n}\n\n// IsEmpty returns true if the MultiBuffer has no content.\nfunc (mb MultiBuffer) IsEmpty() bool {\n\tfor _, b := range mb {\n\t\tif !b.IsEmpty() {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// String returns the content of the MultiBuffer in string.\nfunc (mb MultiBuffer) String() string {\n\tv := make([]interface{}, len(mb))\n\tfor i, b := range mb {\n\t\tv[i] = b\n\t}\n\treturn serial.Concat(v...)\n}\n\n// MultiBufferContainer is a ReadWriteCloser wrapper over MultiBuffer.\ntype MultiBufferContainer struct {\n\tMultiBuffer\n}\n\n// Read implements io.Reader.\nfunc (c *MultiBufferContainer) Read(b []byte) (int, error) {\n\tif c.MultiBuffer.IsEmpty() {\n\t\treturn 0, io.EOF\n\t}\n\n\tmb, nBytes := SplitBytes(c.MultiBuffer, b)\n\tc.MultiBuffer = mb\n\treturn nBytes, nil\n}\n\n// ReadMultiBuffer implements Reader.\nfunc (c *MultiBufferContainer) ReadMultiBuffer() (MultiBuffer, error) {\n\tmb := c.MultiBuffer\n\tc.MultiBuffer = nil\n\treturn mb, nil\n}\n\n// Write implements io.Writer.\nfunc (c *MultiBufferContainer) Write(b []byte) (int, error) {\n\tc.MultiBuffer = MergeBytes(c.MultiBuffer, b)\n\treturn len(b), nil\n}\n\n// WriteMultiBuffer implements Writer.\nfunc (c *MultiBufferContainer) WriteMultiBuffer(b MultiBuffer) error {\n\tmb, _ := MergeMulti(c.MultiBuffer, b)\n\tc.MultiBuffer = mb\n\treturn nil\n}\n\n// Close implements io.Closer.\nfunc (c *MultiBufferContainer) Close() error {\n\tc.MultiBuffer = ReleaseMulti(c.MultiBuffer)\n\treturn nil\n}\n"
  },
  {
    "path": "common/buf/multi_buffer_test.go",
    "content": "package buf_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\nfunc TestMultiBufferRead(t *testing.T) {\n\tb1 := New()\n\tcommon.Must2(b1.WriteString(\"ab\"))\n\n\tb2 := New()\n\tcommon.Must2(b2.WriteString(\"cd\"))\n\tmb := MultiBuffer{b1, b2}\n\n\tbs := make([]byte, 32)\n\t_, nBytes := SplitBytes(mb, bs)\n\tif nBytes != 4 {\n\t\tt.Error(\"expect 4 bytes split, but got \", nBytes)\n\t}\n\tif r := cmp.Diff(bs[:nBytes], []byte(\"abcd\")); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestMultiBufferAppend(t *testing.T) {\n\tvar mb MultiBuffer\n\tb := New()\n\tcommon.Must2(b.WriteString(\"ab\"))\n\tmb = append(mb, b)\n\tif mb.Len() != 2 {\n\t\tt.Error(\"expected length 2, but got \", mb.Len())\n\t}\n}\n\nfunc TestMultiBufferSliceBySizeLarge(t *testing.T) {\n\tlb := make([]byte, 8*1024)\n\tcommon.Must2(io.ReadFull(rand.Reader, lb))\n\n\tmb := MergeBytes(nil, lb)\n\n\tmb, mb2 := SplitSize(mb, 1024)\n\tif mb2.Len() != 1024 {\n\t\tt.Error(\"expect length 1024, but got \", mb2.Len())\n\t}\n\tif mb.Len() != 7*1024 {\n\t\tt.Error(\"expect length 7*1024, but got \", mb.Len())\n\t}\n\n\tmb, mb3 := SplitSize(mb, 7*1024)\n\tif mb3.Len() != 7*1024 {\n\t\tt.Error(\"expect length 7*1024, but got\", mb.Len())\n\t}\n\n\tif !mb.IsEmpty() {\n\t\tt.Error(\"expect empty buffer, but got \", mb.Len())\n\t}\n}\n\nfunc TestMultiBufferSplitFirst(t *testing.T) {\n\tb1 := New()\n\tb1.WriteString(\"b1\")\n\n\tb2 := New()\n\tb2.WriteString(\"b2\")\n\n\tb3 := New()\n\tb3.WriteString(\"b3\")\n\n\tvar mb MultiBuffer\n\tmb = append(mb, b1, b2, b3)\n\n\tmb, c1 := SplitFirst(mb)\n\tif diff := cmp.Diff(b1.String(), c1.String()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n\n\tmb, c2 := SplitFirst(mb)\n\tif diff := cmp.Diff(b2.String(), c2.String()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n\n\tmb, c3 := SplitFirst(mb)\n\tif diff := cmp.Diff(b3.String(), c3.String()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n\n\tif !mb.IsEmpty() {\n\t\tt.Error(\"expect empty buffer, but got \", mb.String())\n\t}\n}\n\nfunc TestMultiBufferReadAllToByte(t *testing.T) {\n\t{\n\t\tlb := make([]byte, 8*1024)\n\t\tcommon.Must2(io.ReadFull(rand.Reader, lb))\n\t\trd := bytes.NewBuffer(lb)\n\t\tb, err := ReadAllToBytes(rd)\n\t\tcommon.Must(err)\n\n\t\tif l := len(b); l != 8*1024 {\n\t\t\tt.Error(\"unexpected length from ReadAllToBytes\", l)\n\t\t}\n\t}\n\t{\n\t\tconst dat = \"data/test_MultiBufferReadAllToByte.dat\"\n\t\tf, err := os.Open(dat)\n\t\tcommon.Must(err)\n\n\t\tbuf2, err := ReadAllToBytes(f)\n\t\tcommon.Must(err)\n\t\tf.Close()\n\n\t\tcnt, err := os.ReadFile(dat)\n\t\tcommon.Must(err)\n\n\t\tif d := cmp.Diff(buf2, cnt); d != \"\" {\n\t\t\tt.Error(\"fail to read from file: \", d)\n\t\t}\n\t}\n}\n\nfunc TestMultiBufferCopy(t *testing.T) {\n\tlb := make([]byte, 8*1024)\n\tcommon.Must2(io.ReadFull(rand.Reader, lb))\n\treader := bytes.NewBuffer(lb)\n\n\tmb, err := ReadFrom(reader)\n\tcommon.Must(err)\n\n\tlbdst := make([]byte, 8*1024)\n\tmb.Copy(lbdst)\n\n\tif d := cmp.Diff(lb, lbdst); d != \"\" {\n\t\tt.Error(\"unexpected different from MultiBufferCopy \", d)\n\t}\n}\n\nfunc TestSplitFirstBytes(t *testing.T) {\n\ta := New()\n\tcommon.Must2(a.WriteString(\"ab\"))\n\tb := New()\n\tcommon.Must2(b.WriteString(\"bc\"))\n\n\tmb := MultiBuffer{a, b}\n\n\to := make([]byte, 2)\n\t_, cnt := SplitFirstBytes(mb, o)\n\tif cnt != 2 {\n\t\tt.Error(\"unexpected cnt from SplitFirstBytes \", cnt)\n\t}\n\tif d := cmp.Diff(string(o), \"ab\"); d != \"\" {\n\t\tt.Error(\"unexpected splited result from SplitFirstBytes \", d)\n\t}\n}\n\nfunc TestCompact(t *testing.T) {\n\ta := New()\n\tcommon.Must2(a.WriteString(\"ab\"))\n\tb := New()\n\tcommon.Must2(b.WriteString(\"bc\"))\n\n\tmb := MultiBuffer{a, b}\n\tcmb := Compact(mb)\n\n\tif w := cmb.String(); w != \"abbc\" {\n\t\tt.Error(\"unexpected Compact result \", w)\n\t}\n}\n\nfunc BenchmarkSplitBytes(b *testing.B) {\n\tvar mb MultiBuffer\n\traw := make([]byte, Size)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tbuffer := StackNew()\n\t\tbuffer.Extend(Size)\n\t\tmb = append(mb, &buffer)\n\t\tmb, _ = SplitBytes(mb, raw)\n\t}\n}\n"
  },
  {
    "path": "common/buf/reader.go",
    "content": "package buf\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n)\n\nfunc readOneUDP(r io.Reader) (*Buffer, error) {\n\tb := New()\n\tfor i := 0; i < 64; i++ {\n\t\t_, err := b.ReadFrom(r)\n\t\tif !b.IsEmpty() {\n\t\t\treturn b, nil\n\t\t}\n\t\tif err != nil {\n\t\t\tb.Release()\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tb.Release()\n\treturn nil, newError(\"Reader returns too many empty payloads.\")\n}\n\n// ReadBuffer reads a Buffer from the given reader.\nfunc ReadBuffer(r io.Reader) (*Buffer, error) {\n\tb := New()\n\tn, err := b.ReadFrom(r)\n\tif n > 0 {\n\t\treturn b, err\n\t}\n\tb.Release()\n\treturn nil, err\n}\n\n// BufferedReader is a Reader that keeps its internal buffer.\ntype BufferedReader struct {\n\t// Reader is the underlying reader to be read from\n\tReader Reader\n\t// Buffer is the internal buffer to be read from first\n\tBuffer MultiBuffer\n\t// Spliter is a function to read bytes from MultiBuffer\n\tSpliter func(MultiBuffer, []byte) (MultiBuffer, int)\n}\n\n// BufferedBytes returns the number of bytes that is cached in this reader.\nfunc (r *BufferedReader) BufferedBytes() int32 {\n\treturn r.Buffer.Len()\n}\n\n// ReadByte implements io.ByteReader.\nfunc (r *BufferedReader) ReadByte() (byte, error) {\n\tvar b [1]byte\n\t_, err := r.Read(b[:])\n\treturn b[0], err\n}\n\n// Read implements io.Reader. It reads from internal buffer first (if available) and then reads from the underlying reader.\nfunc (r *BufferedReader) Read(b []byte) (int, error) {\n\tspliter := r.Spliter\n\tif spliter == nil {\n\t\tspliter = SplitBytes\n\t}\n\n\tif !r.Buffer.IsEmpty() {\n\t\tbuffer, nBytes := spliter(r.Buffer, b)\n\t\tr.Buffer = buffer\n\t\tif r.Buffer.IsEmpty() {\n\t\t\tr.Buffer = nil\n\t\t}\n\t\treturn nBytes, nil\n\t}\n\n\tmb, err := r.Reader.ReadMultiBuffer()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tmb, nBytes := spliter(mb, b)\n\tif !mb.IsEmpty() {\n\t\tr.Buffer = mb\n\t}\n\treturn nBytes, nil\n}\n\n// ReadMultiBuffer implements Reader.\nfunc (r *BufferedReader) ReadMultiBuffer() (MultiBuffer, error) {\n\tif !r.Buffer.IsEmpty() {\n\t\tmb := r.Buffer\n\t\tr.Buffer = nil\n\t\treturn mb, nil\n\t}\n\n\treturn r.Reader.ReadMultiBuffer()\n}\n\n// ReadAtMost returns a MultiBuffer with at most size.\nfunc (r *BufferedReader) ReadAtMost(size int32) (MultiBuffer, error) {\n\tif r.Buffer.IsEmpty() {\n\t\tmb, err := r.Reader.ReadMultiBuffer()\n\t\tif mb.IsEmpty() && err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tr.Buffer = mb\n\t}\n\n\trb, mb := SplitSize(r.Buffer, size)\n\tr.Buffer = rb\n\tif r.Buffer.IsEmpty() {\n\t\tr.Buffer = nil\n\t}\n\treturn mb, nil\n}\n\nfunc (r *BufferedReader) writeToInternal(writer io.Writer) (int64, error) {\n\tmbWriter := NewWriter(writer)\n\tvar sc SizeCounter\n\tif r.Buffer != nil {\n\t\tsc.Size = int64(r.Buffer.Len())\n\t\tif err := mbWriter.WriteMultiBuffer(r.Buffer); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tr.Buffer = nil\n\t}\n\n\terr := Copy(r.Reader, mbWriter, CountSize(&sc))\n\treturn sc.Size, err\n}\n\n// WriteTo implements io.WriterTo.\nfunc (r *BufferedReader) WriteTo(writer io.Writer) (int64, error) {\n\tnBytes, err := r.writeToInternal(writer)\n\tif errors.Cause(err) == io.EOF {\n\t\treturn nBytes, nil\n\t}\n\treturn nBytes, err\n}\n\n// Interrupt implements common.Interruptible.\nfunc (r *BufferedReader) Interrupt() {\n\tcommon.Interrupt(r.Reader)\n}\n\n// Close implements io.Closer.\nfunc (r *BufferedReader) Close() error {\n\treturn common.Close(r.Reader)\n}\n\n// SingleReader is a Reader that read one Buffer every time.\ntype SingleReader struct {\n\tio.Reader\n}\n\n// ReadMultiBuffer implements Reader.\nfunc (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {\n\tb, err := ReadBuffer(r.Reader)\n\treturn MultiBuffer{b}, err\n}\n\n// PacketReader is a Reader that read one Buffer every time.\ntype PacketReader struct {\n\tio.Reader\n}\n\n// ReadMultiBuffer implements Reader.\nfunc (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {\n\tb, err := readOneUDP(r.Reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn MultiBuffer{b}, nil\n}\n"
  },
  {
    "path": "common/buf/reader_test.go",
    "content": "package buf_test\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc TestBytesReaderWriteTo(t *testing.T) {\n\tpReader, pWriter := pipe.New(pipe.WithSizeLimit(1024))\n\treader := &BufferedReader{Reader: pReader}\n\tb1 := New()\n\tb1.WriteString(\"abc\")\n\tb2 := New()\n\tb2.WriteString(\"efg\")\n\tcommon.Must(pWriter.WriteMultiBuffer(MultiBuffer{b1, b2}))\n\tpWriter.Close()\n\n\tpReader2, pWriter2 := pipe.New(pipe.WithSizeLimit(1024))\n\twriter := NewBufferedWriter(pWriter2)\n\twriter.SetBuffered(false)\n\n\tnBytes, err := io.Copy(writer, reader)\n\tcommon.Must(err)\n\tif nBytes != 6 {\n\t\tt.Error(\"copy: \", nBytes)\n\t}\n\n\tmb, err := pReader2.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif s := mb.String(); s != \"abcefg\" {\n\t\tt.Error(\"content: \", s)\n\t}\n}\n\nfunc TestBytesReaderMultiBuffer(t *testing.T) {\n\tpReader, pWriter := pipe.New(pipe.WithSizeLimit(1024))\n\treader := &BufferedReader{Reader: pReader}\n\tb1 := New()\n\tb1.WriteString(\"abc\")\n\tb2 := New()\n\tb2.WriteString(\"efg\")\n\tcommon.Must(pWriter.WriteMultiBuffer(MultiBuffer{b1, b2}))\n\tpWriter.Close()\n\n\tmbReader := NewReader(reader)\n\tmb, err := mbReader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif s := mb.String(); s != \"abcefg\" {\n\t\tt.Error(\"content: \", s)\n\t}\n}\n\nfunc TestReadByte(t *testing.T) {\n\tsr := strings.NewReader(\"abcd\")\n\treader := &BufferedReader{\n\t\tReader: NewReader(sr),\n\t}\n\tb, err := reader.ReadByte()\n\tcommon.Must(err)\n\tif b != 'a' {\n\t\tt.Error(\"unexpected byte: \", b, \" want a\")\n\t}\n\tif reader.BufferedBytes() != 3 { // 3 bytes left in buffer\n\t\tt.Error(\"unexpected buffered Bytes: \", reader.BufferedBytes())\n\t}\n\n\tnBytes, err := reader.WriteTo(DiscardBytes)\n\tcommon.Must(err)\n\tif nBytes != 3 {\n\t\tt.Error(\"unexpect bytes written: \", nBytes)\n\t}\n}\n\nfunc TestReadBuffer(t *testing.T) {\n\t{\n\t\tsr := strings.NewReader(\"abcd\")\n\t\tbuf, err := ReadBuffer(sr)\n\t\tcommon.Must(err)\n\n\t\tif s := buf.String(); s != \"abcd\" {\n\t\t\tt.Error(\"unexpected str: \", s, \" want abcd\")\n\t\t}\n\t\tbuf.Release()\n\t}\n}\n\nfunc TestReadAtMost(t *testing.T) {\n\tsr := strings.NewReader(\"abcd\")\n\treader := &BufferedReader{\n\t\tReader: NewReader(sr),\n\t}\n\n\tmb, err := reader.ReadAtMost(3)\n\tcommon.Must(err)\n\tif s := mb.String(); s != \"abc\" {\n\t\tt.Error(\"unexpected read result: \", s)\n\t}\n\n\tnBytes, err := reader.WriteTo(DiscardBytes)\n\tcommon.Must(err)\n\tif nBytes != 1 {\n\t\tt.Error(\"unexpect bytes written: \", nBytes)\n\t}\n}\n\nfunc TestPacketReader_ReadMultiBuffer(t *testing.T) {\n\tconst alpha = \"abcefg\"\n\tbuf := bytes.NewBufferString(alpha)\n\treader := &PacketReader{buf}\n\tmb, err := reader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif s := mb.String(); s != alpha {\n\t\tt.Error(\"content: \", s)\n\t}\n}\n\nfunc TestReaderInterface(t *testing.T) {\n\t_ = (io.Reader)(new(ReadVReader))\n\t_ = (Reader)(new(ReadVReader))\n\n\t_ = (Reader)(new(BufferedReader))\n\t_ = (io.Reader)(new(BufferedReader))\n\t_ = (io.ByteReader)(new(BufferedReader))\n\t_ = (io.WriterTo)(new(BufferedReader))\n}\n"
  },
  {
    "path": "common/buf/readv_posix.go",
    "content": "//go:build !windows && !wasm && !illumos\n// +build !windows,!wasm,!illumos\n\npackage buf\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\ntype posixReader struct {\n\tiovecs []syscall.Iovec\n}\n\nfunc (r *posixReader) Init(bs []*Buffer) {\n\tiovecs := r.iovecs\n\tif iovecs == nil {\n\t\tiovecs = make([]syscall.Iovec, 0, len(bs))\n\t}\n\tfor idx, b := range bs {\n\t\tiovecs = append(iovecs, syscall.Iovec{\n\t\t\tBase: &(b.v[0]),\n\t\t})\n\t\tiovecs[idx].SetLen(int(Size))\n\t}\n\tr.iovecs = iovecs\n}\n\nfunc (r *posixReader) Read(fd uintptr) int32 {\n\tn, _, e := syscall.Syscall(syscall.SYS_READV, fd, uintptr(unsafe.Pointer(&r.iovecs[0])), uintptr(len(r.iovecs)))\n\tif e != 0 {\n\t\treturn -1\n\t}\n\treturn int32(n)\n}\n\nfunc (r *posixReader) Clear() {\n\tfor idx := range r.iovecs {\n\t\tr.iovecs[idx].Base = nil\n\t}\n\tr.iovecs = r.iovecs[:0]\n}\n\nfunc newMultiReader() multiReader {\n\treturn &posixReader{}\n}\n"
  },
  {
    "path": "common/buf/readv_reader.go",
    "content": "//go:build !wasm\n// +build !wasm\n\npackage buf\n\nimport (\n\t\"io\"\n\t\"runtime\"\n\t\"syscall\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n)\n\ntype allocStrategy struct {\n\tcurrent uint32\n}\n\nfunc (s *allocStrategy) Current() uint32 {\n\treturn s.current\n}\n\nfunc (s *allocStrategy) Adjust(n uint32) {\n\tif n >= s.current {\n\t\ts.current *= 4\n\t} else {\n\t\ts.current = n\n\t}\n\n\tif s.current > 32 {\n\t\ts.current = 32\n\t}\n\n\tif s.current == 0 {\n\t\ts.current = 1\n\t}\n}\n\nfunc (s *allocStrategy) Alloc() []*Buffer {\n\tbs := make([]*Buffer, s.current)\n\tfor i := range bs {\n\t\tbs[i] = New()\n\t}\n\treturn bs\n}\n\ntype multiReader interface {\n\tInit([]*Buffer)\n\tRead(fd uintptr) int32\n\tClear()\n}\n\n// ReadVReader is a Reader that uses readv(2) syscall to read data.\ntype ReadVReader struct {\n\tio.Reader\n\trawConn syscall.RawConn\n\tmr      multiReader\n\talloc   allocStrategy\n}\n\n// NewReadVReader creates a new ReadVReader.\nfunc NewReadVReader(reader io.Reader, rawConn syscall.RawConn) *ReadVReader {\n\treturn &ReadVReader{\n\t\tReader:  reader,\n\t\trawConn: rawConn,\n\t\talloc: allocStrategy{\n\t\t\tcurrent: 1,\n\t\t},\n\t\tmr: newMultiReader(),\n\t}\n}\n\nfunc (r *ReadVReader) readMulti() (MultiBuffer, error) {\n\tbs := r.alloc.Alloc()\n\n\tr.mr.Init(bs)\n\tvar nBytes int32\n\terr := r.rawConn.Read(func(fd uintptr) bool {\n\t\tn := r.mr.Read(fd)\n\t\tif n < 0 {\n\t\t\treturn false\n\t\t}\n\n\t\tnBytes = n\n\t\treturn true\n\t})\n\tr.mr.Clear()\n\n\tif err != nil {\n\t\tReleaseMulti(MultiBuffer(bs))\n\t\treturn nil, err\n\t}\n\n\tif nBytes == 0 {\n\t\tReleaseMulti(MultiBuffer(bs))\n\t\treturn nil, io.EOF\n\t}\n\n\tnBuf := 0\n\tfor nBuf < len(bs) {\n\t\tif nBytes <= 0 {\n\t\t\tbreak\n\t\t}\n\t\tend := nBytes\n\t\tif end > Size {\n\t\t\tend = Size\n\t\t}\n\t\tbs[nBuf].end = end\n\t\tnBytes -= end\n\t\tnBuf++\n\t}\n\n\tfor i := nBuf; i < len(bs); i++ {\n\t\tbs[i].Release()\n\t\tbs[i] = nil\n\t}\n\n\treturn MultiBuffer(bs[:nBuf]), nil\n}\n\n// ReadMultiBuffer implements Reader.\nfunc (r *ReadVReader) ReadMultiBuffer() (MultiBuffer, error) {\n\tif r.alloc.Current() == 1 {\n\t\tb, err := ReadBuffer(r.Reader)\n\t\tif b.IsFull() {\n\t\t\tr.alloc.Adjust(1)\n\t\t}\n\t\treturn MultiBuffer{b}, err\n\t}\n\n\tmb, err := r.readMulti()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tr.alloc.Adjust(uint32(len(mb)))\n\treturn mb, nil\n}\n\nvar useReadv = false\n\nfunc init() {\n\tconst defaultFlagValue = \"NOT_DEFINED_AT_ALL\"\n\tvalue := platform.NewEnvFlag(\"v2ray.buf.readv\").GetValue(func() string { return defaultFlagValue })\n\tswitch value {\n\tcase defaultFlagValue, \"auto\":\n\t\tif (runtime.GOARCH == \"386\" || runtime.GOARCH == \"amd64\" || runtime.GOARCH == \"s390x\") && (runtime.GOOS == \"linux\" || runtime.GOOS == \"darwin\" || runtime.GOOS == \"windows\") {\n\t\t\tuseReadv = true\n\t\t}\n\tcase \"enable\":\n\t\tuseReadv = true\n\t}\n}\n"
  },
  {
    "path": "common/buf/readv_reader_wasm.go",
    "content": "//go:build wasm\n// +build wasm\n\npackage buf\n\nimport (\n\t\"io\"\n\t\"syscall\"\n)\n\nconst useReadv = false\n\nfunc NewReadVReader(reader io.Reader, rawConn syscall.RawConn) Reader {\n\tpanic(\"not implemented\")\n}\n"
  },
  {
    "path": "common/buf/readv_test.go",
    "content": "//go:build !wasm\n// +build !wasm\n\npackage buf_test\n\nimport (\n\t\"crypto/rand\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestReadvReader(t *testing.T) {\n\ttcpServer := &tcp.Server{\n\t\tMsgProcessor: func(b []byte) []byte {\n\t\t\treturn b\n\t\t},\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tconn, err := net.Dial(\"tcp\", dest.NetAddr())\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst size = 8192\n\tdata := make([]byte, 8192)\n\tcommon.Must2(rand.Read(data))\n\n\tvar errg errgroup.Group\n\terrg.Go(func() error {\n\t\twriter := NewWriter(conn)\n\t\tmb := MergeBytes(nil, data)\n\n\t\treturn writer.WriteMultiBuffer(mb)\n\t})\n\n\tdefer func() {\n\t\tif err := errg.Wait(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}()\n\n\trawConn, err := conn.(*net.TCPConn).SyscallConn()\n\tcommon.Must(err)\n\n\treader := NewReadVReader(conn, rawConn)\n\tvar rmb MultiBuffer\n\tfor {\n\t\tmb, err := reader.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\tt.Fatal(\"unexpected error: \", err)\n\t\t}\n\t\trmb, _ = MergeMulti(rmb, mb)\n\t\tif rmb.Len() == size {\n\t\t\tbreak\n\t\t}\n\t}\n\n\trdata := make([]byte, size)\n\tSplitBytes(rmb, rdata)\n\n\tif r := cmp.Diff(data, rdata); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n"
  },
  {
    "path": "common/buf/readv_unix.go",
    "content": "//go:build illumos\n// +build illumos\n\npackage buf\n\nimport \"golang.org/x/sys/unix\"\n\ntype unixReader struct {\n\tiovs [][]byte\n}\n\nfunc (r *unixReader) Init(bs []*Buffer) {\n\tiovs := r.iovs\n\tif iovs == nil {\n\t\tiovs = make([][]byte, 0, len(bs))\n\t}\n\tfor _, b := range bs {\n\t\tiovs = append(iovs, b.v)\n\t}\n\tr.iovs = iovs\n}\n\nfunc (r *unixReader) Read(fd uintptr) int32 {\n\tn, e := unix.Readv(int(fd), r.iovs)\n\tif e != nil {\n\t\treturn -1\n\t}\n\treturn int32(n)\n}\n\nfunc (r *unixReader) Clear() {\n\tr.iovs = r.iovs[:0]\n}\n\nfunc newMultiReader() multiReader {\n\treturn &unixReader{}\n}\n"
  },
  {
    "path": "common/buf/readv_windows.go",
    "content": "package buf\n\nimport (\n\t\"syscall\"\n)\n\ntype windowsReader struct {\n\tbufs []syscall.WSABuf\n}\n\nfunc (r *windowsReader) Init(bs []*Buffer) {\n\tif r.bufs == nil {\n\t\tr.bufs = make([]syscall.WSABuf, 0, len(bs))\n\t}\n\tfor _, b := range bs {\n\t\tr.bufs = append(r.bufs, syscall.WSABuf{Len: uint32(Size), Buf: &b.v[0]})\n\t}\n}\n\nfunc (r *windowsReader) Clear() {\n\tfor idx := range r.bufs {\n\t\tr.bufs[idx].Buf = nil\n\t}\n\tr.bufs = r.bufs[:0]\n}\n\nfunc (r *windowsReader) Read(fd uintptr) int32 {\n\tvar nBytes uint32\n\tvar flags uint32\n\terr := syscall.WSARecv(syscall.Handle(fd), &r.bufs[0], uint32(len(r.bufs)), &nBytes, &flags, nil, nil)\n\tif err != nil {\n\t\treturn -1\n\t}\n\treturn int32(nBytes)\n}\n\nfunc newMultiReader() multiReader {\n\treturn new(windowsReader)\n}\n"
  },
  {
    "path": "common/buf/writer.go",
    "content": "package buf\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n)\n\n// BufferToBytesWriter is a Writer that writes alloc.Buffer into underlying writer.\ntype BufferToBytesWriter struct {\n\tio.Writer\n\n\tcache [][]byte\n}\n\n// WriteMultiBuffer implements Writer. This method takes ownership of the given buffer.\nfunc (w *BufferToBytesWriter) WriteMultiBuffer(mb MultiBuffer) error {\n\tdefer ReleaseMulti(mb)\n\n\tsize := mb.Len()\n\tif size == 0 {\n\t\treturn nil\n\t}\n\n\tif len(mb) == 1 {\n\t\treturn WriteAllBytes(w.Writer, mb[0].Bytes())\n\t}\n\n\tif cap(w.cache) < len(mb) {\n\t\tw.cache = make([][]byte, 0, len(mb))\n\t}\n\n\tbs := w.cache\n\tfor _, b := range mb {\n\t\tbs = append(bs, b.Bytes())\n\t}\n\n\tdefer func() {\n\t\tfor idx := range bs {\n\t\t\tbs[idx] = nil\n\t\t}\n\t}()\n\n\tnb := net.Buffers(bs)\n\n\tfor size > 0 {\n\t\tn, err := nb.WriteTo(w.Writer)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsize -= int32(n)\n\t}\n\n\treturn nil\n}\n\n// ReadFrom implements io.ReaderFrom.\nfunc (w *BufferToBytesWriter) ReadFrom(reader io.Reader) (int64, error) {\n\tvar sc SizeCounter\n\terr := Copy(NewReader(reader), w, CountSize(&sc))\n\treturn sc.Size, err\n}\n\n// BufferedWriter is a Writer with internal buffer.\ntype BufferedWriter struct {\n\tsync.Mutex\n\twriter   Writer\n\tbuffer   *Buffer\n\tbuffered bool\n}\n\n// NewBufferedWriter creates a new BufferedWriter.\nfunc NewBufferedWriter(writer Writer) *BufferedWriter {\n\treturn &BufferedWriter{\n\t\twriter:   writer,\n\t\tbuffer:   New(),\n\t\tbuffered: true,\n\t}\n}\n\n// WriteByte implements io.ByteWriter.\nfunc (w *BufferedWriter) WriteByte(c byte) error {\n\treturn common.Error2(w.Write([]byte{c}))\n}\n\n// Write implements io.Writer.\nfunc (w *BufferedWriter) Write(b []byte) (int, error) {\n\tif len(b) == 0 {\n\t\treturn 0, nil\n\t}\n\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif !w.buffered {\n\t\tif writer, ok := w.writer.(io.Writer); ok {\n\t\t\treturn writer.Write(b)\n\t\t}\n\t}\n\n\ttotalBytes := 0\n\tfor len(b) > 0 {\n\t\tif w.buffer == nil {\n\t\t\tw.buffer = New()\n\t\t}\n\n\t\tnBytes, err := w.buffer.Write(b)\n\t\ttotalBytes += nBytes\n\t\tif err != nil {\n\t\t\treturn totalBytes, err\n\t\t}\n\t\tif !w.buffered || w.buffer.IsFull() {\n\t\t\tif err := w.flushInternal(); err != nil {\n\t\t\t\treturn totalBytes, err\n\t\t\t}\n\t\t}\n\t\tb = b[nBytes:]\n\t}\n\n\treturn totalBytes, nil\n}\n\n// WriteMultiBuffer implements Writer. It takes ownership of the given MultiBuffer.\nfunc (w *BufferedWriter) WriteMultiBuffer(b MultiBuffer) error {\n\tif b.IsEmpty() {\n\t\treturn nil\n\t}\n\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif !w.buffered {\n\t\treturn w.writer.WriteMultiBuffer(b)\n\t}\n\n\treader := MultiBufferContainer{\n\t\tMultiBuffer: b,\n\t}\n\tdefer reader.Close()\n\n\tfor !reader.MultiBuffer.IsEmpty() {\n\t\tif w.buffer == nil {\n\t\t\tw.buffer = New()\n\t\t}\n\t\tcommon.Must2(w.buffer.ReadFrom(&reader))\n\t\tif w.buffer.IsFull() {\n\t\t\tif err := w.flushInternal(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Flush flushes buffered content into underlying writer.\nfunc (w *BufferedWriter) Flush() error {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\treturn w.flushInternal()\n}\n\nfunc (w *BufferedWriter) flushInternal() error {\n\tif w.buffer.IsEmpty() {\n\t\treturn nil\n\t}\n\n\tb := w.buffer\n\tw.buffer = nil\n\n\tif writer, ok := w.writer.(io.Writer); ok {\n\t\terr := WriteAllBytes(writer, b.Bytes())\n\t\tb.Release()\n\t\treturn err\n\t}\n\n\treturn w.writer.WriteMultiBuffer(MultiBuffer{b})\n}\n\n// SetBuffered sets whether the internal buffer is used. If set to false, Flush() will be called to clear the buffer.\nfunc (w *BufferedWriter) SetBuffered(f bool) error {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tw.buffered = f\n\tif !f {\n\t\treturn w.flushInternal()\n\t}\n\treturn nil\n}\n\n// ReadFrom implements io.ReaderFrom.\nfunc (w *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {\n\tif err := w.SetBuffered(false); err != nil {\n\t\treturn 0, err\n\t}\n\n\tvar sc SizeCounter\n\terr := Copy(NewReader(reader), w, CountSize(&sc))\n\treturn sc.Size, err\n}\n\n// Close implements io.Closable.\nfunc (w *BufferedWriter) Close() error {\n\tif err := w.Flush(); err != nil {\n\t\treturn err\n\t}\n\treturn common.Close(w.writer)\n}\n\n// SequentialWriter is a Writer that writes MultiBuffer sequentially into the underlying io.Writer.\ntype SequentialWriter struct {\n\tio.Writer\n}\n\n// WriteMultiBuffer implements Writer.\nfunc (w *SequentialWriter) WriteMultiBuffer(mb MultiBuffer) error {\n\tmb, err := WriteMultiBuffer(w.Writer, mb)\n\tReleaseMulti(mb)\n\treturn err\n}\n\ntype noOpWriter byte\n\nfunc (noOpWriter) WriteMultiBuffer(b MultiBuffer) error {\n\tReleaseMulti(b)\n\treturn nil\n}\n\nfunc (noOpWriter) Write(b []byte) (int, error) {\n\treturn len(b), nil\n}\n\nfunc (noOpWriter) ReadFrom(reader io.Reader) (int64, error) {\n\tb := New()\n\tdefer b.Release()\n\n\ttotalBytes := int64(0)\n\tfor {\n\t\tb.Clear()\n\t\t_, err := b.ReadFrom(reader)\n\t\ttotalBytes += int64(b.Len())\n\t\tif err != nil {\n\t\t\tif errors.Cause(err) == io.EOF {\n\t\t\t\treturn totalBytes, nil\n\t\t\t}\n\t\t\treturn totalBytes, err\n\t\t}\n\t}\n}\n\nvar (\n\t// Discard is a Writer that swallows all contents written in.\n\tDiscard Writer = noOpWriter(0)\n\n\t// DiscardBytes is an io.Writer that swallows all contents written in.\n\tDiscardBytes io.Writer = noOpWriter(0)\n)\n"
  },
  {
    "path": "common/buf/writer_test.go",
    "content": "package buf_test\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc TestWriter(t *testing.T) {\n\tlb := New()\n\tcommon.Must2(lb.ReadFrom(rand.Reader))\n\n\texpectedBytes := append([]byte(nil), lb.Bytes()...)\n\n\twriteBuffer := bytes.NewBuffer(make([]byte, 0, 1024*1024))\n\n\twriter := NewBufferedWriter(NewWriter(writeBuffer))\n\twriter.SetBuffered(false)\n\tcommon.Must(writer.WriteMultiBuffer(MultiBuffer{lb}))\n\tcommon.Must(writer.Flush())\n\n\tif r := cmp.Diff(expectedBytes, writeBuffer.Bytes()); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestBytesWriterReadFrom(t *testing.T) {\n\tconst size = 50000\n\tpReader, pWriter := pipe.New(pipe.WithSizeLimit(size))\n\treader := bufio.NewReader(io.LimitReader(rand.Reader, size))\n\twriter := NewBufferedWriter(pWriter)\n\twriter.SetBuffered(false)\n\tnBytes, err := reader.WriteTo(writer)\n\tif nBytes != size {\n\t\tt.Fatal(\"unexpected size of bytes written: \", nBytes)\n\t}\n\tif err != nil {\n\t\tt.Fatal(\"expect success, but actually error: \", err.Error())\n\t}\n\n\tmb, err := pReader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif mb.Len() != size {\n\t\tt.Fatal(\"unexpected size read: \", mb.Len())\n\t}\n}\n\nfunc TestDiscardBytes(t *testing.T) {\n\tb := New()\n\tcommon.Must2(b.ReadFullFrom(rand.Reader, Size))\n\n\tnBytes, err := io.Copy(DiscardBytes, b)\n\tcommon.Must(err)\n\tif nBytes != Size {\n\t\tt.Error(\"copy size: \", nBytes)\n\t}\n}\n\nfunc TestDiscardBytesMultiBuffer(t *testing.T) {\n\tconst size = 10240*1024 + 1\n\tbuffer := bytes.NewBuffer(make([]byte, 0, size))\n\tcommon.Must2(buffer.ReadFrom(io.LimitReader(rand.Reader, size)))\n\n\tr := NewReader(buffer)\n\tnBytes, err := io.Copy(DiscardBytes, &BufferedReader{Reader: r})\n\tcommon.Must(err)\n\tif nBytes != size {\n\t\tt.Error(\"copy size: \", nBytes)\n\t}\n}\n\nfunc TestWriterInterface(t *testing.T) {\n\t{\n\t\tvar writer interface{} = (*BufferToBytesWriter)(nil)\n\t\tswitch writer.(type) {\n\t\tcase Writer, io.Writer, io.ReaderFrom:\n\t\tdefault:\n\t\t\tt.Error(\"BufferToBytesWriter is not Writer, io.Writer or io.ReaderFrom\")\n\t\t}\n\t}\n\n\t{\n\t\tvar writer interface{} = (*BufferedWriter)(nil)\n\t\tswitch writer.(type) {\n\t\tcase Writer, io.Writer, io.ReaderFrom, io.ByteWriter:\n\t\tdefault:\n\t\t\tt.Error(\"BufferedWriter is not Writer, io.Writer, io.ReaderFrom or io.ByteWriter\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/bytespool/pool.go",
    "content": "package bytespool\n\nimport \"sync\"\n\nfunc createAllocFunc(size int32) func() interface{} {\n\treturn func() interface{} {\n\t\treturn make([]byte, size)\n\t}\n}\n\n// The following parameters controls the size of buffer pools.\n// There are numPools pools. Starting from 2k size, the size of each pool is sizeMulti of the previous one.\n// Package buf is guaranteed to not use buffers larger than the largest pool.\n// Other packets may use larger buffers.\nconst (\n\tnumPools  = 4\n\tsizeMulti = 4\n)\n\nvar (\n\tpool     [numPools]sync.Pool\n\tpoolSize [numPools]int32\n)\n\nfunc init() {\n\tsize := int32(2048)\n\tfor i := 0; i < numPools; i++ {\n\t\tpool[i] = sync.Pool{\n\t\t\tNew: createAllocFunc(size),\n\t\t}\n\t\tpoolSize[i] = size\n\t\tsize *= sizeMulti\n\t}\n}\n\n// GetPool returns a sync.Pool that generates bytes array with at least the given size.\n// It may return nil if no such pool exists.\n//\n// v2ray:api:stable\nfunc GetPool(size int32) *sync.Pool {\n\tfor idx, ps := range poolSize {\n\t\tif size <= ps {\n\t\t\treturn &pool[idx]\n\t\t}\n\t}\n\treturn nil\n}\n\n// Alloc returns a byte slice with at least the given size. Minimum size of returned slice is 2048.\n//\n// v2ray:api:stable\nfunc Alloc(size int32) []byte {\n\tpool := GetPool(size)\n\tif pool != nil {\n\t\treturn pool.Get().([]byte)\n\t}\n\treturn make([]byte, size)\n}\n\n// Free puts a byte slice into the internal pool.\n//\n// v2ray:api:stable\nfunc Free(b []byte) {\n\tsize := int32(cap(b))\n\tb = b[0:cap(b)]\n\tfor i := numPools - 1; i >= 0; i-- {\n\t\tif size >= poolSize[i] {\n\t\t\tpool[i].Put(b) // nolint: staticcheck\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/cache/lru.go",
    "content": "package cache\n\nimport (\n\t\"container/list\"\n\t\"sync\"\n)\n\n// Lru simple, fast lru cache implementation\ntype Lru interface {\n\tGet(key interface{}) (value interface{}, ok bool)\n\tGetKeyFromValue(value interface{}) (key interface{}, ok bool)\n\tPut(key, value interface{})\n}\n\ntype lru struct {\n\tcapacity         int\n\tdoubleLinkedlist *list.List\n\tkeyToElement     *sync.Map\n\tvalueToElement   *sync.Map\n\tmu               *sync.Mutex\n}\n\ntype lruElement struct {\n\tkey   interface{}\n\tvalue interface{}\n}\n\n// NewLru initializes a lru cache\nfunc NewLru(cap int) Lru {\n\treturn &lru{\n\t\tcapacity:         cap,\n\t\tdoubleLinkedlist: list.New(),\n\t\tkeyToElement:     new(sync.Map),\n\t\tvalueToElement:   new(sync.Map),\n\t\tmu:               new(sync.Mutex),\n\t}\n}\n\nfunc (l *lru) Get(key interface{}) (value interface{}, ok bool) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif v, ok := l.keyToElement.Load(key); ok {\n\t\telement := v.(*list.Element)\n\t\tl.doubleLinkedlist.MoveToFront(element)\n\t\treturn element.Value.(*lruElement).value, true\n\t}\n\treturn nil, false\n}\n\nfunc (l *lru) GetKeyFromValue(value interface{}) (key interface{}, ok bool) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif k, ok := l.valueToElement.Load(value); ok {\n\t\telement := k.(*list.Element)\n\t\tl.doubleLinkedlist.MoveToFront(element)\n\t\treturn element.Value.(*lruElement).key, true\n\t}\n\treturn nil, false\n}\n\nfunc (l *lru) Put(key, value interface{}) {\n\tl.mu.Lock()\n\te := &lruElement{key, value}\n\tif v, ok := l.keyToElement.Load(key); ok {\n\t\telement := v.(*list.Element)\n\t\telement.Value = e\n\t\tl.doubleLinkedlist.MoveToFront(element)\n\t} else {\n\t\telement := l.doubleLinkedlist.PushFront(e)\n\t\tl.keyToElement.Store(key, element)\n\t\tl.valueToElement.Store(value, element)\n\t\tif l.doubleLinkedlist.Len() > l.capacity {\n\t\t\ttoBeRemove := l.doubleLinkedlist.Back()\n\t\t\tl.doubleLinkedlist.Remove(toBeRemove)\n\t\t\tl.keyToElement.Delete(toBeRemove.Value.(*lruElement).key)\n\t\t\tl.valueToElement.Delete(toBeRemove.Value.(*lruElement).value)\n\t\t}\n\t}\n\tl.mu.Unlock()\n}\n"
  },
  {
    "path": "common/cache/lru_test.go",
    "content": "package cache_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/cache\"\n)\n\nfunc TestLruReplaceValue(t *testing.T) {\n\tlru := NewLru(2)\n\tlru.Put(2, 6)\n\tlru.Put(1, 5)\n\tlru.Put(1, 2)\n\tv, _ := lru.Get(1)\n\tif v != 2 {\n\t\tt.Error(\"should get 2\", v)\n\t}\n\tv, _ = lru.Get(2)\n\tif v != 6 {\n\t\tt.Error(\"should get 6\", v)\n\t}\n}\n\nfunc TestLruRemoveOld(t *testing.T) {\n\tlru := NewLru(2)\n\tv, ok := lru.Get(2)\n\tif ok {\n\t\tt.Error(\"should get nil\", v)\n\t}\n\tlru.Put(1, 1)\n\tlru.Put(2, 2)\n\tv, _ = lru.Get(1)\n\tif v != 1 {\n\t\tt.Error(\"should get 1\", v)\n\t}\n\tlru.Put(3, 3)\n\tv, ok = lru.Get(2)\n\tif ok {\n\t\tt.Error(\"should get nil\", v)\n\t}\n\tlru.Put(4, 4)\n\tv, ok = lru.Get(1)\n\tif ok {\n\t\tt.Error(\"should get nil\", v)\n\t}\n\tv, _ = lru.Get(3)\n\tif v != 3 {\n\t\tt.Error(\"should get 3\", v)\n\t}\n\tv, _ = lru.Get(4)\n\tif v != 4 {\n\t\tt.Error(\"should get 4\", v)\n\t}\n}\n\nfunc TestGetKeyFromValue(t *testing.T) {\n\tlru := NewLru(2)\n\tlru.Put(3, 3)\n\tlru.Put(2, 2)\n\tlru.Put(1, 1)\n\tv, ok := lru.GetKeyFromValue(3)\n\tif ok {\n\t\tt.Error(\"should get nil\", v)\n\t}\n\tv, _ = lru.GetKeyFromValue(2)\n\tif v != 2 {\n\t\tt.Error(\"should get 2\", v)\n\t}\n}\n"
  },
  {
    "path": "common/cmdarg/arg.go",
    "content": "package cmdarg\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"os\"\n)\n\n// LoadArg loads one arg, maybe an remote url, or local file path\nfunc LoadArg(arg string) (out io.Reader, err error) {\n\tbs, err := LoadArgToBytes(arg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout = bytes.NewBuffer(bs)\n\treturn\n}\n\n// LoadArgToBytes loads one arg to []byte, maybe an remote url, or local file path\nfunc LoadArgToBytes(arg string) (out []byte, err error) {\n\tout, err = os.ReadFile(arg)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn\n}\n"
  },
  {
    "path": "common/cmdarg/cmdarg.go",
    "content": "package cmdarg\n\nimport \"strings\"\n\n// Arg is used by flag to accept multiple argument.\ntype Arg []string\n\nfunc (c *Arg) String() string {\n\treturn strings.Join([]string(*c), \" \")\n}\n\n// Set is the method flag package calls\nfunc (c *Arg) Set(value string) error {\n\t*c = append(*c, value)\n\treturn nil\n}\n"
  },
  {
    "path": "common/cmdarg/errors.generated.go",
    "content": "package cmdarg\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/common.go",
    "content": "// Package common contains common utilities that are shared among other packages.\n// See each sub-package for detail.\npackage common\n\nimport (\n\t\"fmt\"\n\t\"go/build\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\n// ErrNoClue is for the situation that existing information is not enough to make a decision. For example, Router may return this error when there is no suitable route.\nvar ErrNoClue = errors.New(\"not enough information for making a decision\")\n\n// Must panics if err is not nil.\nfunc Must(err error) {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\n// Must2 panics if the second parameter is not nil, otherwise returns the first parameter.\nfunc Must2(v interface{}, err error) interface{} {\n\tMust(err)\n\treturn v\n}\n\n// Error2 returns the err from the 2nd parameter.\nfunc Error2(v interface{}, err error) error {\n\treturn err\n}\n\n// envFile returns the name of the Go environment configuration file.\n// Copy from https://github.com/golang/go/blob/c4f2a9788a7be04daf931ac54382fbe2cb754938/src/cmd/go/internal/cfg/cfg.go#L150-L166\nfunc envFile() (string, error) {\n\tif file := os.Getenv(\"GOENV\"); file != \"\" {\n\t\tif file == \"off\" {\n\t\t\treturn \"\", fmt.Errorf(\"GOENV=off\")\n\t\t}\n\t\treturn file, nil\n\t}\n\tdir, err := os.UserConfigDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif dir == \"\" {\n\t\treturn \"\", fmt.Errorf(\"missing user-config dir\")\n\t}\n\treturn filepath.Join(dir, \"go\", \"env\"), nil\n}\n\n// GetRuntimeEnv returns the value of runtime environment variable,\n// that is set by running following command: `go env -w key=value`.\nfunc GetRuntimeEnv(key string) (string, error) {\n\tfile, err := envFile()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif file == \"\" {\n\t\treturn \"\", fmt.Errorf(\"missing runtime env file\")\n\t}\n\tvar data []byte\n\tvar runtimeEnv string\n\tdata, readErr := os.ReadFile(file)\n\tif readErr != nil {\n\t\treturn \"\", readErr\n\t}\n\tenvStrings := strings.Split(string(data), \"\\n\")\n\tfor _, envItem := range envStrings {\n\t\tenvItem = strings.TrimSuffix(envItem, \"\\r\")\n\t\tenvKeyValue := strings.Split(envItem, \"=\")\n\t\tif strings.EqualFold(strings.TrimSpace(envKeyValue[0]), key) {\n\t\t\truntimeEnv = strings.TrimSpace(envKeyValue[1])\n\t\t}\n\t}\n\treturn runtimeEnv, nil\n}\n\n// GetGOBIN returns GOBIN environment variable as a string. It will NOT be empty.\nfunc GetGOBIN() string {\n\t// The one set by user explicitly by `export GOBIN=/path` or `env GOBIN=/path command`\n\tGOBIN := os.Getenv(\"GOBIN\")\n\tif GOBIN == \"\" {\n\t\tvar err error\n\t\t// The one set by user by running `go env -w GOBIN=/path`\n\t\tGOBIN, err = GetRuntimeEnv(\"GOBIN\")\n\t\tif err != nil {\n\t\t\t// The default one that Golang uses\n\t\t\treturn filepath.Join(build.Default.GOPATH, \"bin\")\n\t\t}\n\t\tif GOBIN == \"\" {\n\t\t\treturn filepath.Join(build.Default.GOPATH, \"bin\")\n\t\t}\n\t\treturn GOBIN\n\t}\n\treturn GOBIN\n}\n\n// GetGOPATH returns GOPATH environment variable as a string. It will NOT be empty.\nfunc GetGOPATH() string {\n\t// The one set by user explicitly by `export GOPATH=/path` or `env GOPATH=/path command`\n\tGOPATH := os.Getenv(\"GOPATH\")\n\tif GOPATH == \"\" {\n\t\tvar err error\n\t\t// The one set by user by running `go env -w GOPATH=/path`\n\t\tGOPATH, err = GetRuntimeEnv(\"GOPATH\")\n\t\tif err != nil {\n\t\t\t// The default one that Golang uses\n\t\t\treturn build.Default.GOPATH\n\t\t}\n\t\tif GOPATH == \"\" {\n\t\t\treturn build.Default.GOPATH\n\t\t}\n\t\treturn GOPATH\n\t}\n\treturn GOPATH\n}\n\n// FetchHTTPContent dials http(s) for remote content\nfunc FetchHTTPContent(target string) ([]byte, error) {\n\tparsedTarget, err := url.Parse(target)\n\tif err != nil {\n\t\treturn nil, newError(\"invalid URL: \", target).Base(err)\n\t}\n\n\tif s := strings.ToLower(parsedTarget.Scheme); s != \"http\" && s != \"https\" {\n\t\treturn nil, newError(\"invalid scheme: \", parsedTarget.Scheme)\n\t}\n\n\tclient := &http.Client{\n\t\tTimeout: 30 * time.Second,\n\t}\n\tresp, err := client.Do(&http.Request{\n\t\tMethod: \"GET\",\n\t\tURL:    parsedTarget,\n\t\tClose:  true,\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial to \", target).Base(err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, newError(\"unexpected HTTP status code: \", resp.StatusCode)\n\t}\n\n\tcontent, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read HTTP response\").Base(err)\n\t}\n\n\treturn content, nil\n}\n"
  },
  {
    "path": "common/common_test.go",
    "content": "package common_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc TestMust(t *testing.T) {\n\thasPanic := func(f func()) (ret bool) {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\tret = true\n\t\t\t}\n\t\t}()\n\t\tf()\n\t\treturn false\n\t}\n\n\ttestCases := []struct {\n\t\tInput func()\n\t\tPanic bool\n\t}{\n\t\t{\n\t\t\tPanic: true,\n\t\t\tInput: func() { Must(func() error { return errors.New(\"test error\") }()) },\n\t\t},\n\t\t{\n\t\t\tPanic: true,\n\t\t\tInput: func() { Must2(func() (int, error) { return 0, errors.New(\"test error\") }()) },\n\t\t},\n\t\t{\n\t\t\tPanic: false,\n\t\t\tInput: func() { Must(func() error { return nil }()) },\n\t\t},\n\t}\n\n\tfor idx, test := range testCases {\n\t\tif hasPanic(test.Input) != test.Panic {\n\t\t\tt.Error(\"test case #\", idx, \" expect panic \", test.Panic, \" but actually not\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/crypto/aes.go",
    "content": "package crypto\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n// NewAesDecryptionStream creates a new AES encryption stream based on given key and IV.\n// Caller must ensure the length of key and IV is either 16, 24 or 32 bytes.\nfunc NewAesDecryptionStream(key []byte, iv []byte) cipher.Stream {\n\treturn NewAesStreamMethod(key, iv, cipher.NewCFBDecrypter)\n}\n\n// NewAesEncryptionStream creates a new AES description stream based on given key and IV.\n// Caller must ensure the length of key and IV is either 16, 24 or 32 bytes.\nfunc NewAesEncryptionStream(key []byte, iv []byte) cipher.Stream {\n\treturn NewAesStreamMethod(key, iv, cipher.NewCFBEncrypter)\n}\n\nfunc NewAesStreamMethod(key []byte, iv []byte, f func(cipher.Block, []byte) cipher.Stream) cipher.Stream {\n\taesBlock, err := aes.NewCipher(key)\n\tcommon.Must(err)\n\treturn f(aesBlock, iv)\n}\n\n// NewAesCTRStream creates a stream cipher based on AES-CTR.\nfunc NewAesCTRStream(key []byte, iv []byte) cipher.Stream {\n\treturn NewAesStreamMethod(key, iv, cipher.NewCTR)\n}\n\n// NewAesGcm creates a AEAD cipher based on AES-GCM.\nfunc NewAesGcm(key []byte) cipher.AEAD {\n\tblock, err := aes.NewCipher(key)\n\tcommon.Must(err)\n\taead, err := cipher.NewGCM(block)\n\tcommon.Must(err)\n\treturn aead\n}\n"
  },
  {
    "path": "common/crypto/auth.go",
    "content": "package crypto\n\nimport (\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/bytespool\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\ntype BytesGenerator func() []byte\n\nfunc GenerateEmptyBytes() BytesGenerator {\n\tvar b [1]byte\n\treturn func() []byte {\n\t\treturn b[:0]\n\t}\n}\n\nfunc GenerateStaticBytes(content []byte) BytesGenerator {\n\treturn func() []byte {\n\t\treturn content\n\t}\n}\n\nfunc GenerateIncreasingNonce(nonce []byte) BytesGenerator {\n\tc := append([]byte(nil), nonce...)\n\treturn func() []byte {\n\t\tfor i := range c {\n\t\t\tc[i]++\n\t\t\tif c[i] != 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn c\n\t}\n}\n\nfunc GenerateInitialAEADNonce() BytesGenerator {\n\treturn GenerateIncreasingNonce([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})\n}\n\ntype Authenticator interface {\n\tNonceSize() int\n\tOverhead() int\n\tOpen(dst, cipherText []byte) ([]byte, error)\n\tSeal(dst, plainText []byte) ([]byte, error)\n}\n\ntype AEADAuthenticator struct {\n\tcipher.AEAD\n\tNonceGenerator          BytesGenerator\n\tAdditionalDataGenerator BytesGenerator\n}\n\nfunc (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) {\n\tiv := v.NonceGenerator()\n\tif len(iv) != v.AEAD.NonceSize() {\n\t\treturn nil, newError(\"invalid AEAD nonce size: \", len(iv))\n\t}\n\n\tvar additionalData []byte\n\tif v.AdditionalDataGenerator != nil {\n\t\tadditionalData = v.AdditionalDataGenerator()\n\t}\n\treturn v.AEAD.Open(dst, iv, cipherText, additionalData)\n}\n\nfunc (v *AEADAuthenticator) Seal(dst, plainText []byte) ([]byte, error) {\n\tiv := v.NonceGenerator()\n\tif len(iv) != v.AEAD.NonceSize() {\n\t\treturn nil, newError(\"invalid AEAD nonce size: \", len(iv))\n\t}\n\n\tvar additionalData []byte\n\tif v.AdditionalDataGenerator != nil {\n\t\tadditionalData = v.AdditionalDataGenerator()\n\t}\n\treturn v.AEAD.Seal(dst, iv, plainText, additionalData), nil\n}\n\ntype AuthenticationReader struct {\n\tauth         Authenticator\n\treader       *buf.BufferedReader\n\tsizeParser   ChunkSizeDecoder\n\tsizeBytes    []byte\n\ttransferType protocol.TransferType\n\tpadding      PaddingLengthGenerator\n\tsize         uint16\n\tsizeOffset   uint16\n\tpaddingLen   uint16\n\thasSize      bool\n\tdone         bool\n}\n\nfunc NewAuthenticationReader(auth Authenticator, sizeParser ChunkSizeDecoder, reader io.Reader, transferType protocol.TransferType, paddingLen PaddingLengthGenerator) *AuthenticationReader {\n\tr := &AuthenticationReader{\n\t\tauth:         auth,\n\t\tsizeParser:   sizeParser,\n\t\ttransferType: transferType,\n\t\tpadding:      paddingLen,\n\t\tsizeBytes:    make([]byte, sizeParser.SizeBytes()),\n\t}\n\tif chunkSizeDecoderWithOffset, ok := sizeParser.(ChunkSizeDecoderWithOffset); ok {\n\t\tr.sizeOffset = chunkSizeDecoderWithOffset.HasConstantOffset()\n\t}\n\tif breader, ok := reader.(*buf.BufferedReader); ok {\n\t\tr.reader = breader\n\t} else {\n\t\tr.reader = &buf.BufferedReader{Reader: buf.NewReader(reader)}\n\t}\n\treturn r\n}\n\nfunc (r *AuthenticationReader) readSize() (uint16, uint16, error) {\n\tif r.hasSize {\n\t\tr.hasSize = false\n\t\treturn r.size, r.paddingLen, nil\n\t}\n\tif _, err := io.ReadFull(r.reader, r.sizeBytes); err != nil {\n\t\treturn 0, 0, err\n\t}\n\tvar padding uint16\n\tif r.padding != nil {\n\t\tpadding = r.padding.NextPaddingLen()\n\t}\n\tsize, err := r.sizeParser.Decode(r.sizeBytes)\n\treturn size, padding, err\n}\n\nvar errSoft = newError(\"waiting for more data\")\n\nfunc (r *AuthenticationReader) readBuffer(size int32, padding int32) (*buf.Buffer, error) {\n\tb := buf.New()\n\tif _, err := b.ReadFullFrom(r.reader, size); err != nil {\n\t\tb.Release()\n\t\treturn nil, err\n\t}\n\tsize -= padding\n\trb, err := r.auth.Open(b.BytesTo(0), b.BytesTo(size))\n\tif err != nil {\n\t\tb.Release()\n\t\treturn nil, err\n\t}\n\tb.Resize(0, int32(len(rb)))\n\treturn b, nil\n}\n\nfunc (r *AuthenticationReader) readInternal(soft bool, mb *buf.MultiBuffer) error {\n\tif soft && r.reader.BufferedBytes() < r.sizeParser.SizeBytes() {\n\t\treturn errSoft\n\t}\n\n\tif r.done {\n\t\treturn io.EOF\n\t}\n\n\tsize, padding, err := r.readSize()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif size+r.sizeOffset == uint16(r.auth.Overhead())+padding {\n\t\tr.done = true\n\t\treturn io.EOF\n\t}\n\n\teffectiveSize := int32(size) + int32(r.sizeOffset)\n\n\tif soft && effectiveSize > r.reader.BufferedBytes() {\n\t\tr.size = size\n\t\tr.paddingLen = padding\n\t\tr.hasSize = true\n\t\treturn errSoft\n\t}\n\n\tif effectiveSize <= buf.Size {\n\t\tb, err := r.readBuffer(effectiveSize, int32(padding))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*mb = append(*mb, b)\n\t\treturn nil\n\t}\n\n\tpayload := bytespool.Alloc(effectiveSize)\n\tdefer bytespool.Free(payload)\n\n\tif _, err := io.ReadFull(r.reader, payload[:effectiveSize]); err != nil {\n\t\treturn err\n\t}\n\n\teffectiveSize -= int32(padding)\n\n\trb, err := r.auth.Open(payload[:0], payload[:effectiveSize])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*mb = buf.MergeBytes(*mb, rb)\n\treturn nil\n}\n\nfunc (r *AuthenticationReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tconst readSize = 16\n\tmb := make(buf.MultiBuffer, 0, readSize)\n\tif err := r.readInternal(false, &mb); err != nil {\n\t\tbuf.ReleaseMulti(mb)\n\t\treturn nil, err\n\t}\n\n\tfor i := 1; i < readSize; i++ {\n\t\terr := r.readInternal(true, &mb)\n\t\tif err == errSoft || err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn mb, nil\n}\n\ntype AuthenticationWriter struct {\n\tauth         Authenticator\n\twriter       buf.Writer\n\tsizeParser   ChunkSizeEncoder\n\ttransferType protocol.TransferType\n\tpadding      PaddingLengthGenerator\n}\n\nfunc NewAuthenticationWriter(auth Authenticator, sizeParser ChunkSizeEncoder, writer io.Writer, transferType protocol.TransferType, padding PaddingLengthGenerator) *AuthenticationWriter {\n\tw := &AuthenticationWriter{\n\t\tauth:         auth,\n\t\twriter:       buf.NewWriter(writer),\n\t\tsizeParser:   sizeParser,\n\t\ttransferType: transferType,\n\t}\n\tif padding != nil {\n\t\tw.padding = padding\n\t}\n\treturn w\n}\n\nfunc (w *AuthenticationWriter) seal(b []byte) (*buf.Buffer, error) {\n\tencryptedSize := int32(len(b) + w.auth.Overhead())\n\tvar paddingSize int32\n\tif w.padding != nil {\n\t\tpaddingSize = int32(w.padding.NextPaddingLen())\n\t}\n\n\tsizeBytes := w.sizeParser.SizeBytes()\n\ttotalSize := sizeBytes + encryptedSize + paddingSize\n\tif totalSize > buf.Size {\n\t\treturn nil, newError(\"size too large: \", totalSize)\n\t}\n\n\teb := buf.New()\n\tw.sizeParser.Encode(uint16(encryptedSize+paddingSize), eb.Extend(sizeBytes))\n\tif _, err := w.auth.Seal(eb.Extend(encryptedSize)[:0], b); err != nil {\n\t\teb.Release()\n\t\treturn nil, err\n\t}\n\tif paddingSize > 0 {\n\t\t// These paddings will send in clear text.\n\t\t// To avoid leakage of PRNG internal state, a cryptographically secure PRNG should be used.\n\t\tpaddingBytes := eb.Extend(paddingSize)\n\t\tcommon.Must2(rand.Read(paddingBytes))\n\t}\n\n\treturn eb, nil\n}\n\nfunc (w *AuthenticationWriter) writeStream(mb buf.MultiBuffer) error {\n\tdefer buf.ReleaseMulti(mb)\n\n\tvar maxPadding int32\n\tif w.padding != nil {\n\t\tmaxPadding = int32(w.padding.MaxPaddingLen())\n\t}\n\n\tpayloadSize := buf.Size - int32(w.auth.Overhead()) - w.sizeParser.SizeBytes() - maxPadding\n\tif len(mb)+10 > 64*1024*1024 {\n\t\treturn errors.New(\"value too large\")\n\t}\n\tsliceSize := len(mb) + 10\n\tmb2Write := make(buf.MultiBuffer, 0, sliceSize)\n\n\ttemp := buf.New()\n\tdefer temp.Release()\n\n\trawBytes := temp.Extend(payloadSize)\n\n\tfor {\n\t\tnb, nBytes := buf.SplitBytes(mb, rawBytes)\n\t\tmb = nb\n\n\t\teb, err := w.seal(rawBytes[:nBytes])\n\t\tif err != nil {\n\t\t\tbuf.ReleaseMulti(mb2Write)\n\t\t\treturn err\n\t\t}\n\t\tmb2Write = append(mb2Write, eb)\n\t\tif mb.IsEmpty() {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn w.writer.WriteMultiBuffer(mb2Write)\n}\n\nfunc (w *AuthenticationWriter) writePacket(mb buf.MultiBuffer) error {\n\tdefer buf.ReleaseMulti(mb)\n\n\tif len(mb)+1 > 64*1024*1024 {\n\t\treturn errors.New(\"value too large\")\n\t}\n\tsliceSize := len(mb) + 1\n\tmb2Write := make(buf.MultiBuffer, 0, sliceSize)\n\n\tfor _, b := range mb {\n\t\tif b.IsEmpty() {\n\t\t\tcontinue\n\t\t}\n\n\t\teb, err := w.seal(b.Bytes())\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tmb2Write = append(mb2Write, eb)\n\t}\n\n\tif mb2Write.IsEmpty() {\n\t\treturn nil\n\t}\n\n\treturn w.writer.WriteMultiBuffer(mb2Write)\n}\n\n// WriteMultiBuffer implements buf.Writer.\nfunc (w *AuthenticationWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tif mb.IsEmpty() {\n\t\teb, err := w.seal([]byte{})\n\t\tcommon.Must(err)\n\t\treturn w.writer.WriteMultiBuffer(buf.MultiBuffer{eb})\n\t}\n\n\tif w.transferType == protocol.TransferTypeStream {\n\t\treturn w.writeStream(mb)\n\t}\n\n\treturn w.writePacket(mb)\n}\n"
  },
  {
    "path": "common/crypto/auth_test.go",
    "content": "package crypto_test\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nfunc TestAuthenticationReaderWriter(t *testing.T) {\n\tkey := make([]byte, 16)\n\trand.Read(key)\n\tblock, err := aes.NewCipher(key)\n\tcommon.Must(err)\n\n\taead, err := cipher.NewGCM(block)\n\tcommon.Must(err)\n\n\tconst payloadSize = 1024 * 80\n\trawPayload := make([]byte, payloadSize)\n\trand.Read(rawPayload)\n\n\tpayload := buf.MergeBytes(nil, rawPayload)\n\n\tcache := bytes.NewBuffer(nil)\n\tiv := make([]byte, 12)\n\trand.Read(iv)\n\n\twriter := NewAuthenticationWriter(&AEADAuthenticator{\n\t\tAEAD:                    aead,\n\t\tNonceGenerator:          GenerateStaticBytes(iv),\n\t\tAdditionalDataGenerator: GenerateEmptyBytes(),\n\t}, PlainChunkSizeParser{}, cache, protocol.TransferTypeStream, nil)\n\n\tcommon.Must(writer.WriteMultiBuffer(payload))\n\tif cache.Len() <= 1024*80 {\n\t\tt.Error(\"cache len: \", cache.Len())\n\t}\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{}))\n\n\treader := NewAuthenticationReader(&AEADAuthenticator{\n\t\tAEAD:                    aead,\n\t\tNonceGenerator:          GenerateStaticBytes(iv),\n\t\tAdditionalDataGenerator: GenerateEmptyBytes(),\n\t}, PlainChunkSizeParser{}, cache, protocol.TransferTypeStream, nil)\n\n\tvar mb buf.MultiBuffer\n\n\tfor mb.Len() < payloadSize {\n\t\tmb2, err := reader.ReadMultiBuffer()\n\t\tcommon.Must(err)\n\n\t\tmb, _ = buf.MergeMulti(mb, mb2)\n\t}\n\n\tif mb.Len() != payloadSize {\n\t\tt.Error(\"mb len: \", mb.Len())\n\t}\n\n\tmbContent := make([]byte, payloadSize)\n\tbuf.SplitBytes(mb, mbContent)\n\tif r := cmp.Diff(mbContent, rawPayload); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\t_, err = reader.ReadMultiBuffer()\n\tif err != io.EOF {\n\t\tt.Error(\"error: \", err)\n\t}\n}\n\nfunc TestAuthenticationReaderWriterPacket(t *testing.T) {\n\tkey := make([]byte, 16)\n\tcommon.Must2(rand.Read(key))\n\tblock, err := aes.NewCipher(key)\n\tcommon.Must(err)\n\n\taead, err := cipher.NewGCM(block)\n\tcommon.Must(err)\n\n\tcache := buf.New()\n\tiv := make([]byte, 12)\n\trand.Read(iv)\n\n\twriter := NewAuthenticationWriter(&AEADAuthenticator{\n\t\tAEAD:                    aead,\n\t\tNonceGenerator:          GenerateStaticBytes(iv),\n\t\tAdditionalDataGenerator: GenerateEmptyBytes(),\n\t}, PlainChunkSizeParser{}, cache, protocol.TransferTypePacket, nil)\n\n\tvar payload buf.MultiBuffer\n\tpb1 := buf.New()\n\tpb1.Write([]byte(\"abcd\"))\n\tpayload = append(payload, pb1)\n\n\tpb2 := buf.New()\n\tpb2.Write([]byte(\"efgh\"))\n\tpayload = append(payload, pb2)\n\n\tcommon.Must(writer.WriteMultiBuffer(payload))\n\tif cache.Len() == 0 {\n\t\tt.Error(\"cache len: \", cache.Len())\n\t}\n\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{}))\n\n\treader := NewAuthenticationReader(&AEADAuthenticator{\n\t\tAEAD:                    aead,\n\t\tNonceGenerator:          GenerateStaticBytes(iv),\n\t\tAdditionalDataGenerator: GenerateEmptyBytes(),\n\t}, PlainChunkSizeParser{}, cache, protocol.TransferTypePacket, nil)\n\n\tmb, err := reader.ReadMultiBuffer()\n\tcommon.Must(err)\n\n\tmb, b1 := buf.SplitFirst(mb)\n\tif b1.String() != \"abcd\" {\n\t\tt.Error(\"b1: \", b1.String())\n\t}\n\n\tmb, b2 := buf.SplitFirst(mb)\n\tif b2.String() != \"efgh\" {\n\t\tt.Error(\"b2: \", b2.String())\n\t}\n\n\tif !mb.IsEmpty() {\n\t\tt.Error(\"not empty\")\n\t}\n\n\t_, err = reader.ReadMultiBuffer()\n\tif err != io.EOF {\n\t\tt.Error(\"error: \", err)\n\t}\n}\n"
  },
  {
    "path": "common/crypto/benchmark_test.go",
    "content": "package crypto_test\n\nimport (\n\t\"crypto/cipher\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\nconst benchSize = 1024 * 1024\n\nfunc benchmarkStream(b *testing.B, c cipher.Stream) {\n\tb.SetBytes(benchSize)\n\tinput := make([]byte, benchSize)\n\toutput := make([]byte, benchSize)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tc.XORKeyStream(output, input)\n\t}\n}\n\nfunc BenchmarkChaCha20(b *testing.B) {\n\tkey := make([]byte, 32)\n\tnonce := make([]byte, 8)\n\tc := NewChaCha20Stream(key, nonce)\n\tbenchmarkStream(b, c)\n}\n\nfunc BenchmarkChaCha20IETF(b *testing.B) {\n\tkey := make([]byte, 32)\n\tnonce := make([]byte, 12)\n\tc := NewChaCha20Stream(key, nonce)\n\tbenchmarkStream(b, c)\n}\n\nfunc BenchmarkAESEncryption(b *testing.B) {\n\tkey := make([]byte, 32)\n\tiv := make([]byte, 16)\n\tc := NewAesEncryptionStream(key, iv)\n\n\tbenchmarkStream(b, c)\n}\n\nfunc BenchmarkAESDecryption(b *testing.B) {\n\tkey := make([]byte, 32)\n\tiv := make([]byte, 16)\n\tc := NewAesDecryptionStream(key, iv)\n\n\tbenchmarkStream(b, c)\n}\n"
  },
  {
    "path": "common/crypto/chacha20.go",
    "content": "package crypto\n\nimport (\n\t\"crypto/cipher\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto/internal\"\n)\n\n// NewChaCha20Stream creates a new Chacha20 encryption/descryption stream based on give key and IV.\n// Caller must ensure the length of key is 32 bytes, and length of IV is either 8 or 12 bytes.\nfunc NewChaCha20Stream(key []byte, iv []byte) cipher.Stream {\n\treturn internal.NewChaCha20Stream(key, iv, 20)\n}\n"
  },
  {
    "path": "common/crypto/chacha20_test.go",
    "content": "package crypto_test\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\nfunc mustDecodeHex(s string) []byte {\n\tb, err := hex.DecodeString(s)\n\tcommon.Must(err)\n\treturn b\n}\n\nfunc TestChaCha20Stream(t *testing.T) {\n\tcases := []struct {\n\t\tkey    []byte\n\t\tiv     []byte\n\t\toutput []byte\n\t}{\n\t\t{\n\t\t\tkey: mustDecodeHex(\"0000000000000000000000000000000000000000000000000000000000000000\"),\n\t\t\tiv:  mustDecodeHex(\"0000000000000000\"),\n\t\t\toutput: mustDecodeHex(\"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7\" +\n\t\t\t\t\"da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586\" +\n\t\t\t\t\"9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed\" +\n\t\t\t\t\"29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f\"),\n\t\t},\n\t\t{\n\t\t\tkey: mustDecodeHex(\"5555555555555555555555555555555555555555555555555555555555555555\"),\n\t\t\tiv:  mustDecodeHex(\"5555555555555555\"),\n\t\t\toutput: mustDecodeHex(\"bea9411aa453c5434a5ae8c92862f564396855a9ea6e22d6d3b50ae1b3663311\" +\n\t\t\t\t\"a4a3606c671d605ce16c3aece8e61ea145c59775017bee2fa6f88afc758069f7\" +\n\t\t\t\t\"e0b8f676e644216f4d2a3422d7fa36c6c4931aca950e9da42788e6d0b6d1cd83\" +\n\t\t\t\t\"8ef652e97b145b14871eae6c6804c7004db5ac2fce4c68c726d004b10fcaba86\"),\n\t\t},\n\t\t{\n\t\t\tkey:    mustDecodeHex(\"0000000000000000000000000000000000000000000000000000000000000000\"),\n\t\t\tiv:     mustDecodeHex(\"000000000000000000000000\"),\n\t\t\toutput: mustDecodeHex(\"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586\"),\n\t\t},\n\t}\n\tfor _, c := range cases {\n\t\ts := NewChaCha20Stream(c.key, c.iv)\n\t\tinput := make([]byte, len(c.output))\n\t\tactualOutput := make([]byte, len(c.output))\n\t\ts.XORKeyStream(actualOutput, input)\n\t\tif r := cmp.Diff(c.output, actualOutput); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n}\n\nfunc TestChaCha20Decoding(t *testing.T) {\n\tkey := make([]byte, 32)\n\tcommon.Must2(rand.Read(key))\n\tiv := make([]byte, 8)\n\tcommon.Must2(rand.Read(iv))\n\tstream := NewChaCha20Stream(key, iv)\n\n\tpayload := make([]byte, 1024)\n\tcommon.Must2(rand.Read(payload))\n\n\tx := make([]byte, len(payload))\n\tstream.XORKeyStream(x, payload)\n\n\tstream2 := NewChaCha20Stream(key, iv)\n\tstream2.XORKeyStream(x, x)\n\tif r := cmp.Diff(x, payload); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n"
  },
  {
    "path": "common/crypto/chunk.go",
    "content": "package crypto\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\n// ChunkSizeDecoder is a utility class to decode size value from bytes.\ntype ChunkSizeDecoder interface {\n\t// SizeBytes must be stable, return the same value across all calls\n\tSizeBytes() int32\n\tDecode([]byte) (uint16, error)\n}\n\ntype ChunkSizeDecoderWithOffset interface {\n\tChunkSizeDecoder\n\t// HasConstantOffset set the constant offset of Decode\n\t// The effective size should be HasConstantOffset() + Decode(_).[0](uint64)\n\tHasConstantOffset() uint16\n}\n\n// ChunkSizeEncoder is a utility class to encode size value into bytes.\ntype ChunkSizeEncoder interface {\n\tSizeBytes() int32\n\tEncode(uint16, []byte) []byte\n}\n\ntype PaddingLengthGenerator interface {\n\tMaxPaddingLen() uint16\n\tNextPaddingLen() uint16\n}\n\ntype PlainChunkSizeParser struct{}\n\nfunc (PlainChunkSizeParser) SizeBytes() int32 {\n\treturn 2\n}\n\nfunc (PlainChunkSizeParser) Encode(size uint16, b []byte) []byte {\n\tbinary.BigEndian.PutUint16(b, size)\n\treturn b[:2]\n}\n\nfunc (PlainChunkSizeParser) Decode(b []byte) (uint16, error) {\n\treturn binary.BigEndian.Uint16(b), nil\n}\n\ntype AEADChunkSizeParser struct {\n\tAuth *AEADAuthenticator\n}\n\nfunc (p *AEADChunkSizeParser) SizeBytes() int32 {\n\treturn 2 + int32(p.Auth.Overhead())\n}\n\nfunc (p *AEADChunkSizeParser) Encode(size uint16, b []byte) []byte {\n\tbinary.BigEndian.PutUint16(b, size-uint16(p.Auth.Overhead()))\n\tb, err := p.Auth.Seal(b[:0], b[:2])\n\tcommon.Must(err)\n\treturn b\n}\n\nfunc (p *AEADChunkSizeParser) Decode(b []byte) (uint16, error) {\n\tb, err := p.Auth.Open(b[:0], b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn binary.BigEndian.Uint16(b) + uint16(p.Auth.Overhead()), nil\n}\n\ntype ChunkStreamReader struct {\n\tsizeDecoder ChunkSizeDecoder\n\treader      *buf.BufferedReader\n\n\tbuffer       []byte\n\tleftOverSize int32\n\tmaxNumChunk  uint32\n\tnumChunk     uint32\n}\n\nfunc NewChunkStreamReader(sizeDecoder ChunkSizeDecoder, reader io.Reader) *ChunkStreamReader {\n\treturn NewChunkStreamReaderWithChunkCount(sizeDecoder, reader, 0)\n}\n\nfunc NewChunkStreamReaderWithChunkCount(sizeDecoder ChunkSizeDecoder, reader io.Reader, maxNumChunk uint32) *ChunkStreamReader {\n\tr := &ChunkStreamReader{\n\t\tsizeDecoder: sizeDecoder,\n\t\tbuffer:      make([]byte, sizeDecoder.SizeBytes()),\n\t\tmaxNumChunk: maxNumChunk,\n\t}\n\tif breader, ok := reader.(*buf.BufferedReader); ok {\n\t\tr.reader = breader\n\t} else {\n\t\tr.reader = &buf.BufferedReader{Reader: buf.NewReader(reader)}\n\t}\n\n\treturn r\n}\n\nfunc (r *ChunkStreamReader) readSize() (uint16, error) {\n\tif _, err := io.ReadFull(r.reader, r.buffer); err != nil {\n\t\treturn 0, err\n\t}\n\treturn r.sizeDecoder.Decode(r.buffer)\n}\n\nfunc (r *ChunkStreamReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tsize := r.leftOverSize\n\tif size == 0 {\n\t\tr.numChunk++\n\t\tif r.maxNumChunk > 0 && r.numChunk > r.maxNumChunk {\n\t\t\treturn nil, io.EOF\n\t\t}\n\t\tnextSize, err := r.readSize()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif nextSize == 0 {\n\t\t\treturn nil, io.EOF\n\t\t}\n\t\tsize = int32(nextSize)\n\t}\n\tr.leftOverSize = size\n\n\tmb, err := r.reader.ReadAtMost(size)\n\tif !mb.IsEmpty() {\n\t\tr.leftOverSize -= mb.Len()\n\t\treturn mb, nil\n\t}\n\treturn nil, err\n}\n\ntype ChunkStreamWriter struct {\n\tsizeEncoder ChunkSizeEncoder\n\twriter      buf.Writer\n}\n\nfunc NewChunkStreamWriter(sizeEncoder ChunkSizeEncoder, writer io.Writer) *ChunkStreamWriter {\n\treturn &ChunkStreamWriter{\n\t\tsizeEncoder: sizeEncoder,\n\t\twriter:      buf.NewWriter(writer),\n\t}\n}\n\nfunc (w *ChunkStreamWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tconst sliceSize = 8192\n\tmbLen := mb.Len()\n\tmb2Write := make(buf.MultiBuffer, 0, mbLen/buf.Size+mbLen/sliceSize+2)\n\n\tfor {\n\t\tmb2, slice := buf.SplitSize(mb, sliceSize)\n\t\tmb = mb2\n\n\t\tb := buf.New()\n\t\tw.sizeEncoder.Encode(uint16(slice.Len()), b.Extend(w.sizeEncoder.SizeBytes()))\n\t\tmb2Write = append(mb2Write, b)\n\t\tmb2Write = append(mb2Write, slice...)\n\n\t\tif mb.IsEmpty() {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn w.writer.WriteMultiBuffer(mb2Write)\n}\n"
  },
  {
    "path": "common/crypto/chunk_test.go",
    "content": "package crypto_test\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\nfunc TestChunkStreamIO(t *testing.T) {\n\tcache := bytes.NewBuffer(make([]byte, 0, 8192))\n\n\twriter := NewChunkStreamWriter(PlainChunkSizeParser{}, cache)\n\treader := NewChunkStreamReader(PlainChunkSizeParser{}, cache)\n\n\tb := buf.New()\n\tb.WriteString(\"abcd\")\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{b}))\n\n\tb = buf.New()\n\tb.WriteString(\"efg\")\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{b}))\n\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{}))\n\n\tif cache.Len() != 13 {\n\t\tt.Fatalf(\"Cache length is %d, want 13\", cache.Len())\n\t}\n\n\tmb, err := reader.ReadMultiBuffer()\n\tcommon.Must(err)\n\n\tif s := mb.String(); s != \"abcd\" {\n\t\tt.Error(\"content: \", s)\n\t}\n\n\tmb, err = reader.ReadMultiBuffer()\n\tcommon.Must(err)\n\n\tif s := mb.String(); s != \"efg\" {\n\t\tt.Error(\"content: \", s)\n\t}\n\n\t_, err = reader.ReadMultiBuffer()\n\tif err != io.EOF {\n\t\tt.Error(\"error: \", err)\n\t}\n}\n"
  },
  {
    "path": "common/crypto/crypto.go",
    "content": "// Package crypto provides common crypto libraries for V2Ray.\npackage crypto\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/crypto/errors.generated.go",
    "content": "package crypto\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/crypto/internal/chacha.go",
    "content": "package internal\n\n//go:generate go run chacha_core_gen.go\n\nimport (\n\t\"encoding/binary\"\n)\n\nconst (\n\twordSize  = 4                    // the size of ChaCha20's words\n\tstateSize = 16                   // the size of ChaCha20's state, in words\n\tblockSize = stateSize * wordSize // the size of ChaCha20's block, in bytes\n)\n\ntype ChaCha20Stream struct {\n\tstate  [stateSize]uint32 // the state as an array of 16 32-bit words\n\tblock  [blockSize]byte   // the keystream as an array of 64 bytes\n\toffset int               // the offset of used bytes in block\n\trounds int\n}\n\nfunc NewChaCha20Stream(key []byte, nonce []byte, rounds int) *ChaCha20Stream {\n\ts := new(ChaCha20Stream)\n\t// the magic constants for 256-bit keys\n\ts.state[0] = 0x61707865\n\ts.state[1] = 0x3320646e\n\ts.state[2] = 0x79622d32\n\ts.state[3] = 0x6b206574\n\n\tfor i := 0; i < 8; i++ {\n\t\ts.state[i+4] = binary.LittleEndian.Uint32(key[i*4 : i*4+4])\n\t}\n\n\tswitch len(nonce) {\n\tcase 8:\n\t\ts.state[14] = binary.LittleEndian.Uint32(nonce[0:])\n\t\ts.state[15] = binary.LittleEndian.Uint32(nonce[4:])\n\tcase 12:\n\t\ts.state[13] = binary.LittleEndian.Uint32(nonce[0:4])\n\t\ts.state[14] = binary.LittleEndian.Uint32(nonce[4:8])\n\t\ts.state[15] = binary.LittleEndian.Uint32(nonce[8:12])\n\tdefault:\n\t\tpanic(\"bad nonce length\")\n\t}\n\n\ts.rounds = rounds\n\tChaCha20Block(&s.state, s.block[:], s.rounds)\n\treturn s\n}\n\nfunc (s *ChaCha20Stream) XORKeyStream(dst, src []byte) {\n\t// Stride over the input in 64-byte blocks, minus the amount of keystream\n\t// previously used. This will produce best results when processing blocks\n\t// of a size evenly divisible by 64.\n\ti := 0\n\tmax := len(src)\n\tfor i < max {\n\t\tgap := blockSize - s.offset\n\n\t\tlimit := i + gap\n\t\tif limit > max {\n\t\t\tlimit = max\n\t\t}\n\n\t\to := s.offset\n\t\tfor j := i; j < limit; j++ {\n\t\t\tdst[j] = src[j] ^ s.block[o]\n\t\t\to++\n\t\t}\n\n\t\ti += gap\n\t\ts.offset = o\n\n\t\tif o == blockSize {\n\t\t\ts.offset = 0\n\t\t\ts.state[12]++\n\t\t\tChaCha20Block(&s.state, s.block[:], s.rounds)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/crypto/internal/chacha_core.generated.go",
    "content": "package internal\n\nimport \"encoding/binary\"\n\nfunc ChaCha20Block(s *[16]uint32, out []byte, rounds int) {\n\tx0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]\n\tfor i := 0; i < rounds; i += 2 {\n\t\tvar x uint32\n\n\t\tx0 += x4\n\t\tx = x12 ^ x0\n\t\tx12 = (x << 16) | (x >> (32 - 16))\n\t\tx8 += x12\n\t\tx = x4 ^ x8\n\t\tx4 = (x << 12) | (x >> (32 - 12))\n\t\tx0 += x4\n\t\tx = x12 ^ x0\n\t\tx12 = (x << 8) | (x >> (32 - 8))\n\t\tx8 += x12\n\t\tx = x4 ^ x8\n\t\tx4 = (x << 7) | (x >> (32 - 7))\n\t\tx1 += x5\n\t\tx = x13 ^ x1\n\t\tx13 = (x << 16) | (x >> (32 - 16))\n\t\tx9 += x13\n\t\tx = x5 ^ x9\n\t\tx5 = (x << 12) | (x >> (32 - 12))\n\t\tx1 += x5\n\t\tx = x13 ^ x1\n\t\tx13 = (x << 8) | (x >> (32 - 8))\n\t\tx9 += x13\n\t\tx = x5 ^ x9\n\t\tx5 = (x << 7) | (x >> (32 - 7))\n\t\tx2 += x6\n\t\tx = x14 ^ x2\n\t\tx14 = (x << 16) | (x >> (32 - 16))\n\t\tx10 += x14\n\t\tx = x6 ^ x10\n\t\tx6 = (x << 12) | (x >> (32 - 12))\n\t\tx2 += x6\n\t\tx = x14 ^ x2\n\t\tx14 = (x << 8) | (x >> (32 - 8))\n\t\tx10 += x14\n\t\tx = x6 ^ x10\n\t\tx6 = (x << 7) | (x >> (32 - 7))\n\t\tx3 += x7\n\t\tx = x15 ^ x3\n\t\tx15 = (x << 16) | (x >> (32 - 16))\n\t\tx11 += x15\n\t\tx = x7 ^ x11\n\t\tx7 = (x << 12) | (x >> (32 - 12))\n\t\tx3 += x7\n\t\tx = x15 ^ x3\n\t\tx15 = (x << 8) | (x >> (32 - 8))\n\t\tx11 += x15\n\t\tx = x7 ^ x11\n\t\tx7 = (x << 7) | (x >> (32 - 7))\n\t\tx0 += x5\n\t\tx = x15 ^ x0\n\t\tx15 = (x << 16) | (x >> (32 - 16))\n\t\tx10 += x15\n\t\tx = x5 ^ x10\n\t\tx5 = (x << 12) | (x >> (32 - 12))\n\t\tx0 += x5\n\t\tx = x15 ^ x0\n\t\tx15 = (x << 8) | (x >> (32 - 8))\n\t\tx10 += x15\n\t\tx = x5 ^ x10\n\t\tx5 = (x << 7) | (x >> (32 - 7))\n\t\tx1 += x6\n\t\tx = x12 ^ x1\n\t\tx12 = (x << 16) | (x >> (32 - 16))\n\t\tx11 += x12\n\t\tx = x6 ^ x11\n\t\tx6 = (x << 12) | (x >> (32 - 12))\n\t\tx1 += x6\n\t\tx = x12 ^ x1\n\t\tx12 = (x << 8) | (x >> (32 - 8))\n\t\tx11 += x12\n\t\tx = x6 ^ x11\n\t\tx6 = (x << 7) | (x >> (32 - 7))\n\t\tx2 += x7\n\t\tx = x13 ^ x2\n\t\tx13 = (x << 16) | (x >> (32 - 16))\n\t\tx8 += x13\n\t\tx = x7 ^ x8\n\t\tx7 = (x << 12) | (x >> (32 - 12))\n\t\tx2 += x7\n\t\tx = x13 ^ x2\n\t\tx13 = (x << 8) | (x >> (32 - 8))\n\t\tx8 += x13\n\t\tx = x7 ^ x8\n\t\tx7 = (x << 7) | (x >> (32 - 7))\n\t\tx3 += x4\n\t\tx = x14 ^ x3\n\t\tx14 = (x << 16) | (x >> (32 - 16))\n\t\tx9 += x14\n\t\tx = x4 ^ x9\n\t\tx4 = (x << 12) | (x >> (32 - 12))\n\t\tx3 += x4\n\t\tx = x14 ^ x3\n\t\tx14 = (x << 8) | (x >> (32 - 8))\n\t\tx9 += x14\n\t\tx = x4 ^ x9\n\t\tx4 = (x << 7) | (x >> (32 - 7))\n\t}\n\tbinary.LittleEndian.PutUint32(out[0:4], s[0]+x0)\n\tbinary.LittleEndian.PutUint32(out[4:8], s[1]+x1)\n\tbinary.LittleEndian.PutUint32(out[8:12], s[2]+x2)\n\tbinary.LittleEndian.PutUint32(out[12:16], s[3]+x3)\n\tbinary.LittleEndian.PutUint32(out[16:20], s[4]+x4)\n\tbinary.LittleEndian.PutUint32(out[20:24], s[5]+x5)\n\tbinary.LittleEndian.PutUint32(out[24:28], s[6]+x6)\n\tbinary.LittleEndian.PutUint32(out[28:32], s[7]+x7)\n\tbinary.LittleEndian.PutUint32(out[32:36], s[8]+x8)\n\tbinary.LittleEndian.PutUint32(out[36:40], s[9]+x9)\n\tbinary.LittleEndian.PutUint32(out[40:44], s[10]+x10)\n\tbinary.LittleEndian.PutUint32(out[44:48], s[11]+x11)\n\tbinary.LittleEndian.PutUint32(out[48:52], s[12]+x12)\n\tbinary.LittleEndian.PutUint32(out[52:56], s[13]+x13)\n\tbinary.LittleEndian.PutUint32(out[56:60], s[14]+x14)\n\tbinary.LittleEndian.PutUint32(out[60:64], s[15]+x15)\n}\n"
  },
  {
    "path": "common/crypto/internal/chacha_core_gen.go",
    "content": "//go:build generate\n// +build generate\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc writeQuarterRound(file *os.File, a, b, c, d int) {\n\tadd := \"x%d+=x%d\\n\"\n\txor := \"x=x%d^x%d\\n\"\n\trotate := \"x%d=(x << %d) | (x >> (32 - %d))\\n\"\n\n\tfmt.Fprintf(file, add, a, b)\n\tfmt.Fprintf(file, xor, d, a)\n\tfmt.Fprintf(file, rotate, d, 16, 16)\n\n\tfmt.Fprintf(file, add, c, d)\n\tfmt.Fprintf(file, xor, b, c)\n\tfmt.Fprintf(file, rotate, b, 12, 12)\n\n\tfmt.Fprintf(file, add, a, b)\n\tfmt.Fprintf(file, xor, d, a)\n\tfmt.Fprintf(file, rotate, d, 8, 8)\n\n\tfmt.Fprintf(file, add, c, d)\n\tfmt.Fprintf(file, xor, b, c)\n\tfmt.Fprintf(file, rotate, b, 7, 7)\n}\n\nfunc writeChacha20Block(file *os.File) {\n\tfmt.Fprintln(file, `\nfunc ChaCha20Block(s *[16]uint32, out []byte, rounds int) {\n  var x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15 = s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9],s[10],s[11],s[12],s[13],s[14],s[15]\n\tfor i := 0; i < rounds; i+=2 {\n    var x uint32\n    `)\n\n\twriteQuarterRound(file, 0, 4, 8, 12)\n\twriteQuarterRound(file, 1, 5, 9, 13)\n\twriteQuarterRound(file, 2, 6, 10, 14)\n\twriteQuarterRound(file, 3, 7, 11, 15)\n\twriteQuarterRound(file, 0, 5, 10, 15)\n\twriteQuarterRound(file, 1, 6, 11, 12)\n\twriteQuarterRound(file, 2, 7, 8, 13)\n\twriteQuarterRound(file, 3, 4, 9, 14)\n\tfmt.Fprintln(file, \"}\")\n\tfor i := 0; i < 16; i++ {\n\t\tfmt.Fprintf(file, \"binary.LittleEndian.PutUint32(out[%d:%d], s[%d]+x%d)\\n\", i*4, i*4+4, i, i)\n\t}\n\tfmt.Fprintln(file, \"}\")\n\tfmt.Fprintln(file)\n}\n\nfunc main() {\n\tfile, err := os.OpenFile(\"chacha_core.generated.go\", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o644)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to generate chacha_core.go: %v\", err)\n\t}\n\tdefer file.Close()\n\n\tfmt.Fprintln(file, \"package internal\")\n\tfmt.Fprintln(file)\n\tfmt.Fprintln(file, \"import \\\"encoding/binary\\\"\")\n\tfmt.Fprintln(file)\n\twriteChacha20Block(file)\n}\n"
  },
  {
    "path": "common/crypto/io.go",
    "content": "package crypto\n\nimport (\n\t\"crypto/cipher\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\ntype CryptionReader struct {\n\tstream cipher.Stream\n\treader io.Reader\n}\n\nfunc NewCryptionReader(stream cipher.Stream, reader io.Reader) *CryptionReader {\n\treturn &CryptionReader{\n\t\tstream: stream,\n\t\treader: reader,\n\t}\n}\n\nfunc (r *CryptionReader) Read(data []byte) (int, error) {\n\tnBytes, err := r.reader.Read(data)\n\tif nBytes > 0 {\n\t\tr.stream.XORKeyStream(data[:nBytes], data[:nBytes])\n\t}\n\treturn nBytes, err\n}\n\nvar _ buf.Writer = (*CryptionWriter)(nil)\n\ntype CryptionWriter struct {\n\tstream    cipher.Stream\n\twriter    io.Writer\n\tbufWriter buf.Writer\n}\n\n// NewCryptionWriter creates a new CryptionWriter.\nfunc NewCryptionWriter(stream cipher.Stream, writer io.Writer) *CryptionWriter {\n\treturn &CryptionWriter{\n\t\tstream:    stream,\n\t\twriter:    writer,\n\t\tbufWriter: buf.NewWriter(writer),\n\t}\n}\n\n// Write implements io.Writer.Write().\nfunc (w *CryptionWriter) Write(data []byte) (int, error) {\n\tw.stream.XORKeyStream(data, data)\n\n\tif err := buf.WriteAllBytes(w.writer, data); err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(data), nil\n}\n\n// WriteMultiBuffer implements buf.Writer.\nfunc (w *CryptionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tfor _, b := range mb {\n\t\tw.stream.XORKeyStream(b.Bytes(), b.Bytes())\n\t}\n\n\treturn w.bufWriter.WriteMultiBuffer(mb)\n}\n"
  },
  {
    "path": "common/dice/dice.go",
    "content": "// Package dice contains common functions to generate random number.\n// It also initialize math/rand with the time in seconds at launch time.\npackage dice\n\nimport (\n\tcrand \"crypto/rand\"\n\t\"io\"\n\t\"math/big\"\n\t\"math/rand\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n// Roll returns a non-negative number between 0 (inclusive) and n (exclusive).\nfunc Roll(n int) int {\n\tif n == 1 {\n\t\treturn 0\n\t}\n\treturn rand.Intn(n)\n}\n\n// RollWith returns a non-negative number between 0 (inclusive) and n (exclusive).\n// Use random as the random source, if read fails, it panics.\nfunc RollWith(n int, random io.Reader) int {\n\tif n == 1 {\n\t\treturn 0\n\t}\n\tmrand, err := crand.Int(random, big.NewInt(int64(n)))\n\tcommon.Must(err)\n\treturn int(mrand.Int64())\n}\n\n// Roll returns a non-negative number between 0 (inclusive) and n (exclusive).\nfunc RollDeterministic(n int, seed int64) int {\n\tif n == 1 {\n\t\treturn 0\n\t}\n\treturn rand.New(rand.NewSource(seed)).Intn(n)\n}\n\n// RollUint16 returns a random uint16 value.\nfunc RollUint16() uint16 {\n\treturn uint16(rand.Int63() >> 47)\n}\n\nfunc RollUint64() uint64 {\n\treturn rand.Uint64()\n}\n\nfunc NewDeterministicDice(seed int64) *DeterministicDice {\n\treturn &DeterministicDice{rand.New(rand.NewSource(seed))}\n}\n\ntype DeterministicDice struct {\n\t*rand.Rand\n}\n\nfunc (dd *DeterministicDice) Roll(n int) int {\n\tif n == 1 {\n\t\treturn 0\n\t}\n\treturn dd.Intn(n)\n}\n\nfunc init() {\n\trand.Seed(time.Now().Unix())\n}\n"
  },
  {
    "path": "common/dice/dice_test.go",
    "content": "package dice_test\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\nfunc BenchmarkRoll1(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tRoll(1)\n\t}\n}\n\nfunc BenchmarkRoll20(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tRoll(20)\n\t}\n}\n\nfunc BenchmarkIntn1(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\trand.Intn(1) //nolint:staticcheck\n\t}\n}\n\nfunc BenchmarkIntn20(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\trand.Intn(20)\n\t}\n}\n\nfunc BenchmarkInt63(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = uint16(rand.Int63() >> 47)\n\t}\n}\n\nfunc BenchmarkInt31(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = uint16(rand.Int31() >> 15)\n\t}\n}\n\nfunc BenchmarkIntn(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = uint16(rand.Intn(65536))\n\t}\n}\n"
  },
  {
    "path": "common/drain/drain.go",
    "content": "package drain\n\nimport \"io\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype Drainer interface {\n\tAcknowledgeReceive(size int)\n\tDrain(reader io.Reader) error\n}\n"
  },
  {
    "path": "common/drain/drainer.go",
    "content": "package drain\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\ntype BehaviorSeedLimitedDrainer struct {\n\tDrainSize int\n}\n\nfunc NewBehaviorSeedLimitedDrainer(behaviorSeed int64, drainFoundation, maxBaseDrainSize, maxRandDrain int) (Drainer, error) {\n\tbehaviorRand := dice.NewDeterministicDice(behaviorSeed)\n\tBaseDrainSize := behaviorRand.Roll(maxBaseDrainSize)\n\tRandDrainMax := behaviorRand.Roll(maxRandDrain) + 1\n\tRandDrainRolled := dice.Roll(RandDrainMax)\n\tDrainSize := drainFoundation + BaseDrainSize + RandDrainRolled\n\treturn &BehaviorSeedLimitedDrainer{DrainSize: DrainSize}, nil\n}\n\nfunc (d *BehaviorSeedLimitedDrainer) AcknowledgeReceive(size int) {\n\td.DrainSize -= size\n}\n\nfunc (d *BehaviorSeedLimitedDrainer) Drain(reader io.Reader) error {\n\tif d.DrainSize > 0 {\n\t\terr := drainReadN(reader, d.DrainSize)\n\t\tif err == nil {\n\t\t\treturn newError(\"drained connection\")\n\t\t}\n\t\treturn newError(\"unable to drain connection\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc drainReadN(reader io.Reader, n int) error {\n\t_, err := io.CopyN(io.Discard, reader, int64(n))\n\treturn err\n}\n\nfunc WithError(drainer Drainer, reader io.Reader, err error) error {\n\tdrainErr := drainer.Drain(reader)\n\tif drainErr == nil {\n\t\treturn err\n\t}\n\treturn newError(drainErr).Base(err)\n}\n\ntype NopDrainer struct{}\n\nfunc (n NopDrainer) AcknowledgeReceive(size int) {\n}\n\nfunc (n NopDrainer) Drain(reader io.Reader) error {\n\treturn nil\n}\n\nfunc NewNopDrainer() Drainer {\n\treturn &NopDrainer{}\n}\n"
  },
  {
    "path": "common/drain/errors.generated.go",
    "content": "package drain\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/dualStack/fusedPacketConn/fusedPacketSocket.go",
    "content": "package fusedPacketConn\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nvar errClosed = errors.New(\"fused packet conn is closed\")\n\n// FusedPacketConn combines two PacketConn socket to create a dual stack PacketConn\n// When sending packet, the correct PacketConn for that destination address will be chosen\n// When receiving packet, will receive packet from either socket\n// Other operations will be done on both conn\ntype FusedPacketConn struct {\n\tipv6 net.PacketConn\n\tipv4 net.PacketConn\n\n\treadCh chan readResult\n\tdone   chan struct{}\n\n\tlocalAddrPreferIPv6 bool\n}\n\ntype readResult struct {\n\tdata []byte\n\taddr net.Addr\n\terr  error\n}\n\nfunc NewFusedPacketConn(ipv4, ipv6 net.PacketConn, readBufSize int, localAddrPreferIPv6 bool) *FusedPacketConn {\n\tf := &FusedPacketConn{\n\t\tipv4:                ipv4,\n\t\tipv6:                ipv6,\n\t\treadCh:              make(chan readResult, 2),\n\t\tdone:                make(chan struct{}),\n\t\tlocalAddrPreferIPv6: localAddrPreferIPv6,\n\t}\n\tgo f.readLoop(ipv4, readBufSize)\n\tgo f.readLoop(ipv6, readBufSize)\n\treturn f\n}\n\nfunc (f *FusedPacketConn) readLoop(conn net.PacketConn, bufSize int) {\n\tfor {\n\t\tbuf := make([]byte, bufSize)\n\t\tn, addr, err := conn.ReadFrom(buf)\n\t\tselect {\n\t\tcase <-f.done:\n\t\t\treturn\n\t\tcase f.readCh <- readResult{data: buf[:n], addr: addr, err: err}:\n\t\t}\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (f *FusedPacketConn) ReadFrom(p []byte) (int, net.Addr, error) {\n\tselect {\n\tcase <-f.done:\n\t\treturn 0, nil, errClosed\n\tcase r := <-f.readCh:\n\t\tif r.err != nil {\n\t\t\treturn 0, r.addr, r.err\n\t\t}\n\t\tn := copy(p, r.data)\n\t\treturn n, r.addr, nil\n\t}\n}\n\nfunc isIPv4Addr(addr net.Addr) bool {\n\tudpAddr, ok := addr.(*net.UDPAddr)\n\tif !ok {\n\t\treturn false\n\t}\n\treturn udpAddr.IP.To4() != nil\n}\n\nfunc (f *FusedPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) {\n\tif isIPv4Addr(addr) {\n\t\treturn f.ipv4.WriteTo(p, addr)\n\t}\n\treturn f.ipv6.WriteTo(p, addr)\n}\n\nfunc (f *FusedPacketConn) Close() error {\n\tclose(f.done)\n\terr4 := f.ipv4.Close()\n\terr6 := f.ipv6.Close()\n\tif err4 != nil {\n\t\treturn err4\n\t}\n\treturn err6\n}\n\nfunc (f *FusedPacketConn) LocalAddr() net.Addr {\n\tif f.localAddrPreferIPv6 {\n\t\treturn f.ipv6.LocalAddr()\n\t}\n\treturn f.ipv4.LocalAddr()\n}\n\nfunc (f *FusedPacketConn) SetDeadline(t time.Time) error {\n\terr4 := f.ipv4.SetDeadline(t)\n\terr6 := f.ipv6.SetDeadline(t)\n\tif err4 != nil {\n\t\treturn err4\n\t}\n\treturn err6\n}\n\nfunc (f *FusedPacketConn) SetReadDeadline(t time.Time) error {\n\terr4 := f.ipv4.SetReadDeadline(t)\n\terr6 := f.ipv6.SetReadDeadline(t)\n\tif err4 != nil {\n\t\treturn err4\n\t}\n\treturn err6\n}\n\nfunc (f *FusedPacketConn) SetWriteDeadline(t time.Time) error {\n\terr4 := f.ipv4.SetWriteDeadline(t)\n\terr6 := f.ipv6.SetWriteDeadline(t)\n\tif err4 != nil {\n\t\treturn err4\n\t}\n\treturn err6\n}\n"
  },
  {
    "path": "common/dualStack/happyEyeball/racingDialer.go",
    "content": "package happyEyeball\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task/taskDerive\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype Dialer func(ctx context.Context, domainDestination net.Destination, ips net.IP) (internet.Connection, error)\n\nfunc RacingDialer(ctx context.Context, domainDestination net.Destination, ips []net.IP, dialer Dialer, preferIPv6 bool, preferredHeadStart time.Duration) (internet.Connection, error) {\n\t// check if they are of a single family, if so no one have head start\n\thasIPv4 := false\n\thasIPv6 := false\n\tfor _, a := range ips {\n\t\tif a == nil {\n\t\t\tcontinue\n\t\t}\n\t\tswitch a.To4() != nil {\n\t\tcase true:\n\t\t\thasIPv4 = true\n\t\tcase false:\n\t\t\thasIPv6 = true\n\t\t}\n\t}\n\n\t// If there is only one family present, there is no head start\n\tif !hasIPv4 || !hasIPv6 {\n\t\tpreferredHeadStart = 0\n\t}\n\tif preferredHeadStart < 0 {\n\t\tpreferredHeadStart = 0\n\t}\n\n\tif len(ips) == 0 {\n\t\treturn nil, fmt.Errorf(\"no addresses to dial\")\n\t}\n\n\tconnCh := make(chan internet.Connection, 1)\n\tfinished := done.New()\n\n\ttasks := make([]func() error, 0, len(ips))\n\tfor _, a := range ips {\n\t\taddr := a\n\t\t// determine delay for this address\n\t\tdelay := time.Duration(0)\n\t\tif preferredHeadStart > 0 && addr != nil {\n\t\t\tisIPv6 := a.To4() == nil\n\t\t\t// if preferIPv6 is true, IPv4 gets the head start delay (i.e. IPv6 starts earlier)\n\t\t\tif preferIPv6 {\n\t\t\t\tif !isIPv6 {\n\t\t\t\t\tdelay = preferredHeadStart\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// prefer IPv4, so IPv6 gets delayed\n\t\t\t\tif isIPv6 {\n\t\t\t\t\tdelay = preferredHeadStart\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// capture addr and delay in closure\n\t\ttasks = append(tasks, func() error {\n\t\t\tif delay > 0 {\n\t\t\t\tselect {\n\t\t\t\tcase <-time.After(delay):\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t\treturn ctx.Err()\n\t\t\t\t}\n\t\t\t}\n\t\t\tif finished.Done() {\n\t\t\t\treturn fmt.Errorf(\"dial attempt cancelled due to another successful dial\")\n\t\t\t}\n\t\t\tc, err := dialer(ctx, domainDestination, addr)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif c == nil {\n\t\t\t\treturn fmt.Errorf(\"dialer returned nil connection\")\n\t\t\t}\n\t\t\t// send the successful conn (non-blocking due to buffer)\n\t\t\tselect {\n\t\t\tcase connCh <- c:\n\t\t\t\t// stored\n\t\t\tdefault:\n\t\t\t\t// channel already has a conn, close this extra one\n\t\t\t\t_ = c.Close()\n\t\t\t}\n\t\t\t_ = finished.Close()\n\t\t\treturn nil\n\t\t})\n\t}\n\n\terrs := taskDerive.RunTryAll(ctx, tasks...)\n\tif errs == nil {\n\t\t// at least one dial succeeded; return the conn\n\t\tselect {\n\t\tcase c := <-connCh:\n\t\t\treturn c, nil\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\tdefault:\n\t\t\t// theoretically should not happen, but handle defensively\n\t\t\treturn nil, fmt.Errorf(\"dial succeeded but no connection available\")\n\t\t}\n\t}\n\t// all attempts failed, return the first non-nil error\n\tfor _, e := range errs {\n\t\tif e != nil {\n\t\t\treturn nil, e\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"all dial attempts failed\")\n}\n"
  },
  {
    "path": "common/environment/app.go",
    "content": "package environment\n\ntype AppEnvironmentCapabilitySet interface {\n\tBaseEnvironmentCapabilitySet\n\tSystemNetworkCapabilitySet\n\tInstanceNetworkCapabilitySet\n\tFileSystemCapabilitySet\n\tPersistentStorageCapabilitySet\n\tTransientStorageCapabilitySet\n}\n\ntype AppEnvironment interface {\n\tAppEnvironmentCapabilitySet\n\tNarrowScope(key string) (AppEnvironment, error)\n\tdoNotImpl()\n}\n"
  },
  {
    "path": "common/environment/base.go",
    "content": "package environment\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/filesystemcap\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\ntype BaseEnvironmentCapabilitySet interface {\n\tFeaturesLookupCapabilitySet\n\tLogCapabilitySet\n}\n\ntype BaseEnvironment interface {\n\tBaseEnvironmentCapabilitySet\n\tdoNotImpl()\n}\n\ntype SystemNetworkCapabilitySet interface {\n\tDialer() internet.SystemDialer\n\tListener() internet.SystemListener\n}\n\ntype InstanceNetworkCapabilitySet interface {\n\tOutboundDialer() tagged.DialFunc\n}\n\ntype FeaturesLookupCapabilitySet interface {\n\tRequireFeatures() interface{}\n}\n\ntype LogCapabilitySet interface {\n\tRecordLog() interface{}\n}\n\ntype FileSystemCapabilitySet interface {\n\tfilesystemcap.FileSystemCapabilitySet\n}\n\ntype PersistentStorageCapabilitySet interface {\n\tPersistentStorage() storage.ScopedPersistentStorage\n}\ntype TransientStorageCapabilitySet interface {\n\tTransientStorage() storage.ScopedTransientStorage\n}\n\ntype ProxyMetadataCapabilitySet interface {\n\tSelfProxyTag() string\n}\n"
  },
  {
    "path": "common/environment/connection.go",
    "content": "package environment\n\nimport \"github.com/v2fly/v2ray-core/v5/common/log\"\n\ntype ConnectionCapabilitySet interface {\n\tConnectionLogCapabilitySet\n}\n\ntype ConnectionEnvironment interface {\n\tConnectionCapabilitySet\n\tdoNotImpl()\n}\n\ntype ConnectionLogCapabilitySet interface {\n\tRecordConnectionLog(msg log.Message)\n}\n"
  },
  {
    "path": "common/environment/deferredpersistentstorage/defereredPersistentStorage.go",
    "content": "package deferredpersistentstorage\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/persistentstorage\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n)\n\ntype DeferredPersistentStorage interface {\n\tstorage.ScopedPersistentStorage\n\tProvideInner(ctx context.Context, inner persistentstorage.ScopedPersistentStorage)\n}\n\nvar errNotExist = errors.New(\"persistent storage does not exist\")\n\ntype deferredPersistentStorage struct {\n\tready context.Context\n\tdone  context.CancelFunc\n\tinner persistentstorage.ScopedPersistentStorage\n\n\tawaitingChildren []*deferredPersistentStorage\n\n\tintoScopes []string\n}\n\nfunc (d *deferredPersistentStorage) ScopedPersistentStorageEngine() {\n}\n\nfunc (d *deferredPersistentStorage) Put(ctx context.Context, key []byte, value []byte) error {\n\t<-d.ready.Done()\n\tif d.inner == nil {\n\t\treturn errNotExist\n\t}\n\treturn d.inner.Put(ctx, key, value)\n}\n\nfunc (d *deferredPersistentStorage) Get(ctx context.Context, key []byte) ([]byte, error) {\n\t<-d.ready.Done()\n\tif d.inner == nil {\n\t\treturn nil, errNotExist\n\t}\n\treturn d.inner.Get(ctx, key)\n}\n\nfunc (d *deferredPersistentStorage) List(ctx context.Context, keyPrefix []byte) ([][]byte, error) {\n\t<-d.ready.Done()\n\tif d.inner == nil {\n\t\treturn nil, errNotExist\n\t}\n\treturn d.inner.List(ctx, keyPrefix)\n}\n\nfunc (d *deferredPersistentStorage) Clear(ctx context.Context) {\n\t<-d.ready.Done()\n\tif d.inner == nil {\n\t\treturn\n\t}\n\td.inner.Clear(ctx)\n}\n\nfunc (d *deferredPersistentStorage) NarrowScope(ctx context.Context, key []byte) (storage.ScopedPersistentStorage, error) {\n\tif d.ready.Err() != nil {\n\t\treturn d.inner.NarrowScope(ctx, key)\n\t}\n\tready, done := context.WithCancel(ctx)\n\tswallowCopyScopes := d.intoScopes\n\tdps := &deferredPersistentStorage{\n\t\tready:      ready,\n\t\tdone:       done,\n\t\tinner:      nil,\n\t\tintoScopes: append(swallowCopyScopes, string(key)),\n\t}\n\td.awaitingChildren = append(d.awaitingChildren, dps)\n\treturn dps, nil\n}\n\nfunc (d *deferredPersistentStorage) DropScope(ctx context.Context, key []byte) error {\n\t<-d.ready.Done()\n\tif d.inner == nil {\n\t\treturn errNotExist\n\t}\n\treturn d.inner.DropScope(ctx, key)\n}\n\nfunc (d *deferredPersistentStorage) ProvideInner(ctx context.Context, inner persistentstorage.ScopedPersistentStorage) {\n\td.inner = inner\n\tif inner != nil {\n\t\tfor _, scope := range d.intoScopes {\n\t\t\tnewScope, err := inner.NarrowScope(ctx, []byte(scope))\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\td.inner = newScope\n\t\t}\n\t}\n\tfor _, child := range d.awaitingChildren {\n\t\tchild.ProvideInner(ctx, d.inner)\n\t}\n\td.done()\n}\n\nfunc NewDeferredPersistentStorage(ctx context.Context) DeferredPersistentStorage {\n\tready, done := context.WithCancel(ctx)\n\treturn &deferredPersistentStorage{\n\t\tready: ready,\n\t\tdone:  done,\n\t\tinner: nil,\n\t}\n}\n"
  },
  {
    "path": "common/environment/envctx/env.go",
    "content": "package envctx\n\nimport \"context\"\n\nconst (\n\tenvironmentKey string = \"v2.environment\"\n)\n\nfunc ContextWithEnvironment(ctx context.Context, environment interface{}) context.Context {\n\treturn context.WithValue(ctx, environmentKey, environment) //nolint: revive,staticcheck\n}\n\nfunc EnvironmentFromContext(ctx context.Context) interface{} {\n\treturn ctx.Value(environmentKey)\n}\n"
  },
  {
    "path": "common/environment/envimpl/fs.go",
    "content": "package envimpl\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem/fsifce\"\n)\n\ntype fileSystemDefaultImpl struct{}\n\nfunc (f fileSystemDefaultImpl) ReadDir() fsifce.FileReadDirFunc {\n\treturn filesystem.NewFileReadDir\n}\n\nfunc (f fileSystemDefaultImpl) RemoveFile() fsifce.FileRemoveFunc {\n\treturn filesystem.NewFileRemover\n}\n\nfunc (f fileSystemDefaultImpl) OpenFileForReadSeek() fsifce.FileSeekerFunc {\n\treturn filesystem.NewFileSeeker\n}\n\nfunc (f fileSystemDefaultImpl) OpenFileForRead() fsifce.FileReaderFunc {\n\treturn filesystem.NewFileReader\n}\n\nfunc (f fileSystemDefaultImpl) OpenFileForWrite() fsifce.FileWriterFunc {\n\treturn filesystem.NewFileWriter\n}\n\nfunc NewDefaultFileSystemDefaultImpl() environment.FileSystemCapabilitySet {\n\treturn fileSystemDefaultImpl{}\n}\n"
  },
  {
    "path": "common/environment/filesystemcap/fscap.go",
    "content": "package filesystemcap\n\nimport \"github.com/v2fly/v2ray-core/v5/common/platform/filesystem/fsifce\"\n\ntype FileSystemCapabilitySet interface {\n\tOpenFileForReadSeek() fsifce.FileSeekerFunc\n\tOpenFileForRead() fsifce.FileReaderFunc\n\tOpenFileForWrite() fsifce.FileWriterFunc\n\tReadDir() fsifce.FileReadDirFunc\n\tRemoveFile() fsifce.FileRemoveFunc\n}\n"
  },
  {
    "path": "common/environment/filesystemimpl/fsimpl.go",
    "content": "package filesystemimpl\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem/fsifce\"\n)\n\nfunc NewDefaultFileSystemDefaultImpl() environment.FileSystemCapabilitySet {\n\treturn fsCapImpl{}\n}\n\ntype fsCapImpl struct{}\n\nfunc (f fsCapImpl) OpenFileForReadSeek() fsifce.FileSeekerFunc {\n\treturn filesystem.NewFileSeeker\n}\n\nfunc (f fsCapImpl) OpenFileForRead() fsifce.FileReaderFunc {\n\treturn filesystem.NewFileReader\n}\n\nfunc (f fsCapImpl) OpenFileForWrite() fsifce.FileWriterFunc {\n\treturn filesystem.NewFileWriter\n}\n\nfunc (f fsCapImpl) ReadDir() fsifce.FileReadDirFunc {\n\treturn filesystem.NewFileReadDir\n}\n\nfunc (f fsCapImpl) RemoveFile() fsifce.FileRemoveFunc {\n\treturn filesystem.NewFileRemover\n}\n"
  },
  {
    "path": "common/environment/proxy.go",
    "content": "package environment\n\ntype ProxyEnvironmentCapabilitySet interface {\n\tBaseEnvironmentCapabilitySet\n\tInstanceNetworkCapabilitySet\n\tTransientStorageCapabilitySet\n\tProxyMetadataCapabilitySet\n}\n\n// TODO Add NarrowScopeToConnection\n\ntype ProxyEnvironment interface {\n\tProxyEnvironmentCapabilitySet\n\tNarrowScope(key string) (ProxyEnvironment, error)\n\tNarrowScopeToTransport(key string) (TransportEnvironment, error)\n\tdoNotImpl()\n}\n"
  },
  {
    "path": "common/environment/rootcap.go",
    "content": "package environment\n\ntype RootEnvironment interface {\n\tAppEnvironment(tag string) AppEnvironment\n\tProxyEnvironment(tag string) ProxyEnvironment\n\tDropProxyEnvironment(tag string) error\n\tdoNotImpl()\n}\n"
  },
  {
    "path": "common/environment/rootcap_impl.go",
    "content": "package environment\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem/fsifce\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\nfunc NewRootEnvImpl(ctx context.Context, transientStorage storage.ScopedTransientStorage,\n\tsystemDialer internet.SystemDialer, systemListener internet.SystemListener,\n\tfilesystem FileSystemCapabilitySet, persistStorage storage.ScopedPersistentStorage,\n) RootEnvironment {\n\treturn &rootEnvImpl{\n\t\ttransientStorage: transientStorage,\n\t\tsystemListener:   systemListener,\n\t\tsystemDialer:     systemDialer,\n\t\tfilesystem:       filesystem,\n\t\tpersistStorage:   persistStorage,\n\t\tctx:              ctx,\n\t}\n}\n\ntype rootEnvImpl struct {\n\tpersistStorage   storage.ScopedPersistentStorage\n\ttransientStorage storage.ScopedTransientStorage\n\tsystemDialer     internet.SystemDialer\n\tsystemListener   internet.SystemListener\n\tfilesystem       FileSystemCapabilitySet\n\n\tctx context.Context\n}\n\nfunc (r *rootEnvImpl) doNotImpl() {\n\tpanic(\"placeholder doNotImpl\")\n}\n\nfunc (r *rootEnvImpl) AppEnvironment(tag string) AppEnvironment {\n\ttransientStorage, err := r.transientStorage.NarrowScope(r.ctx, tag)\n\tif err != nil {\n\t\treturn nil\n\t}\n\tpersistStorage, err := r.persistStorage.NarrowScope(r.ctx, []byte(tag))\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &appEnvImpl{\n\t\ttransientStorage: transientStorage,\n\t\tpersistStorage:   persistStorage,\n\t\tsystemListener:   r.systemListener,\n\t\tsystemDialer:     r.systemDialer,\n\t\tfilesystem:       r.filesystem,\n\t\tctx:              r.ctx,\n\t}\n}\n\nfunc (r *rootEnvImpl) ProxyEnvironment(tag string) ProxyEnvironment {\n\ttransientStorage, err := r.transientStorage.NarrowScope(r.ctx, tag)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &proxyEnvImpl{\n\t\ttransientStorage: transientStorage,\n\t\tsystemListener:   r.systemListener,\n\t\tsystemDialer:     r.systemDialer,\n\t\tctx:              r.ctx,\n\t}\n}\n\nfunc (r *rootEnvImpl) DropProxyEnvironment(tag string) error {\n\ttransientStorage, err := r.transientStorage.NarrowScope(r.ctx, tag)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttransientStorage.Clear(r.ctx)\n\treturn r.transientStorage.DropScope(r.ctx, tag)\n}\n\ntype appEnvImpl struct {\n\tpersistStorage   storage.ScopedPersistentStorage\n\ttransientStorage storage.ScopedTransientStorage\n\tsystemDialer     internet.SystemDialer\n\tsystemListener   internet.SystemListener\n\tfilesystem       FileSystemCapabilitySet\n\n\tctx context.Context\n}\n\nfunc (a *appEnvImpl) RequireFeatures() interface{} {\n\tpanic(\"implement me\")\n}\n\nfunc (a *appEnvImpl) RecordLog() interface{} {\n\tpanic(\"implement me\")\n}\n\nfunc (a *appEnvImpl) Dialer() internet.SystemDialer {\n\tpanic(\"implement me\")\n}\n\nfunc (a *appEnvImpl) Listener() internet.SystemListener {\n\tpanic(\"implement me\")\n}\n\nfunc (a *appEnvImpl) OutboundDialer() tagged.DialFunc {\n\treturn internet.DialTaggedOutbound\n}\n\nfunc (a *appEnvImpl) OpenFileForReadSeek() fsifce.FileSeekerFunc {\n\treturn a.filesystem.OpenFileForReadSeek()\n}\n\nfunc (a *appEnvImpl) OpenFileForRead() fsifce.FileReaderFunc {\n\treturn a.filesystem.OpenFileForRead()\n}\n\nfunc (a *appEnvImpl) OpenFileForWrite() fsifce.FileWriterFunc {\n\treturn a.filesystem.OpenFileForWrite()\n}\n\nfunc (a *appEnvImpl) ReadDir() fsifce.FileReadDirFunc {\n\treturn a.filesystem.ReadDir()\n}\n\nfunc (a *appEnvImpl) RemoveFile() fsifce.FileRemoveFunc {\n\treturn a.filesystem.RemoveFile()\n}\n\nfunc (a *appEnvImpl) PersistentStorage() storage.ScopedPersistentStorage {\n\treturn a.persistStorage\n}\n\nfunc (a *appEnvImpl) TransientStorage() storage.ScopedTransientStorage {\n\treturn a.transientStorage\n}\n\nfunc (a *appEnvImpl) NarrowScope(key string) (AppEnvironment, error) {\n\ttransientStorage, err := a.transientStorage.NarrowScope(a.ctx, key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &appEnvImpl{\n\t\ttransientStorage: transientStorage,\n\t\tsystemDialer:     a.systemDialer,\n\t\tsystemListener:   a.systemListener,\n\t\tctx:              a.ctx,\n\t}, nil\n}\n\nfunc (a *appEnvImpl) doNotImpl() {\n\tpanic(\"placeholder doNotImpl\")\n}\n\ntype proxyEnvImpl struct {\n\ttransientStorage storage.ScopedTransientStorage\n\tsystemDialer     internet.SystemDialer\n\tsystemListener   internet.SystemListener\n\n\tscopeName string\n\n\tctx context.Context\n}\n\nfunc (p *proxyEnvImpl) RequireFeatures() interface{} {\n\tpanic(\"implement me\")\n}\n\nfunc (p *proxyEnvImpl) RecordLog() interface{} {\n\tpanic(\"implement me\")\n}\n\nfunc (p *proxyEnvImpl) OutboundDialer() tagged.DialFunc {\n\tpanic(\"implement me\")\n}\n\nfunc (p *proxyEnvImpl) TransientStorage() storage.ScopedTransientStorage {\n\treturn p.transientStorage\n}\n\nfunc (p *proxyEnvImpl) SelfProxyTag() string {\n\treturn p.scopeName\n}\n\nfunc (p *proxyEnvImpl) NarrowScope(key string) (ProxyEnvironment, error) {\n\ttransientStorage, err := p.transientStorage.NarrowScope(p.ctx, key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &proxyEnvImpl{\n\t\ttransientStorage: transientStorage,\n\t\tscopeName:        p.scopeName,\n\t\tctx:              p.ctx,\n\t}, nil\n}\n\nfunc (p *proxyEnvImpl) NarrowScopeToTransport(key string) (TransportEnvironment, error) {\n\ttransientStorage, err := p.transientStorage.NarrowScope(p.ctx, key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &transportEnvImpl{\n\t\tctx:              p.ctx,\n\t\ttransientStorage: transientStorage,\n\t\tsystemDialer:     p.systemDialer,\n\t\tsystemListener:   p.systemListener,\n\t\tselfProxyTag:     p.scopeName,\n\t}, nil\n}\n\nfunc (p *proxyEnvImpl) doNotImpl() {\n\tpanic(\"placeholder doNotImpl\")\n}\n\ntype transportEnvImpl struct {\n\ttransientStorage storage.ScopedTransientStorage\n\tsystemDialer     internet.SystemDialer\n\tsystemListener   internet.SystemListener\n\n\tctx context.Context\n\n\tselfProxyTag string\n}\n\nfunc (t *transportEnvImpl) RequireFeatures() interface{} {\n\tpanic(\"implement me\")\n}\n\nfunc (t *transportEnvImpl) SelfProxyTag() string {\n\treturn t.selfProxyTag\n}\n\nfunc (t *transportEnvImpl) RecordLog() interface{} {\n\tpanic(\"implement me\")\n}\n\nfunc (t *transportEnvImpl) Dialer() internet.SystemDialer {\n\treturn t.systemDialer\n}\n\nfunc (t *transportEnvImpl) Listener() internet.SystemListener {\n\treturn t.systemListener\n}\n\nfunc (t *transportEnvImpl) OutboundDialer() tagged.DialFunc {\n\treturn tagged.Dialer\n}\n\nfunc (t *transportEnvImpl) TransientStorage() storage.ScopedTransientStorage {\n\treturn t.transientStorage\n}\n\nfunc (t *transportEnvImpl) NarrowScope(key string) (TransportEnvironment, error) {\n\ttransientStorage, err := t.transientStorage.NarrowScope(t.ctx, key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &transportEnvImpl{\n\t\tctx:              t.ctx,\n\t\ttransientStorage: transientStorage,\n\t}, nil\n}\n\nfunc (t *transportEnvImpl) doNotImpl() {\n\tpanic(\"implement me\")\n}\n"
  },
  {
    "path": "common/environment/systemnetworkimpl/systemnetwork.go",
    "content": "package systemnetworkimpl\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc NewSystemNetworkImpl(listener internet.SystemListener, dialer internet.SystemDialer) environment.SystemNetworkCapabilitySet {\n\treturn &systemNetworkImpl{dialer: dialer, listener: listener}\n}\n\ntype systemDefaultDialer struct{}\n\nfunc (s systemDefaultDialer) Listen(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.Listener, error) {\n\treturn internet.ListenSystem(ctx, addr, sockopt)\n}\n\nfunc (s systemDefaultDialer) ListenPacket(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.PacketConn, error) {\n\treturn internet.ListenSystemPacket(ctx, addr, sockopt)\n}\n\nfunc (s systemDefaultDialer) Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *internet.SocketConfig) (net.Conn, error) {\n\treturn internet.DialSystem(ctx, destination, sockopt)\n}\n\nfunc NewSystemNetworkDefault() environment.SystemNetworkCapabilitySet {\n\tsystemDefault := systemDefaultDialer{}\n\treturn &systemNetworkImpl{dialer: systemDefault, listener: systemDefault}\n}\n\ntype systemNetworkImpl struct {\n\tlistener internet.SystemListener\n\tdialer   internet.SystemDialer\n}\n\nfunc (s systemNetworkImpl) Dialer() internet.SystemDialer {\n\treturn s.dialer\n}\n\nfunc (s systemNetworkImpl) Listener() internet.SystemListener {\n\treturn s.listener\n}\n\nfunc NewSystemListenerWithDefaultOpt(listener internet.SystemListener, opt *internet.SocketConfig) internet.SystemListener {\n\treturn systemListenerWithDefaultOpt{SystemListener: listener, opt: opt}\n}\n\ntype systemListenerWithDefaultOpt struct {\n\tinternet.SystemListener\n\topt *internet.SocketConfig\n}\n\nfunc (s systemListenerWithDefaultOpt) Listen(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.Listener, error) {\n\tif sockopt == nil {\n\t\treturn s.Listen(ctx, addr, s.opt)\n\t}\n\treturn s.Listen(ctx, addr, sockopt)\n}\n\nfunc (s systemListenerWithDefaultOpt) ListenPacket(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.PacketConn, error) {\n\tif sockopt == nil {\n\t\treturn s.ListenPacket(ctx, addr, s.opt)\n\t}\n\treturn s.ListenPacket(ctx, addr, sockopt)\n}\n\nfunc NewSystemDialerWithDefaultOpt(listener internet.SystemDialer, opt *internet.SocketConfig) internet.SystemDialer {\n\treturn systemDialerWithDefaultOpt{SystemDialer: listener, opt: opt}\n}\n\ntype systemDialerWithDefaultOpt struct {\n\tinternet.SystemDialer\n\topt *internet.SocketConfig\n}\n\nfunc (s systemDialerWithDefaultOpt) Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *internet.SocketConfig) (net.Conn, error) {\n\tif sockopt == nil {\n\t\treturn s.Dial(ctx, source, destination, s.opt)\n\t}\n\treturn s.Dial(ctx, source, destination, sockopt)\n}\n"
  },
  {
    "path": "common/environment/transientstorageimpl/errors.generated.go",
    "content": "package transientstorageimpl\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/environment/transientstorageimpl/storage.go",
    "content": "package transientstorageimpl\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n)\n\nfunc NewScopedTransientStorageImpl() storage.ScopedTransientStorage {\n\treturn &scopedTransientStorageImpl{scopes: map[string]storage.ScopedTransientStorage{}, values: map[string]interface{}{}}\n}\n\ntype scopedTransientStorageImpl struct {\n\taccess sync.Mutex\n\tscopes map[string]storage.ScopedTransientStorage\n\tvalues map[string]interface{}\n}\n\nfunc (s *scopedTransientStorageImpl) ScopedTransientStorage() {\n\tpanic(\"implement me\")\n}\n\nfunc (s *scopedTransientStorageImpl) Put(ctx context.Context, key string, value interface{}) error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\ts.values[key] = value\n\treturn nil\n}\n\nfunc (s *scopedTransientStorageImpl) Get(ctx context.Context, key string) (interface{}, error) {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tsw, ok := s.values[key]\n\tif !ok {\n\t\treturn nil, newError(\"unable to find \")\n\t}\n\treturn sw, nil\n}\n\nfunc (s *scopedTransientStorageImpl) List(ctx context.Context, keyPrefix string) ([]string, error) {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tvar ret []string\n\tfor key := range s.values {\n\t\tif strings.HasPrefix(key, keyPrefix) {\n\t\t\tret = append(ret, key)\n\t\t}\n\t}\n\treturn ret, nil\n}\n\nfunc (s *scopedTransientStorageImpl) Clear(ctx context.Context) {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tfor _, v := range s.values {\n\t\tif sw, ok := v.(storage.TransientStorageLifecycleReceiver); ok {\n\t\t\t_ = sw.Close()\n\t\t}\n\t}\n\ts.values = map[string]interface{}{}\n\tfor _, v := range s.scopes {\n\t\tv.Clear(ctx)\n\t}\n\ts.scopes = map[string]storage.ScopedTransientStorage{}\n}\n\nfunc (s *scopedTransientStorageImpl) NarrowScope(ctx context.Context, key string) (storage.ScopedTransientStorage, error) {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tsw, ok := s.scopes[key]\n\tif !ok {\n\t\tscope := NewScopedTransientStorageImpl()\n\t\ts.scopes[key] = scope\n\t\treturn scope, nil\n\t}\n\treturn sw, nil\n}\n\nfunc (s *scopedTransientStorageImpl) DropScope(ctx context.Context, key string) error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tif v, ok := s.scopes[key]; ok {\n\t\tv.Clear(ctx)\n\t}\n\tdelete(s.scopes, key)\n\treturn nil\n}\n"
  },
  {
    "path": "common/environment/transport.go",
    "content": "package environment\n\ntype TransportEnvironmentCapacitySet interface {\n\tBaseEnvironmentCapabilitySet\n\tSystemNetworkCapabilitySet\n\tInstanceNetworkCapabilitySet\n\tTransientStorageCapabilitySet\n\tProxyMetadataCapabilitySet\n}\n\ntype TransportEnvironment interface {\n\tTransportEnvironmentCapacitySet\n\tNarrowScope(key string) (TransportEnvironment, error)\n\tdoNotImpl()\n}\n"
  },
  {
    "path": "common/errors/errors.go",
    "content": "// Package errors is a drop-in replacement for Golang lib 'errors'.\npackage errors\n\nimport (\n\t\"os\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype hasInnerError interface {\n\t// Inner returns the underlying error of this one.\n\tInner() error\n}\n\ntype hasSeverity interface {\n\tSeverity() log.Severity\n}\n\n// Error is an error object with underlying error.\ntype Error struct {\n\tpathObj  interface{}\n\tprefix   []interface{}\n\tmessage  []interface{}\n\tinner    error\n\tseverity log.Severity\n}\n\nfunc (err *Error) WithPathObj(obj interface{}) *Error {\n\terr.pathObj = obj\n\treturn err\n}\n\nfunc (err *Error) pkgPath() string {\n\tif err.pathObj == nil {\n\t\treturn \"\"\n\t}\n\tpath := reflect.TypeOf(err.pathObj).PkgPath()\n\t// TODO update required on release\n\tpath = strings.TrimPrefix(path, \"github.com/v2fly/v2ray-core/v5/\")\n\tpath = strings.TrimPrefix(path, \"github.com/v2fly/v2ray-core/v5\")\n\treturn path\n}\n\n// Error implements error.Error().\nfunc (err *Error) Error() string {\n\tbuilder := strings.Builder{}\n\tfor _, prefix := range err.prefix {\n\t\tbuilder.WriteByte('[')\n\t\tbuilder.WriteString(serial.ToString(prefix))\n\t\tbuilder.WriteString(\"] \")\n\t}\n\n\tpath := err.pkgPath()\n\tif len(path) > 0 {\n\t\tbuilder.WriteString(path)\n\t\tbuilder.WriteString(\": \")\n\t}\n\n\tmsg := serial.Concat(err.message...)\n\tbuilder.WriteString(msg)\n\n\tif err.inner != nil {\n\t\tbuilder.WriteString(\" > \")\n\t\tbuilder.WriteString(err.inner.Error())\n\t}\n\n\treturn builder.String()\n}\n\n// Inner implements hasInnerError.Inner()\nfunc (err *Error) Inner() error {\n\tif err.inner == nil {\n\t\treturn nil\n\t}\n\treturn err.inner\n}\n\nfunc (err *Error) Base(e error) *Error {\n\terr.inner = e\n\treturn err\n}\n\nfunc (err *Error) atSeverity(s log.Severity) *Error {\n\terr.severity = s\n\treturn err\n}\n\nfunc (err *Error) Severity() log.Severity {\n\tif err.inner == nil {\n\t\treturn err.severity\n\t}\n\n\tif s, ok := err.inner.(hasSeverity); ok {\n\t\tas := s.Severity()\n\t\tif as < err.severity {\n\t\t\treturn as\n\t\t}\n\t}\n\n\treturn err.severity\n}\n\n// AtDebug sets the severity to debug.\nfunc (err *Error) AtDebug() *Error {\n\treturn err.atSeverity(log.Severity_Debug)\n}\n\n// AtInfo sets the severity to info.\nfunc (err *Error) AtInfo() *Error {\n\treturn err.atSeverity(log.Severity_Info)\n}\n\n// AtWarning sets the severity to warning.\nfunc (err *Error) AtWarning() *Error {\n\treturn err.atSeverity(log.Severity_Warning)\n}\n\n// AtError sets the severity to error.\nfunc (err *Error) AtError() *Error {\n\treturn err.atSeverity(log.Severity_Error)\n}\n\n// String returns the string representation of this error.\nfunc (err *Error) String() string {\n\treturn err.Error()\n}\n\n// WriteToLog writes current error into log.\nfunc (err *Error) WriteToLog(opts ...ExportOption) {\n\tvar holder ExportOptionHolder\n\n\tfor _, opt := range opts {\n\t\topt(&holder)\n\t}\n\n\tif holder.SessionID > 0 {\n\t\terr.prefix = append(err.prefix, holder.SessionID)\n\t}\n\n\tlog.Record(&log.GeneralMessage{\n\t\tSeverity: GetSeverity(err),\n\t\tContent:  err,\n\t})\n}\n\ntype ExportOptionHolder struct {\n\tSessionID uint32\n}\n\ntype ExportOption func(*ExportOptionHolder)\n\n// New returns a new error object with message formed from given arguments.\nfunc New(msg ...interface{}) *Error {\n\treturn &Error{\n\t\tmessage:  msg,\n\t\tseverity: log.Severity_Info,\n\t}\n}\n\n// Cause returns the root cause of this error.\nfunc Cause(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\nL:\n\tfor {\n\t\tswitch inner := err.(type) {\n\t\tcase hasInnerError:\n\t\t\tif inner.Inner() == nil {\n\t\t\t\tbreak L\n\t\t\t}\n\t\t\terr = inner.Inner()\n\t\tcase *os.PathError:\n\t\t\tif inner.Err == nil {\n\t\t\t\tbreak L\n\t\t\t}\n\t\t\terr = inner.Err\n\t\tcase *os.SyscallError:\n\t\t\tif inner.Err == nil {\n\t\t\t\tbreak L\n\t\t\t}\n\t\t\terr = inner.Err\n\t\tdefault:\n\t\t\tbreak L\n\t\t}\n\t}\n\treturn err\n}\n\n// GetSeverity returns the actual severity of the error, including inner errors.\nfunc GetSeverity(err error) log.Severity {\n\tif s, ok := err.(hasSeverity); ok {\n\t\treturn s.Severity()\n\t}\n\treturn log.Severity_Info\n}\n"
  },
  {
    "path": "common/errors/errors_test.go",
    "content": "package errors_test\n\nimport (\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\nfunc TestError(t *testing.T) {\n\terr := New(\"TestError\")\n\tif v := GetSeverity(err); v != log.Severity_Info {\n\t\tt.Error(\"severity: \", v)\n\t}\n\n\terr = New(\"TestError2\").Base(io.EOF)\n\tif v := GetSeverity(err); v != log.Severity_Info {\n\t\tt.Error(\"severity: \", v)\n\t}\n\n\terr = New(\"TestError3\").Base(io.EOF).AtWarning()\n\tif v := GetSeverity(err); v != log.Severity_Warning {\n\t\tt.Error(\"severity: \", v)\n\t}\n\n\terr = New(\"TestError4\").Base(io.EOF).AtWarning()\n\terr = New(\"TestError5\").Base(err)\n\tif v := GetSeverity(err); v != log.Severity_Warning {\n\t\tt.Error(\"severity: \", v)\n\t}\n\tif v := err.Error(); !strings.Contains(v, \"EOF\") {\n\t\tt.Error(\"error: \", v)\n\t}\n}\n\ntype e struct{}\n\nfunc TestErrorMessage(t *testing.T) {\n\tdata := []struct {\n\t\terr error\n\t\tmsg string\n\t}{\n\t\t{\n\t\t\terr: New(\"a\").Base(New(\"b\")).WithPathObj(e{}),\n\t\t\tmsg: \"common/errors_test: a > b\",\n\t\t},\n\t\t{\n\t\t\terr: New(\"a\").Base(New(\"b\").WithPathObj(e{})),\n\t\t\tmsg: \"a > common/errors_test: b\",\n\t\t},\n\t}\n\n\tfor _, d := range data {\n\t\tif diff := cmp.Diff(d.msg, d.err.Error()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/errors/multi_error.go",
    "content": "package errors\n\nimport (\n\t\"strings\"\n)\n\ntype multiError []error\n\nfunc (e multiError) Error() string {\n\tvar r strings.Builder\n\tr.WriteString(\"multierr: \")\n\tfor _, err := range e {\n\t\tr.WriteString(err.Error())\n\t\tr.WriteString(\" | \")\n\t}\n\treturn r.String()\n}\n\nfunc Combine(maybeError ...error) error {\n\tvar errs multiError\n\tfor _, err := range maybeError {\n\t\tif err != nil {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\tif len(errs) == 0 {\n\t\treturn nil\n\t}\n\treturn errs\n}\n"
  },
  {
    "path": "common/errors.generated.go",
    "content": "package common\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/interfaces.go",
    "content": "package common\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\n// Closable is the interface for objects that can release its resources.\n//\n// v2ray:api:beta\ntype Closable interface {\n\t// Close release all resources used by this object, including goroutines.\n\tClose() error\n}\n\n// Interruptible is an interface for objects that can be stopped before its completion.\n//\n// v2ray:api:beta\ntype Interruptible interface {\n\tInterrupt()\n}\n\n// Close closes the obj if it is a Closable.\n//\n// v2ray:api:beta\nfunc Close(obj interface{}) error {\n\tif c, ok := obj.(Closable); ok {\n\t\treturn c.Close()\n\t}\n\treturn nil\n}\n\n// Interrupt calls Interrupt() if object implements Interruptible interface, or Close() if the object implements Closable interface.\n//\n// v2ray:api:beta\nfunc Interrupt(obj interface{}) error {\n\tif c, ok := obj.(Interruptible); ok {\n\t\tc.Interrupt()\n\t\treturn nil\n\t}\n\treturn Close(obj)\n}\n\n// Runnable is the interface for objects that can start to work and stop on demand.\ntype Runnable interface {\n\t// Start starts the runnable object. Upon the method returning nil, the object begins to function properly.\n\tStart() error\n\tClosable\n}\n\n// HasType is the interface for objects that knows its type.\ntype HasType interface {\n\t// Type returns the type of the object.\n\t// Usually it returns (*Type)(nil) of the object.\n\tType() interface{}\n}\n\n// ChainedClosable is a Closable that consists of multiple Closable objects.\ntype ChainedClosable []Closable\n\n// Close implements Closable.\nfunc (cc ChainedClosable) Close() error {\n\tvar errs []error\n\tfor _, c := range cc {\n\t\tif err := c.Close(); err != nil {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\treturn errors.Combine(errs...)\n}\n"
  },
  {
    "path": "common/log/access.go",
    "content": "package log\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype logKey int\n\nconst (\n\taccessMessageKey logKey = iota\n)\n\ntype AccessStatus string\n\nconst (\n\tAccessAccepted = AccessStatus(\"accepted\")\n\tAccessRejected = AccessStatus(\"rejected\")\n)\n\ntype AccessMessage struct {\n\tFrom   interface{}\n\tTo     interface{}\n\tStatus AccessStatus\n\tReason interface{}\n\tEmail  string\n\tDetour string\n}\n\nfunc (m *AccessMessage) String() string {\n\tbuilder := strings.Builder{}\n\tbuilder.WriteString(serial.ToString(m.From))\n\tbuilder.WriteByte(' ')\n\tbuilder.WriteString(string(m.Status))\n\tbuilder.WriteByte(' ')\n\tbuilder.WriteString(serial.ToString(m.To))\n\n\tif len(m.Detour) > 0 {\n\t\tbuilder.WriteString(\" [\")\n\t\tbuilder.WriteString(m.Detour)\n\t\tbuilder.WriteByte(']')\n\t}\n\n\tif reason := serial.ToString(m.Reason); len(reason) > 0 {\n\t\tbuilder.WriteString(\" \")\n\t\tbuilder.WriteString(reason)\n\t}\n\n\tif len(m.Email) > 0 {\n\t\tbuilder.WriteString(\" email: \")\n\t\tbuilder.WriteString(m.Email)\n\t}\n\n\treturn builder.String()\n}\n\nfunc ContextWithAccessMessage(ctx context.Context, accessMessage *AccessMessage) context.Context {\n\treturn context.WithValue(ctx, accessMessageKey, accessMessage)\n}\n\nfunc AccessMessageFromContext(ctx context.Context) *AccessMessage {\n\tif accessMessage, ok := ctx.Value(accessMessageKey).(*AccessMessage); ok {\n\t\treturn accessMessage\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "common/log/log.go",
    "content": "package log\n\nimport (\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\n// Message is the interface for all log messages.\ntype Message interface {\n\tString() string\n}\n\n// Handler is the interface for log handler.\ntype Handler interface {\n\tHandle(msg Message)\n}\n\n// Follower is the interface for following logs.\ntype Follower interface {\n\tAddFollower(func(msg Message))\n\tRemoveFollower(func(msg Message))\n}\n\n// GeneralMessage is a general log message that can contain all kind of content.\ntype GeneralMessage struct {\n\tSeverity Severity\n\tContent  interface{}\n}\n\n// String implements Message.\nfunc (m *GeneralMessage) String() string {\n\treturn serial.Concat(\"[\", m.Severity, \"] \", m.Content)\n}\n\n// Record writes a message into log stream.\nfunc Record(msg Message) {\n\tlogHandler.Handle(msg)\n}\n\nvar logHandler syncHandler\n\n// RegisterHandler register a new handler as current log handler. Previous registered handler will be discarded.\nfunc RegisterHandler(handler Handler) {\n\tif handler == nil {\n\t\tpanic(\"Log handler is nil\")\n\t}\n\tlogHandler.Set(handler)\n}\n\ntype syncHandler struct {\n\tsync.RWMutex\n\tHandler\n}\n\nfunc (h *syncHandler) Handle(msg Message) {\n\th.RLock()\n\tdefer h.RUnlock()\n\n\tif h.Handler != nil {\n\t\th.Handler.Handle(msg)\n\t}\n}\n\nfunc (h *syncHandler) Set(handler Handler) {\n\th.Lock()\n\tdefer h.Unlock()\n\n\th.Handler = handler\n}\n"
  },
  {
    "path": "common/log/log.pb.go",
    "content": "package log\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Severity int32\n\nconst (\n\tSeverity_Unknown Severity = 0\n\tSeverity_Error   Severity = 1\n\tSeverity_Warning Severity = 2\n\tSeverity_Info    Severity = 3\n\tSeverity_Debug   Severity = 4\n)\n\n// Enum value maps for Severity.\nvar (\n\tSeverity_name = map[int32]string{\n\t\t0: \"Unknown\",\n\t\t1: \"Error\",\n\t\t2: \"Warning\",\n\t\t3: \"Info\",\n\t\t4: \"Debug\",\n\t}\n\tSeverity_value = map[string]int32{\n\t\t\"Unknown\": 0,\n\t\t\"Error\":   1,\n\t\t\"Warning\": 2,\n\t\t\"Info\":    3,\n\t\t\"Debug\":   4,\n\t}\n)\n\nfunc (x Severity) Enum() *Severity {\n\tp := new(Severity)\n\t*p = x\n\treturn p\n}\n\nfunc (x Severity) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Severity) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_common_log_log_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Severity) Type() protoreflect.EnumType {\n\treturn &file_common_log_log_proto_enumTypes[0]\n}\n\nfunc (x Severity) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Severity.Descriptor instead.\nfunc (Severity) EnumDescriptor() ([]byte, []int) {\n\treturn file_common_log_log_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_common_log_log_proto protoreflect.FileDescriptor\n\nconst file_common_log_log_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x14common/log/log.proto\\x12\\x15v2ray.core.common.log*D\\n\" +\n\t\"\\bSeverity\\x12\\v\\n\" +\n\t\"\\aUnknown\\x10\\x00\\x12\\t\\n\" +\n\t\"\\x05Error\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aWarning\\x10\\x02\\x12\\b\\n\" +\n\t\"\\x04Info\\x10\\x03\\x12\\t\\n\" +\n\t\"\\x05Debug\\x10\\x04B`\\n\" +\n\t\"\\x19com.v2ray.core.common.logP\\x01Z)github.com/v2fly/v2ray-core/v5/common/log\\xaa\\x02\\x15V2Ray.Core.Common.Logb\\x06proto3\"\n\nvar (\n\tfile_common_log_log_proto_rawDescOnce sync.Once\n\tfile_common_log_log_proto_rawDescData []byte\n)\n\nfunc file_common_log_log_proto_rawDescGZIP() []byte {\n\tfile_common_log_log_proto_rawDescOnce.Do(func() {\n\t\tfile_common_log_log_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_log_log_proto_rawDesc), len(file_common_log_log_proto_rawDesc)))\n\t})\n\treturn file_common_log_log_proto_rawDescData\n}\n\nvar file_common_log_log_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_common_log_log_proto_goTypes = []any{\n\t(Severity)(0), // 0: v2ray.core.common.log.Severity\n}\nvar file_common_log_log_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_common_log_log_proto_init() }\nfunc file_common_log_log_proto_init() {\n\tif File_common_log_log_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: unsafe.Slice(unsafe.StringData(file_common_log_log_proto_rawDesc), len(file_common_log_log_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   0,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_log_log_proto_goTypes,\n\t\tDependencyIndexes: file_common_log_log_proto_depIdxs,\n\t\tEnumInfos:         file_common_log_log_proto_enumTypes,\n\t}.Build()\n\tFile_common_log_log_proto = out.File\n\tfile_common_log_log_proto_goTypes = nil\n\tfile_common_log_log_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/log/log.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.log;\noption csharp_namespace = \"V2Ray.Core.Common.Log\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/log\";\noption java_package = \"com.v2ray.core.common.log\";\noption java_multiple_files = true;\n\nenum Severity {\n  Unknown = 0;\n  Error = 1;\n  Warning = 2;\n  Info = 3;\n  Debug = 4;\n}\n"
  },
  {
    "path": "common/log/log_test.go",
    "content": "package log_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype testLogger struct {\n\tvalue string\n}\n\nfunc (l *testLogger) Handle(msg log.Message) {\n\tl.value = msg.String()\n}\n\nfunc TestLogRecord(t *testing.T) {\n\tvar logger testLogger\n\tlog.RegisterHandler(&logger)\n\n\tip := \"8.8.8.8\"\n\tlog.Record(&log.GeneralMessage{\n\t\tSeverity: log.Severity_Error,\n\t\tContent:  net.ParseAddress(ip),\n\t})\n\n\tif diff := cmp.Diff(\"[Error] \"+ip, logger.value); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "common/log/logger.go",
    "content": "package log\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/semaphore\"\n)\n\n// Writer is the interface for writing logs.\ntype Writer interface {\n\tWrite(string) error\n\tio.Closer\n}\n\n// WriterCreator is a function to create LogWriters.\ntype WriterCreator func() Writer\n\ntype generalLogger struct {\n\tcreator WriterCreator\n\tbuffer  chan Message\n\taccess  *semaphore.Instance\n\tdone    *done.Instance\n}\n\n// NewLogger returns a generic log handler that can handle all type of messages.\nfunc NewLogger(logWriterCreator WriterCreator) Handler {\n\treturn &generalLogger{\n\t\tcreator: logWriterCreator,\n\t\tbuffer:  make(chan Message, 16),\n\t\taccess:  semaphore.New(1),\n\t\tdone:    done.New(),\n\t}\n}\n\nfunc (l *generalLogger) run() {\n\tdefer l.access.Signal()\n\n\tdataWritten := false\n\tticker := time.NewTicker(time.Minute)\n\tdefer ticker.Stop()\n\n\tlogger := l.creator()\n\tif logger == nil {\n\t\treturn\n\t}\n\tdefer logger.Close()\n\n\tfor {\n\t\tselect {\n\t\tcase <-l.done.Wait():\n\t\t\treturn\n\t\tcase msg := <-l.buffer:\n\t\t\tlogger.Write(msg.String() + platform.LineSeparator())\n\t\t\tdataWritten = true\n\t\tcase <-ticker.C:\n\t\t\tif !dataWritten {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdataWritten = false\n\t\t}\n\t}\n}\n\nfunc (l *generalLogger) Handle(msg Message) {\n\tselect {\n\tcase l.buffer <- msg:\n\tdefault:\n\t}\n\n\tselect {\n\tcase <-l.access.Wait():\n\t\tgo l.run()\n\tdefault:\n\t}\n}\n\nfunc (l *generalLogger) Close() error {\n\treturn l.done.Close()\n}\n\ntype consoleLogWriter struct {\n\tlogger *log.Logger\n}\n\nfunc (w *consoleLogWriter) Write(s string) error {\n\tw.logger.Print(s)\n\treturn nil\n}\n\nfunc (w *consoleLogWriter) Close() error {\n\treturn nil\n}\n\ntype fileLogWriter struct {\n\tfile   *os.File\n\tlogger *log.Logger\n}\n\nfunc (w *fileLogWriter) Write(s string) error {\n\tw.logger.Print(s)\n\treturn nil\n}\n\nfunc (w *fileLogWriter) Close() error {\n\treturn w.file.Close()\n}\n\n// CreateStdoutLogWriter returns a LogWriterCreator that creates LogWriter for stdout.\nfunc CreateStdoutLogWriter() WriterCreator {\n\treturn func() Writer {\n\t\treturn &consoleLogWriter{\n\t\t\tlogger: log.New(os.Stdout, \"\", log.Ldate|log.Ltime),\n\t\t}\n\t}\n}\n\n// CreateStderrLogWriter returns a LogWriterCreator that creates LogWriter for stderr.\nfunc CreateStderrLogWriter() WriterCreator {\n\treturn func() Writer {\n\t\treturn &consoleLogWriter{\n\t\t\tlogger: log.New(os.Stderr, \"\", log.Ldate|log.Ltime),\n\t\t}\n\t}\n}\n\n// CreateFileLogWriter returns a LogWriterCreator that creates LogWriter for the given file.\nfunc CreateFileLogWriter(path string) (WriterCreator, error) {\n\tfile, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfile.Close()\n\treturn func() Writer {\n\t\tfile, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0o600)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn &fileLogWriter{\n\t\t\tfile:   file,\n\t\t\tlogger: log.New(file, \"\", log.Ldate|log.Ltime),\n\t\t}\n\t}, nil\n}\n\nfunc init() {\n\tRegisterHandler(NewLogger(CreateStdoutLogWriter()))\n}\n"
  },
  {
    "path": "common/log/logger_test.go",
    "content": "package log_test\n\nimport (\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\nfunc TestFileLogger(t *testing.T) {\n\tf, err := os.CreateTemp(\"\", \"vtest\")\n\tcommon.Must(err)\n\tpath := f.Name()\n\tcommon.Must(f.Close())\n\n\tcreator, err := CreateFileLogWriter(path)\n\tcommon.Must(err)\n\n\thandler := NewLogger(creator)\n\thandler.Handle(&GeneralMessage{Content: \"Test Log\"})\n\ttime.Sleep(2 * time.Second)\n\n\tcommon.Must(common.Close(handler))\n\n\tf, err = os.Open(path)\n\tcommon.Must(err)\n\tdefer f.Close()\n\n\tb, err := buf.ReadAllToBytes(f)\n\tcommon.Must(err)\n\tif !strings.Contains(string(b), \"Test Log\") {\n\t\tt.Fatal(\"Expect log text contains 'Test Log', but actually: \", string(b))\n\t}\n}\n"
  },
  {
    "path": "common/mux/client.go",
    "content": "package mux\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\ntype ClientManager struct {\n\tEnabled bool // wheather mux is enabled from user config\n\tPicker  WorkerPicker\n}\n\nfunc (m *ClientManager) Dispatch(ctx context.Context, link *transport.Link) error {\n\tfor i := 0; i < 16; i++ {\n\t\tworker, err := m.Picker.PickAvailable()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif worker.Dispatch(ctx, link) {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn newError(\"unable to find an available mux client\").AtWarning()\n}\n\ntype WorkerPicker interface {\n\tPickAvailable() (*ClientWorker, error)\n}\n\ntype IncrementalWorkerPicker struct {\n\tFactory ClientWorkerFactory\n\n\taccess      sync.Mutex\n\tworkers     []*ClientWorker\n\tcleanupTask *task.Periodic\n}\n\nfunc (p *IncrementalWorkerPicker) cleanupFunc() error {\n\tp.access.Lock()\n\tdefer p.access.Unlock()\n\n\tif len(p.workers) == 0 {\n\t\treturn newError(\"no worker\")\n\t}\n\n\tp.cleanup()\n\treturn nil\n}\n\nfunc (p *IncrementalWorkerPicker) cleanup() {\n\tvar activeWorkers []*ClientWorker\n\tfor _, w := range p.workers {\n\t\tif !w.Closed() {\n\t\t\tactiveWorkers = append(activeWorkers, w)\n\t\t}\n\t}\n\tp.workers = activeWorkers\n}\n\nfunc (p *IncrementalWorkerPicker) findAvailable() int {\n\tfor idx, w := range p.workers {\n\t\tif !w.IsFull() {\n\t\t\treturn idx\n\t\t}\n\t}\n\n\treturn -1\n}\n\nfunc (p *IncrementalWorkerPicker) pickInternal() (*ClientWorker, bool, error) {\n\tp.access.Lock()\n\tdefer p.access.Unlock()\n\n\tidx := p.findAvailable()\n\tif idx >= 0 {\n\t\tn := len(p.workers)\n\t\tif n > 1 && idx != n-1 {\n\t\t\tp.workers[n-1], p.workers[idx] = p.workers[idx], p.workers[n-1]\n\t\t}\n\t\treturn p.workers[idx], false, nil\n\t}\n\n\tp.cleanup()\n\n\tworker, err := p.Factory.Create()\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tp.workers = append(p.workers, worker)\n\n\tif p.cleanupTask == nil {\n\t\tp.cleanupTask = &task.Periodic{\n\t\t\tInterval: time.Second * 30,\n\t\t\tExecute:  p.cleanupFunc,\n\t\t}\n\t}\n\n\treturn worker, true, nil\n}\n\nfunc (p *IncrementalWorkerPicker) PickAvailable() (*ClientWorker, error) {\n\tworker, start, err := p.pickInternal()\n\tif start {\n\t\tcommon.Must(p.cleanupTask.Start())\n\t}\n\n\treturn worker, err\n}\n\ntype ClientWorkerFactory interface {\n\tCreate() (*ClientWorker, error)\n}\n\ntype DialingWorkerFactory struct {\n\tProxy    proxy.Outbound\n\tDialer   internet.Dialer\n\tStrategy ClientStrategy\n\n\tctx context.Context\n}\n\nfunc NewDialingWorkerFactory(ctx context.Context, proxy proxy.Outbound, dialer internet.Dialer, strategy ClientStrategy) *DialingWorkerFactory {\n\treturn &DialingWorkerFactory{\n\t\tProxy:    proxy,\n\t\tDialer:   dialer,\n\t\tStrategy: strategy,\n\t\tctx:      ctx,\n\t}\n}\n\nfunc (f *DialingWorkerFactory) Create() (*ClientWorker, error) {\n\topts := []pipe.Option{pipe.WithSizeLimit(64 * 1024)}\n\tuplinkReader, upLinkWriter := pipe.New(opts...)\n\tdownlinkReader, downlinkWriter := pipe.New(opts...)\n\n\tc, err := NewClientWorker(transport.Link{\n\t\tReader: downlinkReader,\n\t\tWriter: upLinkWriter,\n\t}, f.Strategy)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tgo func(p proxy.Outbound, d internet.Dialer, c common.Closable) {\n\t\tctx := session.ContextWithOutbound(f.ctx, &session.Outbound{\n\t\t\tTarget: net.TCPDestination(muxCoolAddress, muxCoolPort),\n\t\t})\n\t\tctx, cancel := context.WithCancel(ctx)\n\n\t\tif err := p.Process(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter}, d); err != nil {\n\t\t\terrors.New(\"failed to handler mux client connection\").Base(err).WriteToLog()\n\t\t}\n\t\tcommon.Must(c.Close())\n\t\tcancel()\n\t}(f.Proxy, f.Dialer, c.done)\n\n\treturn c, nil\n}\n\ntype ClientStrategy struct {\n\tMaxConcurrency uint32\n\tMaxConnection  uint32\n}\n\ntype ClientWorker struct {\n\tsessionManager *SessionManager\n\tlink           transport.Link\n\tdone           *done.Instance\n\tstrategy       ClientStrategy\n}\n\nvar (\n\tmuxCoolAddress = net.DomainAddress(\"v1.mux.cool\")\n\tmuxCoolPort    = net.Port(9527)\n)\n\n// NewClientWorker creates a new mux.Client.\nfunc NewClientWorker(stream transport.Link, s ClientStrategy) (*ClientWorker, error) {\n\tc := &ClientWorker{\n\t\tsessionManager: NewSessionManager(),\n\t\tlink:           stream,\n\t\tdone:           done.New(),\n\t\tstrategy:       s,\n\t}\n\n\tgo c.fetchOutput()\n\tgo c.monitor()\n\n\treturn c, nil\n}\n\nfunc (m *ClientWorker) TotalConnections() uint32 {\n\treturn uint32(m.sessionManager.Count())\n}\n\nfunc (m *ClientWorker) ActiveConnections() uint32 {\n\treturn uint32(m.sessionManager.Size())\n}\n\n// Closed returns true if this Client is closed.\nfunc (m *ClientWorker) Closed() bool {\n\treturn m.done.Done()\n}\n\nfunc (m *ClientWorker) monitor() {\n\ttimer := time.NewTicker(time.Second * 16)\n\tdefer timer.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-m.done.Wait():\n\t\t\tm.sessionManager.Close()\n\t\t\tcommon.Close(m.link.Writer)\n\t\t\tcommon.Interrupt(m.link.Reader)\n\t\t\treturn\n\t\tcase <-timer.C:\n\t\t\tsize := m.sessionManager.Size()\n\t\t\tif size == 0 && m.sessionManager.CloseIfNoSession() {\n\t\t\t\tcommon.Must(m.done.Close())\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc writeFirstPayload(reader buf.Reader, writer *Writer) error {\n\terr := buf.CopyOnceTimeout(reader, writer, time.Millisecond*100)\n\tif err == buf.ErrNotTimeoutReader || err == buf.ErrReadTimeout {\n\t\treturn writer.WriteMultiBuffer(buf.MultiBuffer{})\n\t}\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc fetchInput(ctx context.Context, s *Session, output buf.Writer) {\n\tdest := session.OutboundFromContext(ctx).Target\n\ttransferType := protocol.TransferTypeStream\n\tif dest.Network == net.Network_UDP {\n\t\ttransferType = protocol.TransferTypePacket\n\t}\n\ts.transferType = transferType\n\twriter := NewWriter(s.ID, dest, output, transferType)\n\tdefer s.Close()\n\tdefer writer.Close()\n\n\tnewError(\"dispatching request to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\tif err := writeFirstPayload(s.input, writer); err != nil {\n\t\tnewError(\"failed to write first payload\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\twriter.hasError = true\n\t\tcommon.Interrupt(s.input)\n\t\treturn\n\t}\n\n\tif err := buf.Copy(s.input, writer); err != nil {\n\t\tnewError(\"failed to fetch all input\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\twriter.hasError = true\n\t\tcommon.Interrupt(s.input)\n\t\treturn\n\t}\n}\n\nfunc (m *ClientWorker) IsClosing() bool {\n\tsm := m.sessionManager\n\tif m.strategy.MaxConnection > 0 && sm.Count() >= int(m.strategy.MaxConnection) {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (m *ClientWorker) IsFull() bool {\n\tif m.IsClosing() || m.Closed() {\n\t\treturn true\n\t}\n\n\tsm := m.sessionManager\n\tif m.strategy.MaxConcurrency > 0 && sm.Size() >= int(m.strategy.MaxConcurrency) {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (m *ClientWorker) Dispatch(ctx context.Context, link *transport.Link) bool {\n\tif m.IsFull() || m.Closed() {\n\t\treturn false\n\t}\n\n\tsm := m.sessionManager\n\ts := sm.Allocate()\n\tif s == nil {\n\t\treturn false\n\t}\n\ts.input = link.Reader\n\ts.output = link.Writer\n\tgo fetchInput(ctx, s, m.link.Writer)\n\treturn true\n}\n\nfunc (m *ClientWorker) handleStatueKeepAlive(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif meta.Option.Has(OptionData) {\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\treturn nil\n}\n\nfunc (m *ClientWorker) handleStatusNew(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif meta.Option.Has(OptionData) {\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\treturn nil\n}\n\nfunc (m *ClientWorker) handleStatusKeep(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif !meta.Option.Has(OptionData) {\n\t\treturn nil\n\t}\n\n\ts, found := m.sessionManager.Get(meta.SessionID)\n\tif !found {\n\t\t// Notify remote peer to close this session.\n\t\tclosingWriter := NewResponseWriter(meta.SessionID, m.link.Writer, protocol.TransferTypeStream)\n\t\tclosingWriter.Close()\n\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\n\trr := s.NewReader(reader)\n\terr := buf.Copy(rr, s.output)\n\tif err != nil && buf.IsWriteError(err) {\n\t\tnewError(\"failed to write to downstream. closing session \", s.ID).Base(err).WriteToLog()\n\n\t\t// Notify remote peer to close this session.\n\t\tclosingWriter := NewResponseWriter(meta.SessionID, m.link.Writer, protocol.TransferTypeStream)\n\t\tclosingWriter.Close()\n\n\t\tdrainErr := buf.Copy(rr, buf.Discard)\n\t\tcommon.Interrupt(s.input)\n\t\ts.Close()\n\t\treturn drainErr\n\t}\n\n\treturn err\n}\n\nfunc (m *ClientWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif s, found := m.sessionManager.Get(meta.SessionID); found {\n\t\tif meta.Option.Has(OptionError) {\n\t\t\tcommon.Interrupt(s.input)\n\t\t\tcommon.Interrupt(s.output)\n\t\t}\n\t\ts.Close()\n\t}\n\tif meta.Option.Has(OptionData) {\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\treturn nil\n}\n\nfunc (m *ClientWorker) fetchOutput() {\n\tdefer func() {\n\t\tcommon.Must(m.done.Close())\n\t}()\n\n\treader := &buf.BufferedReader{Reader: m.link.Reader}\n\n\tvar meta FrameMetadata\n\tfor {\n\t\terr := meta.Unmarshal(reader)\n\t\tif err != nil {\n\t\t\tif errors.Cause(err) != io.EOF {\n\t\t\t\tnewError(\"failed to read metadata\").Base(err).WriteToLog()\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tswitch meta.SessionStatus {\n\t\tcase SessionStatusKeepAlive:\n\t\t\terr = m.handleStatueKeepAlive(&meta, reader)\n\t\tcase SessionStatusEnd:\n\t\t\terr = m.handleStatusEnd(&meta, reader)\n\t\tcase SessionStatusNew:\n\t\t\terr = m.handleStatusNew(&meta, reader)\n\t\tcase SessionStatusKeep:\n\t\t\terr = m.handleStatusKeep(&meta, reader)\n\t\tdefault:\n\t\t\tstatus := meta.SessionStatus\n\t\t\tnewError(\"unknown status: \", status).AtError().WriteToLog()\n\t\t\treturn\n\t\t}\n\n\t\tif err != nil {\n\t\t\tnewError(\"failed to process data\").Base(err).WriteToLog()\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/mux/client_test.go",
    "content": "package mux_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/mock/gomock\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/mocks\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc TestIncrementalPickerFailure(t *testing.T) {\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tmockWorkerFactory := mocks.NewMuxClientWorkerFactory(mockCtl)\n\tmockWorkerFactory.EXPECT().Create().Return(nil, errors.New(\"test\"))\n\n\tpicker := mux.IncrementalWorkerPicker{\n\t\tFactory: mockWorkerFactory,\n\t}\n\n\t_, err := picker.PickAvailable()\n\tif err == nil {\n\t\tt.Error(\"expected error, but nil\")\n\t}\n}\n\nfunc TestClientWorkerEOF(t *testing.T) {\n\treader, writer := pipe.New(pipe.WithoutSizeLimit())\n\tcommon.Must(writer.Close())\n\n\tworker, err := mux.NewClientWorker(transport.Link{Reader: reader, Writer: writer}, mux.ClientStrategy{})\n\tcommon.Must(err)\n\n\ttime.Sleep(time.Millisecond * 500)\n\n\tf := worker.Dispatch(context.Background(), nil)\n\tif f {\n\t\tt.Error(\"expected failed dispatching, but actually not\")\n\t}\n}\n\nfunc TestClientWorkerClose(t *testing.T) {\n\tmockCtl := gomock.NewController(t)\n\tdefer mockCtl.Finish()\n\n\tr1, w1 := pipe.New(pipe.WithoutSizeLimit())\n\tworker1, err := mux.NewClientWorker(transport.Link{\n\t\tReader: r1,\n\t\tWriter: w1,\n\t}, mux.ClientStrategy{\n\t\tMaxConcurrency: 4,\n\t\tMaxConnection:  4,\n\t})\n\tcommon.Must(err)\n\n\tr2, w2 := pipe.New(pipe.WithoutSizeLimit())\n\tworker2, err := mux.NewClientWorker(transport.Link{\n\t\tReader: r2,\n\t\tWriter: w2,\n\t}, mux.ClientStrategy{\n\t\tMaxConcurrency: 4,\n\t\tMaxConnection:  4,\n\t})\n\tcommon.Must(err)\n\n\tfactory := mocks.NewMuxClientWorkerFactory(mockCtl)\n\tgomock.InOrder(\n\t\tfactory.EXPECT().Create().Return(worker1, nil),\n\t\tfactory.EXPECT().Create().Return(worker2, nil),\n\t)\n\n\tpicker := &mux.IncrementalWorkerPicker{\n\t\tFactory: factory,\n\t}\n\tmanager := &mux.ClientManager{\n\t\tPicker: picker,\n\t}\n\n\ttr1, tw1 := pipe.New(pipe.WithoutSizeLimit())\n\tctx1 := session.ContextWithOutbound(context.Background(), &session.Outbound{\n\t\tTarget: net.TCPDestination(net.DomainAddress(\"www.v2fly.org\"), 80),\n\t})\n\tcommon.Must(manager.Dispatch(ctx1, &transport.Link{\n\t\tReader: tr1,\n\t\tWriter: tw1,\n\t}))\n\tdefer tw1.Close()\n\n\tcommon.Must(w1.Close())\n\n\ttime.Sleep(time.Millisecond * 500)\n\tif !worker1.Closed() {\n\t\tt.Error(\"worker1 is not finished\")\n\t}\n\n\ttr2, tw2 := pipe.New(pipe.WithoutSizeLimit())\n\tctx2 := session.ContextWithOutbound(context.Background(), &session.Outbound{\n\t\tTarget: net.TCPDestination(net.DomainAddress(\"www.v2fly.org\"), 80),\n\t})\n\tcommon.Must(manager.Dispatch(ctx2, &transport.Link{\n\t\tReader: tr2,\n\t\tWriter: tw2,\n\t}))\n\tdefer tw2.Close()\n\n\tcommon.Must(w2.Close())\n}\n"
  },
  {
    "path": "common/mux/errors.generated.go",
    "content": "package mux\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/mux/frame.go",
    "content": "package mux\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/bitmask\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype SessionStatus byte\n\nconst (\n\tSessionStatusNew       SessionStatus = 0x01\n\tSessionStatusKeep      SessionStatus = 0x02\n\tSessionStatusEnd       SessionStatus = 0x03\n\tSessionStatusKeepAlive SessionStatus = 0x04\n)\n\nconst (\n\tOptionData  bitmask.Byte = 0x01\n\tOptionError bitmask.Byte = 0x02\n)\n\ntype TargetNetwork byte\n\nconst (\n\tTargetNetworkTCP TargetNetwork = 0x01\n\tTargetNetworkUDP TargetNetwork = 0x02\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain),\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6),\n\tprotocol.PortThenAddress(),\n)\n\n/*\nFrame format\n2 bytes - length\n2 bytes - session id\n1 bytes - status\n1 bytes - option\n\n1 byte - network\n2 bytes - port\nn bytes - address\n\n*/\n\ntype FrameMetadata struct {\n\tTarget        net.Destination\n\tSessionID     uint16\n\tOption        bitmask.Byte\n\tSessionStatus SessionStatus\n}\n\nfunc (f FrameMetadata) WriteTo(b *buf.Buffer) error {\n\tlenBytes := b.Extend(2)\n\n\tlen0 := b.Len()\n\tsessionBytes := b.Extend(2)\n\tbinary.BigEndian.PutUint16(sessionBytes, f.SessionID)\n\n\tcommon.Must(b.WriteByte(byte(f.SessionStatus)))\n\tcommon.Must(b.WriteByte(byte(f.Option)))\n\n\tif f.SessionStatus == SessionStatusNew {\n\t\tswitch f.Target.Network {\n\t\tcase net.Network_TCP:\n\t\t\tcommon.Must(b.WriteByte(byte(TargetNetworkTCP)))\n\t\tcase net.Network_UDP:\n\t\t\tcommon.Must(b.WriteByte(byte(TargetNetworkUDP)))\n\t\t}\n\n\t\tif err := addrParser.WriteAddressPort(b, f.Target.Address, f.Target.Port); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tlen1 := b.Len()\n\tbinary.BigEndian.PutUint16(lenBytes, uint16(len1-len0))\n\treturn nil\n}\n\n// Unmarshal reads FrameMetadata from the given reader.\nfunc (f *FrameMetadata) Unmarshal(reader io.Reader) error {\n\tmetaLen, err := serial.ReadUint16(reader)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif metaLen > 512 {\n\t\treturn newError(\"invalid metalen \", metaLen).AtError()\n\t}\n\n\tb := buf.New()\n\tdefer b.Release()\n\n\tif _, err := b.ReadFullFrom(reader, int32(metaLen)); err != nil {\n\t\treturn err\n\t}\n\treturn f.UnmarshalFromBuffer(b)\n}\n\n// UnmarshalFromBuffer reads a FrameMetadata from the given buffer.\n// Visible for testing only.\nfunc (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {\n\tif b.Len() < 4 {\n\t\treturn newError(\"insufficient buffer: \", b.Len())\n\t}\n\n\tf.SessionID = binary.BigEndian.Uint16(b.BytesTo(2))\n\tf.SessionStatus = SessionStatus(b.Byte(2))\n\tf.Option = bitmask.Byte(b.Byte(3))\n\tf.Target.Network = net.Network_Unknown\n\n\tif f.SessionStatus == SessionStatusNew {\n\t\tif b.Len() < 8 {\n\t\t\treturn newError(\"insufficient buffer: \", b.Len())\n\t\t}\n\t\tnetwork := TargetNetwork(b.Byte(4))\n\t\tb.Advance(5)\n\n\t\taddr, port, err := addrParser.ReadAddressPort(nil, b)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to parse address and port\").Base(err)\n\t\t}\n\n\t\tswitch network {\n\t\tcase TargetNetworkTCP:\n\t\t\tf.Target = net.TCPDestination(addr, port)\n\t\tcase TargetNetworkUDP:\n\t\t\tf.Target = net.UDPDestination(addr, port)\n\t\tdefault:\n\t\t\treturn newError(\"unknown network type: \", network)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "common/mux/frame_test.go",
    "content": "package mux_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc BenchmarkFrameWrite(b *testing.B) {\n\tframe := mux.FrameMetadata{\n\t\tTarget:        net.TCPDestination(net.DomainAddress(\"www.v2fly.org\"), net.Port(80)),\n\t\tSessionID:     1,\n\t\tSessionStatus: mux.SessionStatusNew,\n\t}\n\twriter := buf.New()\n\tdefer writer.Release()\n\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(frame.WriteTo(writer))\n\t\twriter.Clear()\n\t}\n}\n"
  },
  {
    "path": "common/mux/mux.go",
    "content": "package mux\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/mux/mux_test.go",
    "content": "package mux_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/mux\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc readAll(reader buf.Reader) (buf.MultiBuffer, error) {\n\tvar mb buf.MultiBuffer\n\tfor {\n\t\tb, err := reader.ReadMultiBuffer()\n\t\tif 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\tmb = append(mb, b...)\n\t}\n\treturn mb, nil\n}\n\nfunc TestReaderWriter(t *testing.T) {\n\tpReader, pWriter := pipe.New(pipe.WithSizeLimit(1024))\n\n\tdest := net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80)\n\twriter := NewWriter(1, dest, pWriter, protocol.TransferTypeStream)\n\n\tdest2 := net.TCPDestination(net.LocalHostIP, 443)\n\twriter2 := NewWriter(2, dest2, pWriter, protocol.TransferTypeStream)\n\n\tdest3 := net.TCPDestination(net.LocalHostIPv6, 18374)\n\twriter3 := NewWriter(3, dest3, pWriter, protocol.TransferTypeStream)\n\n\twritePayload := func(writer *Writer, payload ...byte) error {\n\t\tb := buf.New()\n\t\tb.Write(payload)\n\t\treturn writer.WriteMultiBuffer(buf.MultiBuffer{b})\n\t}\n\n\tcommon.Must(writePayload(writer, 'a', 'b', 'c', 'd'))\n\tcommon.Must(writePayload(writer2))\n\n\tcommon.Must(writePayload(writer, 'e', 'f', 'g', 'h'))\n\tcommon.Must(writePayload(writer3, 'x'))\n\n\twriter.Close()\n\twriter3.Close()\n\n\tcommon.Must(writePayload(writer2, 'y'))\n\twriter2.Close()\n\n\tbytesReader := &buf.BufferedReader{Reader: pReader}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     1,\n\t\t\tSessionStatus: SessionStatusNew,\n\t\t\tTarget:        dest,\n\t\t\tOption:        OptionData,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"metadata: \", r)\n\t\t}\n\n\t\tdata, err := readAll(NewStreamReader(bytesReader))\n\t\tcommon.Must(err)\n\t\tif s := data.String(); s != \"abcd\" {\n\t\t\tt.Error(\"data: \", s)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionStatus: SessionStatusNew,\n\t\t\tSessionID:     2,\n\t\t\tOption:        0,\n\t\t\tTarget:        dest2,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     1,\n\t\t\tSessionStatus: SessionStatusKeep,\n\t\t\tOption:        1,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\n\t\tdata, err := readAll(NewStreamReader(bytesReader))\n\t\tcommon.Must(err)\n\t\tif s := data.String(); s != \"efgh\" {\n\t\t\tt.Error(\"data: \", s)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     3,\n\t\t\tSessionStatus: SessionStatusNew,\n\t\t\tOption:        1,\n\t\t\tTarget:        dest3,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\n\t\tdata, err := readAll(NewStreamReader(bytesReader))\n\t\tcommon.Must(err)\n\t\tif s := data.String(); s != \"x\" {\n\t\t\tt.Error(\"data: \", s)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     1,\n\t\t\tSessionStatus: SessionStatusEnd,\n\t\t\tOption:        0,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     3,\n\t\t\tSessionStatus: SessionStatusEnd,\n\t\t\tOption:        0,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     2,\n\t\t\tSessionStatus: SessionStatusKeep,\n\t\t\tOption:        1,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\n\t\tdata, err := readAll(NewStreamReader(bytesReader))\n\t\tcommon.Must(err)\n\t\tif s := data.String(); s != \"y\" {\n\t\t\tt.Error(\"data: \", s)\n\t\t}\n\t}\n\n\t{\n\t\tvar meta FrameMetadata\n\t\tcommon.Must(meta.Unmarshal(bytesReader))\n\t\tif r := cmp.Diff(meta, FrameMetadata{\n\t\t\tSessionID:     2,\n\t\t\tSessionStatus: SessionStatusEnd,\n\t\t\tOption:        0,\n\t\t}); r != \"\" {\n\t\t\tt.Error(\"meta: \", r)\n\t\t}\n\t}\n\n\tpWriter.Close()\n\n\t{\n\t\tvar meta FrameMetadata\n\t\terr := meta.Unmarshal(bytesReader)\n\t\tif err == nil {\n\t\t\tt.Error(\"nil error\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/mux/reader.go",
    "content": "package mux\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\n// PacketReader is an io.Reader that reads whole chunk of Mux frames every time.\ntype PacketReader struct {\n\treader io.Reader\n\teof    bool\n}\n\n// NewPacketReader creates a new PacketReader.\nfunc NewPacketReader(reader io.Reader) *PacketReader {\n\treturn &PacketReader{\n\t\treader: reader,\n\t\teof:    false,\n\t}\n}\n\n// ReadMultiBuffer implements buf.Reader.\nfunc (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tif r.eof {\n\t\treturn nil, io.EOF\n\t}\n\n\tsize, err := serial.ReadUint16(r.reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif size > buf.Size {\n\t\treturn nil, newError(\"packet size too large: \", size)\n\t}\n\n\tb := buf.New()\n\tif _, err := b.ReadFullFrom(r.reader, int32(size)); err != nil {\n\t\tb.Release()\n\t\treturn nil, err\n\t}\n\tr.eof = true\n\treturn buf.MultiBuffer{b}, nil\n}\n\n// NewStreamReader creates a new StreamReader.\nfunc NewStreamReader(reader *buf.BufferedReader) buf.Reader {\n\treturn crypto.NewChunkStreamReaderWithChunkCount(crypto.PlainChunkSizeParser{}, reader, 1)\n}\n"
  },
  {
    "path": "common/mux/server.go",
    "content": "package mux\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\ntype Server struct {\n\tdispatcher routing.Dispatcher\n}\n\n// NewServer creates a new mux.Server.\nfunc NewServer(ctx context.Context) *Server {\n\ts := &Server{}\n\tcore.RequireFeatures(ctx, func(d routing.Dispatcher) {\n\t\ts.dispatcher = d\n\t})\n\treturn s\n}\n\n// Type implements common.HasType.\nfunc (s *Server) Type() interface{} {\n\treturn s.dispatcher.Type()\n}\n\n// Dispatch implements routing.Dispatcher\nfunc (s *Server) Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error) {\n\tif dest.Address != muxCoolAddress {\n\t\treturn s.dispatcher.Dispatch(ctx, dest)\n\t}\n\n\topts := pipe.OptionsFromContext(ctx)\n\tuplinkReader, uplinkWriter := pipe.New(opts...)\n\tdownlinkReader, downlinkWriter := pipe.New(opts...)\n\n\t_, err := NewServerWorker(ctx, s.dispatcher, &transport.Link{\n\t\tReader: uplinkReader,\n\t\tWriter: downlinkWriter,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &transport.Link{Reader: downlinkReader, Writer: uplinkWriter}, nil\n}\n\n// Start implements common.Runnable.\nfunc (s *Server) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (s *Server) Close() error {\n\treturn nil\n}\n\ntype ServerWorker struct {\n\tdispatcher     routing.Dispatcher\n\tlink           *transport.Link\n\tsessionManager *SessionManager\n}\n\nfunc NewServerWorker(ctx context.Context, d routing.Dispatcher, link *transport.Link) (*ServerWorker, error) {\n\tworker := &ServerWorker{\n\t\tdispatcher:     d,\n\t\tlink:           link,\n\t\tsessionManager: NewSessionManager(),\n\t}\n\tgo worker.run(ctx)\n\treturn worker, nil\n}\n\nfunc handle(ctx context.Context, s *Session, output buf.Writer) {\n\twriter := NewResponseWriter(s.ID, output, s.transferType)\n\tif err := buf.Copy(s.input, writer); err != nil {\n\t\tnewError(\"session \", s.ID, \" ends.\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\twriter.hasError = true\n\t}\n\n\twriter.Close()\n\ts.Close()\n}\n\nfunc (w *ServerWorker) ActiveConnections() uint32 {\n\treturn uint32(w.sessionManager.Size())\n}\n\nfunc (w *ServerWorker) Closed() bool {\n\treturn w.sessionManager.Closed()\n}\n\nfunc (w *ServerWorker) handleStatusKeepAlive(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif meta.Option.Has(OptionData) {\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\treturn nil\n}\n\nfunc (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tnewError(\"received request for \", meta.Target).WriteToLog(session.ExportIDToError(ctx))\n\t{\n\t\tmsg := &log.AccessMessage{\n\t\t\tTo:     meta.Target,\n\t\t\tStatus: log.AccessAccepted,\n\t\t\tReason: \"\",\n\t\t}\n\t\tif inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {\n\t\t\tmsg.From = inbound.Source\n\t\t\tmsg.Email = inbound.User.Email\n\t\t}\n\t\tctx = log.ContextWithAccessMessage(ctx, msg)\n\t}\n\tlink, err := w.dispatcher.Dispatch(ctx, meta.Target)\n\tif err != nil {\n\t\tif meta.Option.Has(OptionData) {\n\t\t\tbuf.Copy(NewStreamReader(reader), buf.Discard)\n\t\t}\n\t\treturn newError(\"failed to dispatch request.\").Base(err)\n\t}\n\ts := &Session{\n\t\tinput:        link.Reader,\n\t\toutput:       link.Writer,\n\t\tparent:       w.sessionManager,\n\t\tID:           meta.SessionID,\n\t\ttransferType: protocol.TransferTypeStream,\n\t}\n\tif meta.Target.Network == net.Network_UDP {\n\t\ts.transferType = protocol.TransferTypePacket\n\t}\n\tw.sessionManager.Add(s)\n\tgo handle(ctx, s, w.link.Writer)\n\tif !meta.Option.Has(OptionData) {\n\t\treturn nil\n\t}\n\n\trr := s.NewReader(reader)\n\tif err := buf.Copy(rr, s.output); err != nil {\n\t\tbuf.Copy(rr, buf.Discard)\n\t\tcommon.Interrupt(s.input)\n\t\treturn s.Close()\n\t}\n\treturn nil\n}\n\nfunc (w *ServerWorker) handleStatusKeep(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif !meta.Option.Has(OptionData) {\n\t\treturn nil\n\t}\n\n\ts, found := w.sessionManager.Get(meta.SessionID)\n\tif !found {\n\t\t// Notify remote peer to close this session.\n\t\tclosingWriter := NewResponseWriter(meta.SessionID, w.link.Writer, protocol.TransferTypeStream)\n\t\tclosingWriter.Close()\n\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\n\trr := s.NewReader(reader)\n\terr := buf.Copy(rr, s.output)\n\n\tif err != nil && buf.IsWriteError(err) {\n\t\tnewError(\"failed to write to downstream writer. closing session \", s.ID).Base(err).WriteToLog()\n\n\t\t// Notify remote peer to close this session.\n\t\tclosingWriter := NewResponseWriter(meta.SessionID, w.link.Writer, protocol.TransferTypeStream)\n\t\tclosingWriter.Close()\n\n\t\tdrainErr := buf.Copy(rr, buf.Discard)\n\t\tcommon.Interrupt(s.input)\n\t\ts.Close()\n\t\treturn drainErr\n\t}\n\n\treturn err\n}\n\nfunc (w *ServerWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.BufferedReader) error {\n\tif s, found := w.sessionManager.Get(meta.SessionID); found {\n\t\tif meta.Option.Has(OptionError) {\n\t\t\tcommon.Interrupt(s.input)\n\t\t\tcommon.Interrupt(s.output)\n\t\t}\n\t\ts.Close()\n\t}\n\tif meta.Option.Has(OptionData) {\n\t\treturn buf.Copy(NewStreamReader(reader), buf.Discard)\n\t}\n\treturn nil\n}\n\nfunc (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedReader) error {\n\tvar meta FrameMetadata\n\terr := meta.Unmarshal(reader)\n\tif err != nil {\n\t\treturn newError(\"failed to read metadata\").Base(err)\n\t}\n\n\tswitch meta.SessionStatus {\n\tcase SessionStatusKeepAlive:\n\t\terr = w.handleStatusKeepAlive(&meta, reader)\n\tcase SessionStatusEnd:\n\t\terr = w.handleStatusEnd(&meta, reader)\n\tcase SessionStatusNew:\n\t\terr = w.handleStatusNew(ctx, &meta, reader)\n\tcase SessionStatusKeep:\n\t\terr = w.handleStatusKeep(&meta, reader)\n\tdefault:\n\t\tstatus := meta.SessionStatus\n\t\treturn newError(\"unknown status: \", status).AtError()\n\t}\n\n\tif err != nil {\n\t\treturn newError(\"failed to process data\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc (w *ServerWorker) run(ctx context.Context) {\n\tinput := w.link.Reader\n\treader := &buf.BufferedReader{Reader: input}\n\n\tdefer w.sessionManager.Close()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t\terr := w.handleFrame(ctx, reader)\n\t\t\tif err != nil {\n\t\t\t\tif errors.Cause(err) != io.EOF {\n\t\t\t\t\tnewError(\"unexpected EOF\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t\tcommon.Interrupt(input)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/mux/session.go",
    "content": "package mux\n\nimport (\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\ntype SessionManager struct {\n\tsync.RWMutex\n\tsessions map[uint16]*Session\n\tcount    uint16\n\tclosed   bool\n}\n\nfunc NewSessionManager() *SessionManager {\n\treturn &SessionManager{\n\t\tcount:    0,\n\t\tsessions: make(map[uint16]*Session, 16),\n\t}\n}\n\nfunc (m *SessionManager) Closed() bool {\n\tm.RLock()\n\tdefer m.RUnlock()\n\n\treturn m.closed\n}\n\nfunc (m *SessionManager) Size() int {\n\tm.RLock()\n\tdefer m.RUnlock()\n\n\treturn len(m.sessions)\n}\n\nfunc (m *SessionManager) Count() int {\n\tm.RLock()\n\tdefer m.RUnlock()\n\n\treturn int(m.count)\n}\n\nfunc (m *SessionManager) Allocate() *Session {\n\tm.Lock()\n\tdefer m.Unlock()\n\n\tif m.closed {\n\t\treturn nil\n\t}\n\n\tm.count++\n\ts := &Session{\n\t\tID:     m.count,\n\t\tparent: m,\n\t}\n\tm.sessions[s.ID] = s\n\treturn s\n}\n\nfunc (m *SessionManager) Add(s *Session) {\n\tm.Lock()\n\tdefer m.Unlock()\n\n\tif m.closed {\n\t\treturn\n\t}\n\n\tm.count++\n\tm.sessions[s.ID] = s\n}\n\nfunc (m *SessionManager) Remove(id uint16) {\n\tm.Lock()\n\tdefer m.Unlock()\n\n\tif m.closed {\n\t\treturn\n\t}\n\n\tdelete(m.sessions, id)\n\n\tif len(m.sessions) == 0 {\n\t\tm.sessions = make(map[uint16]*Session, 16)\n\t}\n}\n\nfunc (m *SessionManager) Get(id uint16) (*Session, bool) {\n\tm.RLock()\n\tdefer m.RUnlock()\n\n\tif m.closed {\n\t\treturn nil, false\n\t}\n\n\ts, found := m.sessions[id]\n\treturn s, found\n}\n\nfunc (m *SessionManager) CloseIfNoSession() bool {\n\tm.Lock()\n\tdefer m.Unlock()\n\n\tif m.closed {\n\t\treturn true\n\t}\n\n\tif len(m.sessions) != 0 {\n\t\treturn false\n\t}\n\n\tm.closed = true\n\treturn true\n}\n\nfunc (m *SessionManager) Close() error {\n\tm.Lock()\n\tdefer m.Unlock()\n\n\tif m.closed {\n\t\treturn nil\n\t}\n\n\tm.closed = true\n\n\tfor _, s := range m.sessions {\n\t\tcommon.Close(s.input)\n\t\tcommon.Close(s.output)\n\t}\n\n\tm.sessions = nil\n\treturn nil\n}\n\n// Session represents a client connection in a Mux connection.\ntype Session struct {\n\tinput        buf.Reader\n\toutput       buf.Writer\n\tparent       *SessionManager\n\tID           uint16\n\ttransferType protocol.TransferType\n}\n\n// Close closes all resources associated with this session.\nfunc (s *Session) Close() error {\n\tcommon.Close(s.output)\n\tcommon.Close(s.input)\n\ts.parent.Remove(s.ID)\n\treturn nil\n}\n\n// NewReader creates a buf.Reader based on the transfer type of this Session.\nfunc (s *Session) NewReader(reader *buf.BufferedReader) buf.Reader {\n\tif s.transferType == protocol.TransferTypeStream {\n\t\treturn NewStreamReader(reader)\n\t}\n\treturn NewPacketReader(reader)\n}\n"
  },
  {
    "path": "common/mux/session_test.go",
    "content": "package mux_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/mux\"\n)\n\nfunc TestSessionManagerAdd(t *testing.T) {\n\tm := NewSessionManager()\n\n\ts := m.Allocate()\n\tif s.ID != 1 {\n\t\tt.Error(\"id: \", s.ID)\n\t}\n\tif m.Size() != 1 {\n\t\tt.Error(\"size: \", m.Size())\n\t}\n\n\ts = m.Allocate()\n\tif s.ID != 2 {\n\t\tt.Error(\"id: \", s.ID)\n\t}\n\tif m.Size() != 2 {\n\t\tt.Error(\"size: \", m.Size())\n\t}\n\n\ts = &Session{\n\t\tID: 4,\n\t}\n\tm.Add(s)\n\tif s.ID != 4 {\n\t\tt.Error(\"id: \", s.ID)\n\t}\n\tif m.Size() != 3 {\n\t\tt.Error(\"size: \", m.Size())\n\t}\n}\n\nfunc TestSessionManagerClose(t *testing.T) {\n\tm := NewSessionManager()\n\ts := m.Allocate()\n\n\tif m.CloseIfNoSession() {\n\t\tt.Error(\"able to close\")\n\t}\n\tm.Remove(s.ID)\n\tif !m.CloseIfNoSession() {\n\t\tt.Error(\"not able to close\")\n\t}\n}\n"
  },
  {
    "path": "common/mux/writer.go",
    "content": "package mux\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype Writer struct {\n\tdest         net.Destination\n\twriter       buf.Writer\n\tid           uint16\n\tfollowup     bool\n\thasError     bool\n\ttransferType protocol.TransferType\n}\n\nfunc NewWriter(id uint16, dest net.Destination, writer buf.Writer, transferType protocol.TransferType) *Writer {\n\treturn &Writer{\n\t\tid:           id,\n\t\tdest:         dest,\n\t\twriter:       writer,\n\t\tfollowup:     false,\n\t\ttransferType: transferType,\n\t}\n}\n\nfunc NewResponseWriter(id uint16, writer buf.Writer, transferType protocol.TransferType) *Writer {\n\treturn &Writer{\n\t\tid:           id,\n\t\twriter:       writer,\n\t\tfollowup:     true,\n\t\ttransferType: transferType,\n\t}\n}\n\nfunc (w *Writer) getNextFrameMeta() FrameMetadata {\n\tmeta := FrameMetadata{\n\t\tSessionID: w.id,\n\t\tTarget:    w.dest,\n\t}\n\n\tif w.followup {\n\t\tmeta.SessionStatus = SessionStatusKeep\n\t} else {\n\t\tw.followup = true\n\t\tmeta.SessionStatus = SessionStatusNew\n\t}\n\n\treturn meta\n}\n\nfunc (w *Writer) writeMetaOnly() error {\n\tmeta := w.getNextFrameMeta()\n\tb := buf.New()\n\tif err := meta.WriteTo(b); err != nil {\n\t\treturn err\n\t}\n\treturn w.writer.WriteMultiBuffer(buf.MultiBuffer{b})\n}\n\nfunc writeMetaWithFrame(writer buf.Writer, meta FrameMetadata, data buf.MultiBuffer) error {\n\tframe := buf.New()\n\tif err := meta.WriteTo(frame); err != nil {\n\t\treturn err\n\t}\n\tif _, err := serial.WriteUint16(frame, uint16(data.Len())); err != nil {\n\t\treturn err\n\t}\n\n\tif len(data)+1 > 64*1024*1024 {\n\t\treturn errors.New(\"value too large\")\n\t}\n\tsliceSize := len(data) + 1\n\tmb2 := make(buf.MultiBuffer, 0, sliceSize)\n\tmb2 = append(mb2, frame)\n\tmb2 = append(mb2, data...)\n\treturn writer.WriteMultiBuffer(mb2)\n}\n\nfunc (w *Writer) writeData(mb buf.MultiBuffer) error {\n\tmeta := w.getNextFrameMeta()\n\tmeta.Option.Set(OptionData)\n\n\treturn writeMetaWithFrame(w.writer, meta, mb)\n}\n\n// WriteMultiBuffer implements buf.Writer.\nfunc (w *Writer) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tdefer buf.ReleaseMulti(mb)\n\n\tif mb.IsEmpty() {\n\t\treturn w.writeMetaOnly()\n\t}\n\n\tfor !mb.IsEmpty() {\n\t\tvar chunk buf.MultiBuffer\n\t\tif w.transferType == protocol.TransferTypeStream {\n\t\t\tmb, chunk = buf.SplitSize(mb, 8*1024)\n\t\t} else {\n\t\t\tmb2, b := buf.SplitFirst(mb)\n\t\t\tmb = mb2\n\t\t\tchunk = buf.MultiBuffer{b}\n\t\t}\n\t\tif err := w.writeData(chunk); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (w *Writer) Close() error {\n\tmeta := FrameMetadata{\n\t\tSessionID:     w.id,\n\t\tSessionStatus: SessionStatusEnd,\n\t}\n\tif w.hasError {\n\t\tmeta.Option.Set(OptionError)\n\t}\n\n\tframe := buf.New()\n\tcommon.Must(meta.WriteTo(frame))\n\n\tw.writer.WriteMultiBuffer(buf.MultiBuffer{frame})\n\treturn nil\n}\n"
  },
  {
    "path": "common/natTraversal/stun/filteredStunConnection.go",
    "content": "package stun\n\nimport (\n\t\"github.com/pion/stun/v3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype STUNMessageCallback func(b []byte, addr net.Addr)\n\nfunc NewFilteredConnection(inner net.PacketConn, callback STUNMessageCallback) (*FilteredConnection, error) {\n\treturn &FilteredConnection{\n\t\tPacketConn:      inner,\n\t\tstunMsgCallback: callback,\n\t}, nil\n}\n\ntype FilteredConnection struct {\n\tnet.PacketConn\n\tstunMsgCallback STUNMessageCallback\n}\n\nfunc (f *FilteredConnection) ReadFrom(b []byte) (int, net.Addr, error) {\n\tn, addr, err := f.PacketConn.ReadFrom(b)\n\tif stun.IsMessage(b[:n]) {\n\t\tf.stunMsgCallback(b[:n], addr)\n\t}\n\treturn n, addr, err\n}\n"
  },
  {
    "path": "common/natTraversal/stun/natTypeTest.go",
    "content": "package stun\n\n// Mostly Machine Generated Code\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pion/stun/v3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\ntype NATDependantType int\n\nconst (\n\tUnknown NATDependantType = iota\n\tIndependent\n\tEndpointDependent\n\tEndpointPortDependent\n\tEndpointPortDependentPinned\n)\n\ntype NATYesOrNoUnknownType int\n\nconst (\n\tNATYesOrNoUnknownType_Unknown NATYesOrNoUnknownType = iota\n\tNATYesOrNoUnknownType_Yes\n\tNATYesOrNoUnknownType_No\n)\n\ntype NATTypeTest struct {\n\tnewStunConn     func() (net.PacketConn, error)\n\ttestsTranscript []TestConducted\n\ttranscriptMux   sync.Mutex\n\n\tTimeout  time.Duration\n\tAttempts int\n\n\tFilterBehaviour  NATDependantType\n\tMappingBehaviour NATDependantType\n\tHairpinBehaviour NATYesOrNoUnknownType\n\n\tStableMappingOnSecondaryServer NATYesOrNoUnknownType\n\n\t// Calculated values from testsTranscript\n\tPreserveSourcePortWhenSourceNATMapping NATYesOrNoUnknownType\n\tSingleSourceIPSourceNATMapping         NATYesOrNoUnknownType\n\t// PreserveSourceIPPortWhenDestNATMapping\n\t// means when receiving packets,\n\t// whether the real source address is preserved in the reply message\n\t// some time a bad proxy would fill in a default value rather the real remote address\n\t// this can be detected when asking remote server to reply from a different ip or port\n\tPreserveSourceIPPortWhenDestNATMapping NATYesOrNoUnknownType\n\n\tTestServer          net.Addr\n\tTestServerSecondary net.Addr\n\n\tSourceIPs []net.IP\n}\n\nfunc NewNATTypeTest(newStunConn func() (net.PacketConn, error), testServer net.Addr, testServerSecondary net.Addr, timeout time.Duration, attempts int) *NATTypeTest {\n\treturn &NATTypeTest{\n\t\tnewStunConn:         newStunConn,\n\t\tTimeout:             timeout,\n\t\tAttempts:            attempts,\n\t\tTestServer:          testServer,\n\t\tTestServerSecondary: testServerSecondary,\n\t}\n}\n\ntype TestConducted struct {\n\tReq         stun.Message\n\tReqSentTo   net.Addr\n\tReqSentFrom net.Addr\n\tResp        *stun.Message\n\tRespFrom    net.Addr\n}\n\nfunc changeRequestSetter(changeIP, changePort bool) stun.RawAttribute {\n\tval := make([]byte, 4)\n\tvar flags uint32\n\tif changeIP {\n\t\tflags |= 0x04\n\t}\n\tif changePort {\n\t\tflags |= 0x02\n\t}\n\tbinary.BigEndian.PutUint32(val, flags)\n\treturn stun.RawAttribute{\n\t\tType:  stun.AttrChangeRequest,\n\t\tValue: val,\n\t}\n}\n\nfunc startBackgroundReader(conn *StunClientConn) {\n\tgo func() {\n\t\tbuf := make([]byte, 1500)\n\t\tfor {\n\t\t\t_, _, err := conn.ReadFrom(buf)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc (t *NATTypeTest) recordTransaction(tc TestConducted) {\n\tt.transcriptMux.Lock()\n\tdefer t.transcriptMux.Unlock()\n\tt.testsTranscript = append(t.testsTranscript, tc)\n}\n\n// doTransactionWithRetry sends multiple STUN requests at once (each with a fresh\n// transaction ID) and waits for the first response within a single timeout window.\n// This avoids sequential retry delays caused by UDP packet loss.\n// Non-timeout errors from sending are returned immediately.\nfunc (t *NATTypeTest) doTransactionWithRetry(conn *StunClientConn, localAddr net.Addr, dest net.Addr, attempts int, setters ...stun.Setter) (*stun.Message, net.Addr, error) { //nolint:unparam\n\ttype result struct {\n\t\tmsg  stun.Message\n\t\taddr net.Addr\n\t}\n\tch := make(chan result, attempts)\n\n\tvar txIDs []stunTransactionID\n\tvar firstMsg *stun.Message\n\n\tfor i := 0; i < attempts; i++ {\n\t\tmsg := stun.MustBuild(setters...)\n\t\tif i == 0 {\n\t\t\tfirstMsg = msg\n\t\t}\n\n\t\t_, _, err := conn.ExecuteSTUNMessageAsync(*msg, dest, func(_ [stun.TransactionIDSize]byte, respMsg stun.Message, respAddr net.Addr) {\n\t\t\tch <- result{msg: respMsg, addr: respAddr}\n\t\t})\n\t\tif err != nil {\n\t\t\tfor _, id := range txIDs {\n\t\t\t\tconn.processor.CancelTransaction(id)\n\t\t\t}\n\t\t\treturn nil, nil, err\n\t\t}\n\t\ttxIDs = append(txIDs, msg.TransactionID)\n\t}\n\n\t// Wait for first response or timeout\n\tvar resp *result\n\tselect {\n\tcase r := <-ch:\n\t\tresp = &r\n\tcase <-time.After(t.Timeout):\n\t}\n\n\t// Cancel all remaining pending transactions\n\tfor _, id := range txIDs {\n\t\tconn.processor.CancelTransaction(id)\n\t}\n\n\t// Record result\n\tif resp != nil {\n\t\trespMsg := resp.msg\n\t\tt.recordTransaction(TestConducted{\n\t\t\tReq:         *firstMsg,\n\t\t\tReqSentTo:   dest,\n\t\t\tReqSentFrom: localAddr,\n\t\t\tResp:        &respMsg,\n\t\t\tRespFrom:    resp.addr,\n\t\t})\n\t\treturn &respMsg, resp.addr, nil\n\t}\n\n\tt.recordTransaction(TestConducted{\n\t\tReq:         *firstMsg,\n\t\tReqSentTo:   dest,\n\t\tReqSentFrom: localAddr,\n\t})\n\treturn nil, nil, ErrTimeout\n}\n\n// TestFilterBehaviour determines NAT filtering behavior per RFC 5780 Section 4.4.\nfunc (t *NATTypeTest) TestFilterBehaviour() error {\n\trawConn, err := t.newStunConn()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconn, err := NewStunClientConn(rawConn)\n\tif err != nil {\n\t\trawConn.Close()\n\t\treturn err\n\t}\n\tdefer conn.Close()\n\tlocalAddr := rawConn.LocalAddr()\n\tstartBackgroundReader(conn)\n\n\t// Test I: Regular binding to confirm connectivity and get OTHER-ADDRESS\n\tresp1, _, err := t.doTransactionWithRetry(conn, localAddr, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Check if server supports RFC 5780 (OTHER-ADDRESS).\n\t// Without it, CHANGE-REQUEST results are unreliable.\n\tvar filterOtherAddr stun.OtherAddress\n\tif err := filterOtherAddr.GetFrom(resp1); err != nil {\n\t\tt.FilterBehaviour = Unknown\n\t\treturn nil\n\t}\n\n\t// Test II: Request server to respond from different IP and port\n\t_, _, err = t.doTransactionWithRetry(conn, localAddr, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest, changeRequestSetter(true, true))\n\tif err == nil {\n\t\tt.FilterBehaviour = Independent\n\t\treturn nil\n\t}\n\tif !errors.Is(err, ErrTimeout) {\n\t\treturn err\n\t}\n\n\t// Test III: Request server to respond from different port only\n\t_, _, err = t.doTransactionWithRetry(conn, localAddr, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest, changeRequestSetter(false, true))\n\tif err == nil {\n\t\tt.FilterBehaviour = EndpointDependent\n\t\treturn nil\n\t}\n\tif !errors.Is(err, ErrTimeout) {\n\t\treturn err\n\t}\n\n\t// Test IV: Check if sending outbound UDP can open the filter for a new endpoint.\n\t// Send a binding to the alternative address to create a NAT filter entry,\n\t// then ask the original server to reply from that alternative address.\n\t// If the response arrives, the filter can be opened by outbound packets.\n\taltAddr := &net.UDPAddr{IP: filterOtherAddr.IP, Port: filterOtherAddr.Port}\n\n\t// Send binding to alt address to open the NAT filter for that endpoint\n\t_, _, err = t.doTransactionWithRetry(conn, localAddr, altAddr, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil && !errors.Is(err, ErrTimeout) {\n\t\treturn err\n\t}\n\n\t// Now ask original server to reply from the alternative address\n\t_, _, err = t.doTransactionWithRetry(conn, localAddr, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest, changeRequestSetter(true, true))\n\tif err == nil {\n\t\tt.FilterBehaviour = EndpointPortDependent\n\t\treturn nil\n\t}\n\tif !errors.Is(err, ErrTimeout) {\n\t\treturn err\n\t}\n\n\tt.FilterBehaviour = EndpointPortDependentPinned\n\treturn nil\n}\n\n// TestMappingBehaviour determines NAT mapping behavior per RFC 5780 Section 4.3.\nfunc (t *NATTypeTest) TestMappingBehaviour() error {\n\trawConn, err := t.newStunConn()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconn, err := NewStunClientConn(rawConn)\n\tif err != nil {\n\t\trawConn.Close()\n\t\treturn err\n\t}\n\tdefer conn.Close()\n\tlocalAddr := rawConn.LocalAddr()\n\tstartBackgroundReader(conn)\n\n\t// Test I: Regular binding to primary server\n\tresp1, _, err := t.doTransactionWithRetry(conn, localAddr, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar mappedAddr1 stun.XORMappedAddress\n\tif err := mappedAddr1.GetFrom(resp1); err != nil {\n\t\treturn err\n\t}\n\n\tvar otherAddr stun.OtherAddress\n\tif err := otherAddr.GetFrom(resp1); err != nil {\n\t\t// Server does not support RFC 5780 (no OTHER-ADDRESS), cannot test mapping\n\t\tt.MappingBehaviour = Unknown\n\t\treturn nil\n\t}\n\n\t// Validate OTHER-ADDRESS has both a different IP and port from the primary server.\n\t// The mapping behavior test requires a genuinely distinct endpoint to produce meaningful results.\n\tserverUDPForValidation, ok := t.TestServer.(*net.UDPAddr)\n\tif !ok {\n\t\treturn errors.New(\"TestServer is not a UDP address\")\n\t}\n\tif otherAddr.IP.Equal(serverUDPForValidation.IP) || otherAddr.Port == serverUDPForValidation.Port {\n\t\treturn errors.New(\"OTHER-ADDRESS from STUN server does not differ in both IP and port from the primary server\")\n\t}\n\n\t// Test II: From same socket, binding to OTHER-ADDRESS (different IP and port)\n\taltAddr := &net.UDPAddr{IP: otherAddr.IP, Port: otherAddr.Port}\n\tresp2, _, err := t.doTransactionWithRetry(conn, localAddr, altAddr, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar mappedAddr2 stun.XORMappedAddress\n\tif err := mappedAddr2.GetFrom(resp2); err != nil {\n\t\treturn err\n\t}\n\n\tif mappedAddr1.String() == mappedAddr2.String() {\n\t\tt.MappingBehaviour = Independent\n\t\treturn nil\n\t}\n\n\t// Test III: From same socket, binding to (other IP, original port)\n\tserverUDP, ok := t.TestServer.(*net.UDPAddr)\n\tif !ok {\n\t\treturn errors.New(\"TestServer is not a UDP address\")\n\t}\n\taltAddr2 := &net.UDPAddr{IP: otherAddr.IP, Port: serverUDP.Port}\n\tresp3, _, err := t.doTransactionWithRetry(conn, localAddr, altAddr2, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar mappedAddr3 stun.XORMappedAddress\n\tif err := mappedAddr3.GetFrom(resp3); err != nil {\n\t\treturn err\n\t}\n\n\tif mappedAddr2.String() == mappedAddr3.String() {\n\t\tt.MappingBehaviour = EndpointDependent\n\t} else {\n\t\tt.MappingBehaviour = EndpointPortDependent\n\t}\n\treturn nil\n}\n\nfunc (t *NATTypeTest) TestMappingBehaviourWithSecondaryServer() error {\n\tif t.TestServerSecondary == nil {\n\t\tt.StableMappingOnSecondaryServer = NATYesOrNoUnknownType_Unknown\n\t\treturn nil\n\t}\n\n\trawConn, err := t.newStunConn()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconn, err := NewStunClientConn(rawConn)\n\tif err != nil {\n\t\trawConn.Close()\n\t\treturn err\n\t}\n\tdefer conn.Close()\n\tlocalAddr := rawConn.LocalAddr()\n\tstartBackgroundReader(conn)\n\n\t// Binding to primary server\n\tresp1, _, err := t.doTransactionWithRetry(conn, localAddr, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar mappedAddr1 stun.XORMappedAddress\n\tif err := mappedAddr1.GetFrom(resp1); err != nil {\n\t\treturn err\n\t}\n\n\t// Binding to secondary server from the same socket\n\tresp2, _, err := t.doTransactionWithRetry(conn, localAddr, t.TestServerSecondary, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar mappedAddr2 stun.XORMappedAddress\n\tif err := mappedAddr2.GetFrom(resp2); err != nil {\n\t\treturn err\n\t}\n\n\tif mappedAddr1.String() == mappedAddr2.String() {\n\t\tt.StableMappingOnSecondaryServer = NATYesOrNoUnknownType_Yes\n\t} else {\n\t\tt.StableMappingOnSecondaryServer = NATYesOrNoUnknownType_No\n\t}\n\n\treturn nil\n}\n\n// TestHairpinBehaviour determines if the NAT supports hairpinning per RFC 5780 Section 4.5.\n// Both sockets must first get their mapped addresses via STUN, then send to each other's\n// mapped address. This ensures the NAT filter is opened for the peer's mapped address\n// before the hairpin test packet arrives, avoiding false negatives from filtering.\nfunc (t *NATTypeTest) TestHairpinBehaviour() error {\n\t// Socket 1: get mapped address\n\trawConn1, err := t.newStunConn()\n\tif err != nil {\n\t\treturn err\n\t}\n\tconn1, err := NewStunClientConn(rawConn1)\n\tif err != nil {\n\t\trawConn1.Close()\n\t\treturn err\n\t}\n\tdefer conn1.Close()\n\tlocalAddr1 := rawConn1.LocalAddr()\n\tstartBackgroundReader(conn1)\n\n\tresp1, _, err := t.doTransactionWithRetry(conn1, localAddr1, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar mappedAddr1 stun.XORMappedAddress\n\tif err := mappedAddr1.GetFrom(resp1); err != nil {\n\t\treturn err\n\t}\n\tselfAddr1 := &net.UDPAddr{IP: mappedAddr1.IP, Port: mappedAddr1.Port}\n\n\t// Socket 2: get mapped address\n\trawConn2, err := t.newStunConn()\n\tif err != nil {\n\t\treturn err\n\t}\n\tconn2, err := NewStunClientConn(rawConn2)\n\tif err != nil {\n\t\trawConn2.Close()\n\t\treturn err\n\t}\n\tdefer conn2.Close()\n\tlocalAddr2 := rawConn2.LocalAddr()\n\tstartBackgroundReader(conn2)\n\n\tresp2, _, err := t.doTransactionWithRetry(conn2, localAddr2, t.TestServer, t.Attempts,\n\t\tstun.TransactionID, stun.BindingRequest)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar mappedAddr2 stun.XORMappedAddress\n\tif err := mappedAddr2.GetFrom(resp2); err != nil {\n\t\treturn err\n\t}\n\tselfAddr2 := &net.UDPAddr{IP: mappedAddr2.IP, Port: mappedAddr2.Port}\n\n\t// Socket 1 sends to MA2 to open the NAT filter for MA2 on socket 1's side.\n\t// Without this, a hairpinned packet from socket 2 (appearing as MA2) would be\n\t// filtered by endpoint-dependent filtering on socket 1.\n\topenMsg := stun.MustBuild(stun.TransactionID, stun.BindingRequest)\n\topenMsg.Encode()\n\tconn1.WriteTo(openMsg.Raw, selfAddr2)\n\n\t// Build hairpin test messages: register on conn1's processor, send from conn2.\n\t// Hairpinned packets arrive at conn1 from MA2 (now allowed by filter).\n\ttype result struct {\n\t\tmsg  stun.Message\n\t\taddr net.Addr\n\t}\n\tch := make(chan result, t.Attempts)\n\n\tvar txIDs []stunTransactionID\n\tvar firstMsg *stun.Message\n\tfor i := 0; i < t.Attempts; i++ {\n\t\tmsg := stun.MustBuild(stun.TransactionID, stun.BindingRequest)\n\t\tif i == 0 {\n\t\t\tfirstMsg = msg\n\t\t}\n\t\tmsg.Encode()\n\n\t\t// Register on conn1's processor (hairpinned packet arrives at conn1)\n\t\tconn1.processor.AddPendingTransactionListener(msg.TransactionID, func(_ [stun.TransactionIDSize]byte, respMsg stun.Message, respAddr net.Addr) {\n\t\t\tch <- result{msg: respMsg, addr: respAddr}\n\t\t})\n\t\ttxIDs = append(txIDs, msg.TransactionID)\n\n\t\t// Send from conn2 to MA1 (socket 1's mapped address)\n\t\tif _, err := conn2.WriteTo(msg.Raw, selfAddr1); err != nil {\n\t\t\tfor _, id := range txIDs {\n\t\t\t\tconn1.processor.CancelTransaction(id)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Wait for hairpinned packet on conn1\n\tvar respResult *result\n\tselect {\n\tcase r := <-ch:\n\t\trespResult = &r\n\tcase <-time.After(t.Timeout):\n\t}\n\n\t// Cancel all remaining pending transactions\n\tfor _, id := range txIDs {\n\t\tconn1.processor.CancelTransaction(id)\n\t}\n\n\tt.HairpinBehaviour = NATYesOrNoUnknownType_No\n\n\tif respResult != nil {\n\t\trespMsg := respResult.msg\n\t\tt.recordTransaction(TestConducted{\n\t\t\tReq:         *firstMsg,\n\t\t\tReqSentTo:   selfAddr1,\n\t\t\tReqSentFrom: localAddr2,\n\t\t\tResp:        &respMsg,\n\t\t\tRespFrom:    respResult.addr,\n\t\t})\n\t\tif respMsg.Type == stun.BindingRequest {\n\t\t\tt.HairpinBehaviour = NATYesOrNoUnknownType_Yes\n\t\t}\n\t\treturn nil\n\t}\n\n\tt.recordTransaction(TestConducted{\n\t\tReq:         *firstMsg,\n\t\tReqSentTo:   selfAddr1,\n\t\tReqSentFrom: localAddr2,\n\t})\n\treturn nil\n}\n\n// TestAll runs all NAT behavior tests in parallel, then calculates derived values.\nfunc (t *NATTypeTest) TestAll() error {\n\terr := task.Run(context.Background(),\n\t\tt.TestFilterBehaviour,\n\t\tt.TestMappingBehaviour,\n\t\tt.TestHairpinBehaviour,\n\t\tt.TestMappingBehaviourWithSecondaryServer,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn t.CalcReminderValues()\n}\n\n// CalcReminderValues derives additional NAT properties from the collected test transcripts.\nfunc (t *NATTypeTest) CalcReminderValues() error {\n\tt.transcriptMux.Lock()\n\ttranscripts := make([]TestConducted, len(t.testsTranscript))\n\tcopy(transcripts, t.testsTranscript)\n\tt.transcriptMux.Unlock()\n\n\ttype addrKey struct {\n\t\tip   string\n\t\tport int\n\t}\n\n\tvar mappedAddrs []addrKey\n\tfor _, tc := range transcripts {\n\t\tif tc.Resp == nil {\n\t\t\tcontinue\n\t\t}\n\t\tvar addr stun.XORMappedAddress\n\t\tif err := addr.GetFrom(tc.Resp); err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tmappedAddrs = append(mappedAddrs, addrKey{ip: addr.IP.String(), port: addr.Port})\n\t}\n\n\t// Collect unique mapped source IPs\n\tseenIPs := make(map[string]struct{})\n\tt.SourceIPs = nil\n\tfor _, m := range mappedAddrs {\n\t\tif _, ok := seenIPs[m.ip]; !ok {\n\t\t\tseenIPs[m.ip] = struct{}{}\n\t\t\tt.SourceIPs = append(t.SourceIPs, net.ParseIP(m.ip))\n\t\t}\n\t}\n\n\t// Need at least 2 mapped addresses to draw any meaningful comparison\n\tif len(mappedAddrs) < 2 {\n\t\tt.SingleSourceIPSourceNATMapping = NATYesOrNoUnknownType_Unknown\n\t\tt.PreserveSourceIPPortWhenDestNATMapping = NATYesOrNoUnknownType_Unknown\n\t\tt.PreserveSourcePortWhenSourceNATMapping = NATYesOrNoUnknownType_Unknown\n\t\treturn nil\n\t}\n\n\t// SingleSourceIPSourceNATMapping: check if all mapped IPs are the same\n\tallSameIP := true\n\tfor _, m := range mappedAddrs[1:] {\n\t\tif m.ip != mappedAddrs[0].ip {\n\t\t\tallSameIP = false\n\t\t\tbreak\n\t\t}\n\t}\n\tif allSameIP {\n\t\tt.SingleSourceIPSourceNATMapping = NATYesOrNoUnknownType_Yes\n\t} else {\n\t\tt.SingleSourceIPSourceNATMapping = NATYesOrNoUnknownType_No\n\t}\n\n\t// PreserveSourceIPPortWhenDestNATMapping: check using RESPONSE-ORIGIN if available,\n\t// otherwise fall back to CHANGE-REQUEST hairpin detection.\n\tallResponseOriginMatchRespFrom := true\n\tresponseOriginPairCount := 0\n\tfor _, tc := range transcripts {\n\t\tif tc.Resp == nil || tc.RespFrom == nil || tc.ReqSentTo == nil {\n\t\t\tcontinue\n\t\t}\n\t\tvar responseOrigin stun.ResponseOrigin\n\t\tif err := responseOrigin.GetFrom(tc.Resp); err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tresponseOriginAddr := net.UDPAddr{IP: responseOrigin.IP, Port: responseOrigin.Port}\n\t\tif responseOriginAddr.String() == tc.ReqSentTo.String() {\n\t\t\tcontinue\n\t\t}\n\t\tresponseOriginPairCount++\n\t\tif tc.RespFrom.String() != responseOriginAddr.String() {\n\t\t\tallResponseOriginMatchRespFrom = false\n\t\t\tbreak\n\t\t}\n\t}\n\tif responseOriginPairCount >= 1 {\n\t\tif allResponseOriginMatchRespFrom {\n\t\t\tt.PreserveSourceIPPortWhenDestNATMapping = NATYesOrNoUnknownType_Yes\n\t\t} else {\n\t\t\tt.PreserveSourceIPPortWhenDestNATMapping = NATYesOrNoUnknownType_No\n\t\t}\n\t} else {\n\t\t// Fallback: detect if we receive our own hairpin packets.\n\t\t// If RespFrom == ReqSentTo for all responses, the source address was rewritten (not preserved).\n\t\tallSendToMatchRespFrom := true\n\t\trespPairCount := 0\n\t\tfor _, tc := range transcripts {\n\t\t\tif tc.Resp == nil || tc.RespFrom == nil || tc.ReqSentTo == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Only count hairpin packets: responses that are binding requests (not binding responses)\n\t\t\tif tc.Resp.Type != stun.BindingRequest {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trespPairCount++\n\t\t\tif tc.RespFrom.String() != tc.ReqSentTo.String() {\n\t\t\t\tallSendToMatchRespFrom = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tswitch {\n\t\tcase respPairCount < 1:\n\t\t\tt.PreserveSourceIPPortWhenDestNATMapping = NATYesOrNoUnknownType_Unknown\n\t\tcase allSendToMatchRespFrom:\n\t\t\tt.PreserveSourceIPPortWhenDestNATMapping = NATYesOrNoUnknownType_No\n\t\tdefault:\n\t\t\tt.PreserveSourceIPPortWhenDestNATMapping = NATYesOrNoUnknownType_Yes\n\t\t}\n\t}\n\n\t// PreserveSourcePortWhenSourceNATMapping: check if mapped port matches local source port\n\tpreserves := true\n\tvalidCount := 0\n\tfor _, tc := range transcripts {\n\t\tif tc.Resp == nil || tc.ReqSentFrom == nil {\n\t\t\tcontinue\n\t\t}\n\t\tlocalUDP, ok := tc.ReqSentFrom.(*net.UDPAddr)\n\t\tif !ok || localUDP.Port == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tvar addr stun.XORMappedAddress\n\t\tif err := addr.GetFrom(tc.Resp); err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tvalidCount++\n\t\tif addr.Port != localUDP.Port {\n\t\t\tpreserves = false\n\t\t}\n\t}\n\tif validCount >= 2 {\n\t\tif preserves {\n\t\t\tt.PreserveSourcePortWhenSourceNATMapping = NATYesOrNoUnknownType_Yes\n\t\t} else {\n\t\t\tt.PreserveSourcePortWhenSourceNATMapping = NATYesOrNoUnknownType_No\n\t\t}\n\t} else {\n\t\tt.PreserveSourcePortWhenSourceNATMapping = NATYesOrNoUnknownType_Unknown\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "common/natTraversal/stun/processor.go",
    "content": "package stun\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pion/stun/v3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype stunTransactionID = [stun.TransactionIDSize]byte\n\ntype pendingTransaction struct {\n\thandler   PendingTransactionHandler\n\tcreatedAt time.Time\n}\n\ntype Processor struct {\n\tpendingStunRequest map[stunTransactionID]pendingTransaction\n\tclosed             bool\n\tmux                sync.Mutex\n}\n\nfunc NewProcessor() *Processor {\n\treturn &Processor{\n\t\tpendingStunRequest: make(map[stunTransactionID]pendingTransaction),\n\t}\n}\n\nfunc (p *Processor) HandleStunPacket(b []byte, addr net.Addr) {\n\tvar msg stun.Message\n\tif err := stun.Decode(b, &msg); err != nil {\n\t\treturn\n\t}\n\n\tp.mux.Lock()\n\tpt, ok := p.pendingStunRequest[msg.TransactionID]\n\tif ok {\n\t\tdelete(p.pendingStunRequest, msg.TransactionID)\n\t}\n\tp.mux.Unlock()\n\n\tif ok {\n\t\tpt.handler(msg.TransactionID, msg, addr)\n\t}\n}\n\ntype PendingTransactionHandler func(transactionID [stun.TransactionIDSize]byte, msg stun.Message, addr net.Addr)\n\nfunc (p *Processor) AddPendingTransactionListener(transactionID [stun.TransactionIDSize]byte, handler PendingTransactionHandler) {\n\tp.mux.Lock()\n\tdefer p.mux.Unlock()\n\tp.pendingStunRequest[transactionID] = pendingTransaction{\n\t\thandler:   handler,\n\t\tcreatedAt: time.Now(),\n\t}\n}\n\nfunc (p *Processor) CancelTransaction(transactionID [stun.TransactionIDSize]byte) {\n\tp.mux.Lock()\n\tdefer p.mux.Unlock()\n\tdelete(p.pendingStunRequest, transactionID)\n}\n\nfunc (p *Processor) ExpiredTransaction(newerThanThisTimeOrExpire time.Time) int {\n\tp.mux.Lock()\n\tdefer p.mux.Unlock()\n\texpired := 0\n\tfor id, pt := range p.pendingStunRequest {\n\t\tif pt.createdAt.Before(newerThanThisTimeOrExpire) {\n\t\t\tdelete(p.pendingStunRequest, id)\n\t\t\texpired++\n\t\t}\n\t}\n\treturn expired\n}\n"
  },
  {
    "path": "common/natTraversal/stun/stunClientConn.go",
    "content": "package stun\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/pion/stun/v3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nvar ErrTimeout = errors.New(\"STUN transaction timed out\")\n\nfunc NewStunClientConn(conn net.PacketConn) (*StunClientConn, error) {\n\tprocessor := NewProcessor()\n\tfiltered, err := NewFilteredConnection(conn, processor.HandleStunPacket)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &StunClientConn{\n\t\tPacketConn: filtered,\n\t\tprocessor:  processor,\n\t}, nil\n}\n\ntype StunClientConn struct {\n\tnet.PacketConn\n\tprocessor *Processor\n}\n\nfunc (conn *StunClientConn) ExecuteSTUNMessage(msg stun.Message, dest net.Addr, timeout time.Duration) (resp stun.Message, addr net.Addr, err error) {\n\ttype result struct {\n\t\tmsg  stun.Message\n\t\taddr net.Addr\n\t}\n\tch := make(chan result, 1)\n\n\t_, _, err = conn.ExecuteSTUNMessageAsync(msg, dest, func(_ [stun.TransactionIDSize]byte, respMsg stun.Message, respAddr net.Addr) {\n\t\tch <- result{msg: respMsg, addr: respAddr}\n\t})\n\tif err != nil {\n\t\treturn resp, nil, err\n\t}\n\n\tselect {\n\tcase r := <-ch:\n\t\treturn r.msg, r.addr, nil\n\tcase <-time.After(timeout):\n\t\tconn.processor.CancelTransaction(msg.TransactionID)\n\t\treturn resp, nil, ErrTimeout\n\t}\n}\n\nfunc (conn *StunClientConn) ExecuteSTUNMessageAsync(msg stun.Message, dest net.Addr, callback PendingTransactionHandler) (resp stun.Message, addr net.Addr, err error) {\n\tmsg.Encode()\n\tconn.processor.AddPendingTransactionListener(msg.TransactionID, callback)\n\n\tif _, err = conn.WriteTo(msg.Raw, dest); err != nil {\n\t\tconn.processor.CancelTransaction(msg.TransactionID)\n\t\treturn resp, nil, err\n\t}\n\n\treturn resp, nil, nil\n}\n"
  },
  {
    "path": "common/natTraversal/stun/stuncli/stuncli.go",
    "content": "package stuncli\n\n// Mostly machine generated code\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\tstunlib \"github.com/v2fly/v2ray-core/v5/common/natTraversal/stun\"\n\tvnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n)\n\nvar (\n\tserver    *string\n\tserver2   *string\n\ttimeout   *int\n\tattempts  *int\n\tsocks5udp *string\n)\n\nvar cmdStunTest = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering stun-nat-type-discovery\",\n\tShort:     \"run STUN NAT type tests\",\n\tLong: `\nRun STUN NAT behavior discovery tests (RFC 5780) against a STUN server.\n\nTests NAT filtering, mapping, and hairpin behavior, then reports results.\n\nThe STUN server must support RFC 5780 (OTHER-ADDRESS and CHANGE-REQUEST)\nfor full test coverage.\n\nUsage:\n\t{{.Exec}} engineering stun-test -server <host:port> [-server2 <host:port>] [-timeout <ms>] [-attempts <n>] [-socks5udp <host:port>]\n\nOptions:\n\t-server <host:port>\n\t\tThe STUN server address (required)\n\t-server2 <host:port>\n\t\tA secondary STUN server address for cross-server mapping stability test\n\t-timeout <ms>\n\t\tTimeout per test in milliseconds (default: 3000)\n\t-attempts <n>\n\t\tNumber of parallel requests per test for UDP loss resilience (default: 3)\n\t-socks5udp <host:port>\n\t\tSOCKS5 UDP relay address (skips TCP handshake, sends UDP directly)\n\nExample:\n\t{{.Exec}} engineering stun-test -server stun.example.com:3478\n\t{{.Exec}} engineering stun-test -server stun.example.com:3478 -server2 stun2.example.com:3478\n\t{{.Exec}} engineering stun-test -server stun.example.com:3478 -socks5udp 127.0.0.1:1080\n`,\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tserver = fs.String(\"server\", \"\", \"STUN server address (host:port)\")\n\t\tserver2 = fs.String(\"server2\", \"\", \"secondary STUN server address (host:port)\")\n\t\ttimeout = fs.Int(\"timeout\", 3000, \"timeout per test in milliseconds\")\n\t\tattempts = fs.Int(\"attempts\", 3, \"number of parallel requests per test\")\n\t\tsocks5udp = fs.String(\"socks5udp\", \"\", \"SOCKS5 UDP relay address (host:port)\")\n\t\treturn *fs\n\t}(),\n\tRun: executeStunTest,\n}\n\nfunc init() {\n\tengineering.AddCommand(cmdStunTest)\n}\n\n// socks5UDPConn wraps a PacketConn to encapsulate/decapsulate SOCKS5 UDP packets.\n// All outgoing packets are wrapped in a SOCKS5 UDP header and sent to the relay.\n// All incoming packets are unwrapped, with the real source address extracted from the header.\ntype socks5UDPConn struct {\n\tnet.PacketConn\n\trelayAddr net.Addr\n}\n\nfunc (c *socks5UDPConn) WriteTo(p []byte, addr net.Addr) (int, error) {\n\tudpAddr := addr.(*net.UDPAddr)\n\tdest := vnet.UDPDestination(vnet.IPAddress(udpAddr.IP), vnet.Port(udpAddr.Port))\n\tpacket, err := socks.EncodeUDPPacketFromAddress(dest, p)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer packet.Release()\n\t_, err = c.PacketConn.WriteTo(packet.Bytes(), c.relayAddr)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(p), nil\n}\n\nfunc (c *socks5UDPConn) ReadFrom(p []byte) (int, net.Addr, error) {\n\t// Allocate enough space for SOCKS5 header + payload\n\trawBuf := make([]byte, len(p)+256)\n\tn, _, err := c.PacketConn.ReadFrom(rawBuf)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\tpacket := buf.FromBytes(rawBuf[:n])\n\treq, err := socks.DecodeUDPPacket(packet)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\t// After DecodeUDPPacket, packet.Bytes() contains the payload\n\tdataN := copy(p, packet.Bytes())\n\tsrcAddr := &net.UDPAddr{\n\t\tIP:   req.Address.IP(),\n\t\tPort: int(req.Port),\n\t}\n\treturn dataN, srcAddr, nil\n}\n\nfunc natDependantTypeString(t stunlib.NATDependantType) string {\n\tswitch t {\n\tcase stunlib.Unknown:\n\t\treturn \"Unknown\"\n\tcase stunlib.Independent:\n\t\treturn \"Independent\"\n\tcase stunlib.EndpointDependent:\n\t\treturn \"Endpoint Dependent\"\n\tcase stunlib.EndpointPortDependent:\n\t\treturn \"Endpoint+Port Dependent\"\n\tcase stunlib.EndpointPortDependentPinned:\n\t\treturn \"Endpoint+Port Dependent (Pinned)\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown(%d)\", t)\n\t}\n}\n\nfunc natYesOrNoString(t stunlib.NATYesOrNoUnknownType) string {\n\tswitch t {\n\tcase stunlib.NATYesOrNoUnknownType_Unknown:\n\t\treturn \"Unknown\"\n\tcase stunlib.NATYesOrNoUnknownType_Yes:\n\t\treturn \"Yes\"\n\tcase stunlib.NATYesOrNoUnknownType_No:\n\t\treturn \"No\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown(%d)\", t)\n\t}\n}\n\nfunc executeStunTest(cmd *base.Command, args []string) {\n\terr := cmd.Flag.Parse(args)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to parse flags: %v\", err)\n\t}\n\n\tif *server == \"\" {\n\t\tbase.Fatalf(\"-server is required\")\n\t}\n\n\thost, portStr, err := net.SplitHostPort(*server)\n\tif err != nil {\n\t\tbase.Fatalf(\"invalid server address %q: %v\", *server, err)\n\t}\n\n\tips, err := net.ResolveIPAddr(\"ip\", host)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to resolve %q: %v\", host, err)\n\t}\n\n\tport, err := net.LookupPort(\"udp\", portStr)\n\tif err != nil {\n\t\tbase.Fatalf(\"invalid port %q: %v\", portStr, err)\n\t}\n\n\tserverAddr := &net.UDPAddr{IP: ips.IP, Port: port}\n\n\t// Resolve secondary STUN server address if provided\n\tvar server2Addr *net.UDPAddr\n\tif *server2 != \"\" {\n\t\thost2, portStr2, err := net.SplitHostPort(*server2)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"invalid server2 address %q: %v\", *server2, err)\n\t\t}\n\t\tips2, err := net.ResolveIPAddr(\"ip\", host2)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to resolve server2 host %q: %v\", host2, err)\n\t\t}\n\t\tport2, err := net.LookupPort(\"udp\", portStr2)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"invalid server2 port %q: %v\", portStr2, err)\n\t\t}\n\t\tserver2Addr = &net.UDPAddr{IP: ips2.IP, Port: port2}\n\t}\n\n\t// Resolve SOCKS5 UDP relay address if provided\n\tvar relayAddr *net.UDPAddr\n\tif *socks5udp != \"\" {\n\t\trHost, rPortStr, err := net.SplitHostPort(*socks5udp)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"invalid socks5udp address %q: %v\", *socks5udp, err)\n\t\t}\n\t\trIPs, err := net.ResolveIPAddr(\"ip\", rHost)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to resolve socks5udp host %q: %v\", rHost, err)\n\t\t}\n\t\trPort, err := net.LookupPort(\"udp\", rPortStr)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"invalid socks5udp port %q: %v\", rPortStr, err)\n\t\t}\n\t\trelayAddr = &net.UDPAddr{IP: rIPs.IP, Port: rPort}\n\t}\n\n\tfmt.Printf(\"STUN server: %s\\n\", serverAddr)\n\tif server2Addr != nil {\n\t\tfmt.Printf(\"STUN server 2: %s\\n\", server2Addr)\n\t}\n\tif relayAddr != nil {\n\t\tfmt.Printf(\"SOCKS5 UDP relay: %s\\n\", relayAddr)\n\t}\n\tfmt.Printf(\"Timeout: %dms, Attempts: %d\\n\\n\", *timeout, *attempts)\n\n\tnewConn := func() (net.PacketConn, error) {\n\t\tconn, err := net.ListenPacket(\"udp\", \":0\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif relayAddr != nil {\n\t\t\treturn &socks5UDPConn{PacketConn: conn, relayAddr: relayAddr}, nil\n\t\t}\n\t\treturn conn, nil\n\t}\n\n\tvar secondaryServer net.Addr\n\tif server2Addr != nil {\n\t\tsecondaryServer = server2Addr\n\t}\n\n\ttest := stunlib.NewNATTypeTest(\n\t\tnewConn,\n\t\tserverAddr,\n\t\tsecondaryServer,\n\t\ttime.Duration(*timeout)*time.Millisecond,\n\t\t*attempts,\n\t)\n\n\tfmt.Println(\"Running tests...\")\n\tif err := test.TestAll(); err != nil {\n\t\tbase.Fatalf(\"test failed: %v\", err)\n\t}\n\n\tfmt.Println()\n\tfmt.Println(\"=== NAT Behavior Test Results ===\")\n\tfmt.Printf(\"  Filter Behaviour:  %s\\n\", natDependantTypeString(test.FilterBehaviour))\n\tfmt.Printf(\"  Mapping Behaviour: %s\\n\", natDependantTypeString(test.MappingBehaviour))\n\tfmt.Printf(\"  Hairpin Behaviour: %s\\n\", natYesOrNoString(test.HairpinBehaviour))\n\tfmt.Printf(\"  Stable Mapping on Secondary Server: %s\\n\", natYesOrNoString(test.StableMappingOnSecondaryServer))\n\tfmt.Println()\n\tfmt.Println(\"=== Derived Properties ===\")\n\tfmt.Printf(\"  Preserve Source Port (Source NAT):     %s\\n\", natYesOrNoString(test.PreserveSourcePortWhenSourceNATMapping))\n\tfmt.Printf(\"  Single Source IP (Source NAT):         %s\\n\", natYesOrNoString(test.SingleSourceIPSourceNATMapping))\n\tfmt.Printf(\"  Preserve Source Addr (Dest NAT Reply): %s\\n\", natYesOrNoString(test.PreserveSourceIPPortWhenDestNATMapping))\n\tfmt.Println()\n\tfmt.Println(\"=== Source IPs ===\")\n\tfor _, ip := range test.SourceIPs {\n\t\tfmt.Printf(\"  %s\\n\", ip)\n\t}\n}\n"
  },
  {
    "path": "common/net/abstactOutbount/errors.generated.go",
    "content": "package abstactOutbount\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/net/abstactOutbount/outbound.go",
    "content": "package abstactOutbount\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\nfunc NewOutboundListener() *OutboundListener {\n\treturn &OutboundListener{\n\t\tbuffer: make(chan *connWithContext, 4),\n\t\tdone:   done.New(),\n\t}\n}\n\ntype connWithContext struct {\n\tnet.Conn\n\tctx context.Context\n}\n\nfunc (c *connWithContext) GetConnectionContext() context.Context {\n\treturn c.ctx\n}\n\n// OutboundListener is a net.Listener for listening gRPC connections.\ntype OutboundListener struct {\n\tbuffer chan *connWithContext\n\tdone   *done.Instance\n}\n\nfunc (l *OutboundListener) addWithContext(ctx context.Context, conn net.Conn) {\n\tselect {\n\tcase l.buffer <- &connWithContext{Conn: conn, ctx: ctx}:\n\tcase <-l.done.Wait():\n\t\tconn.Close()\n\tdefault:\n\t\tconn.Close()\n\t}\n}\n\n// Accept implements net.Listener.\nfunc (l *OutboundListener) Accept() (net.Conn, error) {\n\tselect {\n\tcase <-l.done.Wait():\n\t\treturn nil, newError(\"listen closed\")\n\tcase c := <-l.buffer:\n\t\treturn c, nil\n\t}\n}\n\n// Close implement net.Listener.\nfunc (l *OutboundListener) Close() error {\n\tcommon.Must(l.done.Close())\nL:\n\tfor {\n\t\tselect {\n\t\tcase c := <-l.buffer:\n\t\t\tc.Close()\n\t\tdefault:\n\t\t\tbreak L\n\t\t}\n\t}\n\treturn nil\n}\n\n// Addr implements net.Listener.\nfunc (l *OutboundListener) Addr() net.Addr {\n\treturn &net.TCPAddr{\n\t\tIP:   net.IP{0, 0, 0, 0},\n\t\tPort: 0,\n\t}\n}\n\nfunc NewOutbound(tag string, listener *OutboundListener) *Outbound {\n\treturn &Outbound{\n\t\ttag:      tag,\n\t\tlistener: listener,\n\t}\n}\n\n// Outbound is a outbound.Handler that handles gRPC connections.\ntype Outbound struct {\n\ttag      string\n\tlistener *OutboundListener\n\taccess   sync.RWMutex\n\tclosed   bool\n}\n\n// Dispatch implements outbound.Handler.\nfunc (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {\n\tco.access.RLock()\n\n\tif co.closed {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\tco.access.RUnlock()\n\t\treturn\n\t}\n\n\tcloseSignal := done.New()\n\tc := net.NewConnection(net.ConnectionInputMulti(link.Writer), net.ConnectionOutputMulti(link.Reader), net.ConnectionOnClose(closeSignal))\n\tco.listener.addWithContext(ctx, c)\n\tco.access.RUnlock()\n\t<-closeSignal.Wait()\n}\n\n// Tag implements outbound.Handler.\nfunc (co *Outbound) Tag() string {\n\treturn co.tag\n}\n\n// Start implements common.Runnable.\nfunc (co *Outbound) Start() error {\n\tco.access.Lock()\n\tco.closed = false\n\tco.access.Unlock()\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (co *Outbound) Close() error {\n\tco.access.Lock()\n\tdefer co.access.Unlock()\n\n\tco.closed = true\n\treturn co.listener.Close()\n}\n"
  },
  {
    "path": "common/net/address.go",
    "content": "package net\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n)\n\nvar (\n\t// LocalHostIP is a constant value for localhost IP in IPv4.\n\tLocalHostIP = IPAddress([]byte{127, 0, 0, 1})\n\n\t// AnyIP is a constant value for any IP in IPv4.\n\tAnyIP = IPAddress([]byte{0, 0, 0, 0})\n\n\t// LocalHostDomain is a constant value for localhost domain.\n\tLocalHostDomain = DomainAddress(\"localhost\")\n\n\t// LocalHostIPv6 is a constant value for localhost IP in IPv6.\n\tLocalHostIPv6 = IPAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})\n\n\t// AnyIPv6 is a constant value for any IP in IPv6.\n\tAnyIPv6 = IPAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})\n)\n\n// AddressFamily is the type of address.\ntype AddressFamily byte\n\nconst (\n\t// AddressFamilyIPv4 represents address as IPv4\n\tAddressFamilyIPv4 = AddressFamily(0)\n\n\t// AddressFamilyIPv6 represents address as IPv6\n\tAddressFamilyIPv6 = AddressFamily(1)\n\n\t// AddressFamilyDomain represents address as Domain\n\tAddressFamilyDomain = AddressFamily(2)\n)\n\n// IsIPv4 returns true if current AddressFamily is IPv4.\nfunc (af AddressFamily) IsIPv4() bool {\n\treturn af == AddressFamilyIPv4\n}\n\n// IsIPv6 returns true if current AddressFamily is IPv6.\nfunc (af AddressFamily) IsIPv6() bool {\n\treturn af == AddressFamilyIPv6\n}\n\n// IsIP returns true if current AddressFamily is IPv6 or IPv4.\nfunc (af AddressFamily) IsIP() bool {\n\treturn af == AddressFamilyIPv4 || af == AddressFamilyIPv6\n}\n\n// IsDomain returns true if current AddressFamily is Domain.\nfunc (af AddressFamily) IsDomain() bool {\n\treturn af == AddressFamilyDomain\n}\n\n// Address represents a network address to be communicated with. It may be an IP address or domain\n// address, not both. This interface doesn't resolve IP address for a given domain.\ntype Address interface {\n\tIP() net.IP     // IP of this Address\n\tDomain() string // Domain of this Address\n\tFamily() AddressFamily\n\tString() string // String representation of this Address\n}\n\nfunc isAlphaNum(c byte) bool {\n\treturn (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')\n}\n\n// ParseAddress parses a string into an Address. The return value will be an IPAddress when\n// the string is in the form of IPv4 or IPv6 address, or a DomainAddress otherwise.\nfunc ParseAddress(addr string) Address {\n\t// Handle IPv6 address in form as \"[2001:4860:0:2001::68]\"\n\tlenAddr := len(addr)\n\tif lenAddr > 0 && addr[0] == '[' && addr[lenAddr-1] == ']' {\n\t\taddr = addr[1 : lenAddr-1]\n\t\tlenAddr -= 2\n\t}\n\n\tif lenAddr > 0 && (!isAlphaNum(addr[0]) || !isAlphaNum(addr[len(addr)-1])) {\n\t\taddr = strings.TrimSpace(addr)\n\t}\n\n\tip := net.ParseIP(addr)\n\tif ip != nil {\n\t\treturn IPAddress(ip)\n\t}\n\treturn DomainAddress(addr)\n}\n\nvar bytes0 = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}\n\n// IPAddress creates an Address with given IP.\nfunc IPAddress(ip []byte) Address {\n\tswitch len(ip) {\n\tcase net.IPv4len:\n\t\tvar addr ipv4Address = [4]byte{ip[0], ip[1], ip[2], ip[3]}\n\t\treturn addr\n\tcase net.IPv6len:\n\t\tif bytes.Equal(ip[:10], bytes0) && ip[10] == 0xff && ip[11] == 0xff {\n\t\t\treturn IPAddress(ip[12:16])\n\t\t}\n\t\tvar addr ipv6Address = [16]byte{\n\t\t\tip[0], ip[1], ip[2], ip[3],\n\t\t\tip[4], ip[5], ip[6], ip[7],\n\t\t\tip[8], ip[9], ip[10], ip[11],\n\t\t\tip[12], ip[13], ip[14], ip[15],\n\t\t}\n\t\treturn addr\n\tdefault:\n\t\tnewError(\"invalid IP format: \", ip).AtError().WriteToLog()\n\t\treturn nil\n\t}\n}\n\n// DomainAddress creates an Address with given domain.\nfunc DomainAddress(domain string) Address {\n\treturn domainAddress(domain)\n}\n\ntype ipv4Address [4]byte\n\nfunc (a ipv4Address) IP() net.IP {\n\treturn net.IP(a[:])\n}\n\nfunc (ipv4Address) Domain() string {\n\tpanic(\"Calling Domain() on an IPv4Address.\")\n}\n\nfunc (ipv4Address) Family() AddressFamily {\n\treturn AddressFamilyIPv4\n}\n\nfunc (a ipv4Address) String() string {\n\treturn a.IP().String()\n}\n\ntype ipv6Address [16]byte\n\nfunc (a ipv6Address) IP() net.IP {\n\treturn net.IP(a[:])\n}\n\nfunc (ipv6Address) Domain() string {\n\tpanic(\"Calling Domain() on an IPv6Address.\")\n}\n\nfunc (ipv6Address) Family() AddressFamily {\n\treturn AddressFamilyIPv6\n}\n\nfunc (a ipv6Address) String() string {\n\treturn \"[\" + a.IP().String() + \"]\"\n}\n\ntype domainAddress string\n\nfunc (domainAddress) IP() net.IP {\n\tpanic(\"Calling IP() on a DomainAddress.\")\n}\n\nfunc (a domainAddress) Domain() string {\n\treturn string(a)\n}\n\nfunc (domainAddress) Family() AddressFamily {\n\treturn AddressFamilyDomain\n}\n\nfunc (a domainAddress) String() string {\n\treturn a.Domain()\n}\n\n// AsAddress translates IPOrDomain to Address.\nfunc (d *IPOrDomain) AsAddress() Address {\n\tif d == nil {\n\t\treturn nil\n\t}\n\tswitch addr := d.Address.(type) {\n\tcase *IPOrDomain_Ip:\n\t\treturn IPAddress(addr.Ip)\n\tcase *IPOrDomain_Domain:\n\t\treturn DomainAddress(addr.Domain)\n\t}\n\tpanic(\"Common|Net: Invalid address.\")\n}\n\n// NewIPOrDomain translates Address to IPOrDomain\nfunc NewIPOrDomain(addr Address) *IPOrDomain {\n\tswitch addr.Family() {\n\tcase AddressFamilyDomain:\n\t\treturn &IPOrDomain{\n\t\t\tAddress: &IPOrDomain_Domain{\n\t\t\t\tDomain: addr.Domain(),\n\t\t\t},\n\t\t}\n\tcase AddressFamilyIPv4, AddressFamilyIPv6:\n\t\treturn &IPOrDomain{\n\t\t\tAddress: &IPOrDomain_Ip{\n\t\t\t\tIp: addr.IP(),\n\t\t\t},\n\t\t}\n\tdefault:\n\t\tpanic(\"Unknown Address type.\")\n\t}\n}\n\nfunc (d *IPOrDomain) UnmarshalJSONPB(unmarshaler *jsonpb.Unmarshaler, bytes []byte) error {\n\tvar ipOrDomain string\n\tif err := json.Unmarshal(bytes, &ipOrDomain); err != nil {\n\t\treturn err\n\t}\n\tresult := NewIPOrDomain(ParseAddress(ipOrDomain))\n\td.Address = result.Address\n\treturn nil\n}\n\nfunc (d *IPOrDomain) MarshalJSONPB(marshaler *jsonpb.Marshaler) ([]byte, error) {\n\tipod := d.AsAddress().String()\n\n\treturn json.Marshal(ipod)\n}\n"
  },
  {
    "path": "common/net/address.pb.go",
    "content": "package net\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// Address of a network host. It may be either an IP address or a domain\n// address.\ntype IPOrDomain struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Types that are valid to be assigned to Address:\n\t//\n\t//\t*IPOrDomain_Ip\n\t//\t*IPOrDomain_Domain\n\tAddress       isIPOrDomain_Address `protobuf_oneof:\"address\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *IPOrDomain) Reset() {\n\t*x = IPOrDomain{}\n\tmi := &file_common_net_address_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *IPOrDomain) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*IPOrDomain) ProtoMessage() {}\n\nfunc (x *IPOrDomain) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_net_address_proto_msgTypes[0]\n\tif 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 IPOrDomain.ProtoReflect.Descriptor instead.\nfunc (*IPOrDomain) Descriptor() ([]byte, []int) {\n\treturn file_common_net_address_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *IPOrDomain) GetAddress() isIPOrDomain_Address {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *IPOrDomain) GetIp() []byte {\n\tif x != nil {\n\t\tif x, ok := x.Address.(*IPOrDomain_Ip); ok {\n\t\t\treturn x.Ip\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (x *IPOrDomain) GetDomain() string {\n\tif x != nil {\n\t\tif x, ok := x.Address.(*IPOrDomain_Domain); ok {\n\t\t\treturn x.Domain\n\t\t}\n\t}\n\treturn \"\"\n}\n\ntype isIPOrDomain_Address interface {\n\tisIPOrDomain_Address()\n}\n\ntype IPOrDomain_Ip struct {\n\t// IP address. Must by either 4 or 16 bytes.\n\tIp []byte `protobuf:\"bytes,1,opt,name=ip,proto3,oneof\"`\n}\n\ntype IPOrDomain_Domain struct {\n\t// Domain address.\n\tDomain string `protobuf:\"bytes,2,opt,name=domain,proto3,oneof\"`\n}\n\nfunc (*IPOrDomain_Ip) isIPOrDomain_Address() {}\n\nfunc (*IPOrDomain_Domain) isIPOrDomain_Address() {}\n\nvar File_common_net_address_proto protoreflect.FileDescriptor\n\nconst file_common_net_address_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x18common/net/address.proto\\x12\\x15v2ray.core.common.net\\\"C\\n\" +\n\t\"\\n\" +\n\t\"IPOrDomain\\x12\\x10\\n\" +\n\t\"\\x02ip\\x18\\x01 \\x01(\\fH\\x00R\\x02ip\\x12\\x18\\n\" +\n\t\"\\x06domain\\x18\\x02 \\x01(\\tH\\x00R\\x06domainB\\t\\n\" +\n\t\"\\aaddressB`\\n\" +\n\t\"\\x19com.v2ray.core.common.netP\\x01Z)github.com/v2fly/v2ray-core/v5/common/net\\xaa\\x02\\x15V2Ray.Core.Common.Netb\\x06proto3\"\n\nvar (\n\tfile_common_net_address_proto_rawDescOnce sync.Once\n\tfile_common_net_address_proto_rawDescData []byte\n)\n\nfunc file_common_net_address_proto_rawDescGZIP() []byte {\n\tfile_common_net_address_proto_rawDescOnce.Do(func() {\n\t\tfile_common_net_address_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_net_address_proto_rawDesc), len(file_common_net_address_proto_rawDesc)))\n\t})\n\treturn file_common_net_address_proto_rawDescData\n}\n\nvar file_common_net_address_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_net_address_proto_goTypes = []any{\n\t(*IPOrDomain)(nil), // 0: v2ray.core.common.net.IPOrDomain\n}\nvar file_common_net_address_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_common_net_address_proto_init() }\nfunc file_common_net_address_proto_init() {\n\tif File_common_net_address_proto != nil {\n\t\treturn\n\t}\n\tfile_common_net_address_proto_msgTypes[0].OneofWrappers = []any{\n\t\t(*IPOrDomain_Ip)(nil),\n\t\t(*IPOrDomain_Domain)(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: unsafe.Slice(unsafe.StringData(file_common_net_address_proto_rawDesc), len(file_common_net_address_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_net_address_proto_goTypes,\n\t\tDependencyIndexes: file_common_net_address_proto_depIdxs,\n\t\tMessageInfos:      file_common_net_address_proto_msgTypes,\n\t}.Build()\n\tFile_common_net_address_proto = out.File\n\tfile_common_net_address_proto_goTypes = nil\n\tfile_common_net_address_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/net/address.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.net;\noption csharp_namespace = \"V2Ray.Core.Common.Net\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/net\";\noption java_package = \"com.v2ray.core.common.net\";\noption java_multiple_files = true;\n\n// Address of a network host. It may be either an IP address or a domain\n// address.\nmessage IPOrDomain {\n  oneof address {\n    // IP address. Must by either 4 or 16 bytes.\n    bytes ip = 1;\n\n    // Domain address.\n    string domain = 2;\n  }\n}\n"
  },
  {
    "path": "common/net/address_test.go",
    "content": "package net_test\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc TestAddressProperty(t *testing.T) {\n\ttype addrProprty struct {\n\t\tIP     []byte\n\t\tDomain string\n\t\tFamily AddressFamily\n\t\tString string\n\t}\n\n\ttestCases := []struct {\n\t\tInput  Address\n\t\tOutput addrProprty\n\t}{\n\t\t{\n\t\t\tInput: IPAddress([]byte{byte(1), byte(2), byte(3), byte(4)}),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{byte(1), byte(2), byte(3), byte(4)},\n\t\t\t\tFamily: AddressFamilyIPv4,\n\t\t\t\tString: \"1.2.3.4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: IPAddress([]byte{\n\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t}),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP: []byte{\n\t\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t\t},\n\t\t\t\tFamily: AddressFamilyIPv6,\n\t\t\t\tString: \"[102:304:102:304:102:304:102:304]\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: IPAddress([]byte{\n\t\t\t\tbyte(0), byte(0), byte(0), byte(0),\n\t\t\t\tbyte(0), byte(0), byte(0), byte(0),\n\t\t\t\tbyte(0), byte(0), byte(255), byte(255),\n\t\t\t\tbyte(1), byte(2), byte(3), byte(4),\n\t\t\t}),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{byte(1), byte(2), byte(3), byte(4)},\n\t\t\t\tFamily: AddressFamilyIPv4,\n\t\t\t\tString: \"1.2.3.4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: DomainAddress(\"v2fly.org\"),\n\t\t\tOutput: addrProprty{\n\t\t\t\tDomain: \"v2fly.org\",\n\t\t\t\tFamily: AddressFamilyDomain,\n\t\t\t\tString: \"v2fly.org\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: IPAddress(net.IPv4(1, 2, 3, 4)),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{byte(1), byte(2), byte(3), byte(4)},\n\t\t\t\tFamily: AddressFamilyIPv4,\n\t\t\t\tString: \"1.2.3.4\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: ParseAddress(\"[2001:4860:0:2001::68]\"),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{0x20, 0x01, 0x48, 0x60, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68},\n\t\t\t\tFamily: AddressFamilyIPv6,\n\t\t\t\tString: \"[2001:4860:0:2001::68]\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: ParseAddress(\"::0\"),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     AnyIPv6.IP(),\n\t\t\t\tFamily: AddressFamilyIPv6,\n\t\t\t\tString: \"[::]\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: ParseAddress(\"[::ffff:123.151.71.143]\"),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{123, 151, 71, 143},\n\t\t\t\tFamily: AddressFamilyIPv4,\n\t\t\t\tString: \"123.151.71.143\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: NewIPOrDomain(ParseAddress(\"v2fly.org\")).AsAddress(),\n\t\t\tOutput: addrProprty{\n\t\t\t\tDomain: \"v2fly.org\",\n\t\t\t\tFamily: AddressFamilyDomain,\n\t\t\t\tString: \"v2fly.org\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: NewIPOrDomain(ParseAddress(\"8.8.8.8\")).AsAddress(),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{8, 8, 8, 8},\n\t\t\t\tFamily: AddressFamilyIPv4,\n\t\t\t\tString: \"8.8.8.8\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: NewIPOrDomain(ParseAddress(\"[2001:4860:0:2001::68]\")).AsAddress(),\n\t\t\tOutput: addrProprty{\n\t\t\t\tIP:     []byte{0x20, 0x01, 0x48, 0x60, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68},\n\t\t\t\tFamily: AddressFamilyIPv6,\n\t\t\t\tString: \"[2001:4860:0:2001::68]\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tactual := addrProprty{\n\t\t\tFamily: testCase.Input.Family(),\n\t\t\tString: testCase.Input.String(),\n\t\t}\n\t\tif testCase.Input.Family().IsIP() {\n\t\t\tactual.IP = testCase.Input.IP()\n\t\t} else {\n\t\t\tactual.Domain = testCase.Input.Domain()\n\t\t}\n\n\t\tif r := cmp.Diff(actual, testCase.Output); r != \"\" {\n\t\t\tt.Error(\"for input: \", testCase.Input, \":\", r)\n\t\t}\n\t}\n}\n\nfunc TestInvalidAddressConvertion(t *testing.T) {\n\tpanics := func(f func()) (ret bool) {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\tret = true\n\t\t\t}\n\t\t}()\n\t\tf()\n\t\treturn false\n\t}\n\n\ttestCases := []func(){\n\t\tfunc() { ParseAddress(\"8.8.8.8\").Domain() },\n\t\tfunc() { ParseAddress(\"2001:4860:0:2001::68\").Domain() },\n\t\tfunc() { ParseAddress(\"v2fly.org\").IP() },\n\t}\n\tfor idx, testCase := range testCases {\n\t\tif !panics(testCase) {\n\t\t\tt.Error(\"case \", idx, \" failed\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkParseAddressIPv4(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\taddr := ParseAddress(\"8.8.8.8\")\n\t\tif addr.Family() != AddressFamilyIPv4 {\n\t\t\tpanic(\"not ipv4\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkParseAddressIPv6(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\taddr := ParseAddress(\"2001:4860:0:2001::68\")\n\t\tif addr.Family() != AddressFamilyIPv6 {\n\t\t\tpanic(\"not ipv6\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkParseAddressDomain(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\taddr := ParseAddress(\"v2fly.org\")\n\t\tif addr.Family() != AddressFamilyDomain {\n\t\t\tpanic(\"not domain\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/net/connection.go",
    "content": "package net\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n)\n\ntype ConnectionOption func(*connection)\n\nfunc ConnectionLocalAddr(a net.Addr) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.local = a\n\t}\n}\n\nfunc ConnectionRemoteAddr(a net.Addr) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.remote = a\n\t}\n}\n\nfunc ConnectionInput(writer io.Writer) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.writer = buf.NewWriter(writer)\n\t}\n}\n\nfunc ConnectionInputMulti(writer buf.Writer) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.writer = writer\n\t}\n}\n\nfunc ConnectionOutput(reader io.Reader) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.reader = &buf.BufferedReader{Reader: buf.NewReader(reader)}\n\t}\n}\n\nfunc ConnectionOutputMulti(reader buf.Reader) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.reader = &buf.BufferedReader{Reader: reader}\n\t}\n}\n\nfunc ConnectionOutputMultiUDP(reader buf.Reader) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.reader = &buf.BufferedReader{\n\t\t\tReader:  reader,\n\t\t\tSpliter: buf.SplitFirstBytes,\n\t\t}\n\t}\n}\n\nfunc ConnectionOnClose(n io.Closer) ConnectionOption {\n\treturn func(c *connection) {\n\t\tc.onClose = n\n\t}\n}\n\nfunc NewConnection(opts ...ConnectionOption) net.Conn {\n\tc := &connection{\n\t\tdone: done.New(),\n\t\tlocal: &net.TCPAddr{\n\t\t\tIP:   []byte{0, 0, 0, 0},\n\t\t\tPort: 0,\n\t\t},\n\t\tremote: &net.TCPAddr{\n\t\t\tIP:   []byte{0, 0, 0, 0},\n\t\t\tPort: 0,\n\t\t},\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(c)\n\t}\n\n\treturn c\n}\n\ntype connection struct {\n\treader  *buf.BufferedReader\n\twriter  buf.Writer\n\tdone    *done.Instance\n\tonClose io.Closer\n\tlocal   Addr\n\tremote  Addr\n}\n\nfunc (c *connection) Read(b []byte) (int, error) {\n\treturn c.reader.Read(b)\n}\n\n// ReadMultiBuffer implements buf.Reader.\nfunc (c *connection) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\treturn c.reader.ReadMultiBuffer()\n}\n\n// Write implements net.Conn.Write().\nfunc (c *connection) Write(b []byte) (int, error) {\n\tif c.done.Done() {\n\t\treturn 0, io.ErrClosedPipe\n\t}\n\n\tif len(b)/buf.Size+1 > 64*1024*1024 {\n\t\treturn 0, errors.New(\"value too large\")\n\t}\n\tl := len(b)\n\tsliceSize := l/buf.Size + 1\n\tmb := make(buf.MultiBuffer, 0, sliceSize)\n\tmb = buf.MergeBytes(mb, b)\n\treturn l, c.writer.WriteMultiBuffer(mb)\n}\n\nfunc (c *connection) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tif c.done.Done() {\n\t\tbuf.ReleaseMulti(mb)\n\t\treturn io.ErrClosedPipe\n\t}\n\n\treturn c.writer.WriteMultiBuffer(mb)\n}\n\n// Close implements net.Conn.Close().\nfunc (c *connection) Close() error {\n\tcommon.Must(c.done.Close())\n\tcommon.Interrupt(c.reader)\n\tcommon.Close(c.writer)\n\tif c.onClose != nil {\n\t\treturn c.onClose.Close()\n\t}\n\n\treturn nil\n}\n\n// LocalAddr implements net.Conn.LocalAddr().\nfunc (c *connection) LocalAddr() net.Addr {\n\treturn c.local\n}\n\n// RemoteAddr implements net.Conn.RemoteAddr().\nfunc (c *connection) RemoteAddr() net.Addr {\n\treturn c.remote\n}\n\n// SetDeadline implements net.Conn.SetDeadline().\nfunc (c *connection) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\n// SetReadDeadline implements net.Conn.SetReadDeadline().\nfunc (c *connection) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\n// SetWriteDeadline implements net.Conn.SetWriteDeadline().\nfunc (c *connection) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n"
  },
  {
    "path": "common/net/destination.go",
    "content": "package net\n\nimport (\n\t\"net\"\n\t\"strings\"\n)\n\n// Destination represents a network destination including address and protocol (tcp / udp).\ntype Destination struct {\n\tAddress Address\n\tPort    Port\n\tNetwork Network\n}\n\n// DestinationFromAddr generates a Destination from a net address.\nfunc DestinationFromAddr(addr net.Addr) Destination {\n\tswitch addr := addr.(type) {\n\tcase *net.TCPAddr:\n\t\treturn TCPDestination(IPAddress(addr.IP), Port(addr.Port))\n\tcase *net.UDPAddr:\n\t\treturn UDPDestination(IPAddress(addr.IP), Port(addr.Port))\n\tcase *net.UnixAddr:\n\t\treturn UnixDestination(DomainAddress(addr.Name))\n\tdefault:\n\t\tpanic(\"Net: Unknown address type.\")\n\t}\n}\n\n// ParseDestination converts a destination from its string presentation.\nfunc ParseDestination(dest string) (Destination, error) {\n\td := Destination{\n\t\tAddress: AnyIP,\n\t\tPort:    Port(0),\n\t}\n\n\tswitch {\n\tcase strings.HasPrefix(dest, \"tcp:\"):\n\t\td.Network = Network_TCP\n\t\tdest = dest[4:]\n\tcase strings.HasPrefix(dest, \"udp:\"):\n\t\td.Network = Network_UDP\n\t\tdest = dest[4:]\n\tcase strings.HasPrefix(dest, \"unix:\"):\n\t\td = UnixDestination(DomainAddress(dest[5:]))\n\t\treturn d, nil\n\t}\n\n\thstr, pstr, err := SplitHostPort(dest)\n\tif err != nil {\n\t\treturn d, err\n\t}\n\tif len(hstr) > 0 {\n\t\td.Address = ParseAddress(hstr)\n\t}\n\tif len(pstr) > 0 {\n\t\tport, err := PortFromString(pstr)\n\t\tif err != nil {\n\t\t\treturn d, err\n\t\t}\n\t\td.Port = port\n\t}\n\treturn d, nil\n}\n\n// TCPDestination creates a TCP destination with given address\nfunc TCPDestination(address Address, port Port) Destination {\n\treturn Destination{\n\t\tNetwork: Network_TCP,\n\t\tAddress: address,\n\t\tPort:    port,\n\t}\n}\n\n// UDPDestination creates a UDP destination with given address\nfunc UDPDestination(address Address, port Port) Destination {\n\treturn Destination{\n\t\tNetwork: Network_UDP,\n\t\tAddress: address,\n\t\tPort:    port,\n\t}\n}\n\n// UnixDestination creates a Unix destination with given address\nfunc UnixDestination(address Address) Destination {\n\treturn Destination{\n\t\tNetwork: Network_UNIX,\n\t\tAddress: address,\n\t}\n}\n\n// NetAddr returns the network address in this Destination in string form.\nfunc (d Destination) NetAddr() string {\n\taddr := \"\"\n\tif d.Network == Network_TCP || d.Network == Network_UDP {\n\t\taddr = d.Address.String() + \":\" + d.Port.String()\n\t} else if d.Network == Network_UNIX {\n\t\taddr = d.Address.String()\n\t}\n\treturn addr\n}\n\n// String returns the strings form of this Destination.\nfunc (d Destination) String() string {\n\tprefix := \"unknown:\"\n\tswitch d.Network {\n\tcase Network_TCP:\n\t\tprefix = \"tcp:\"\n\tcase Network_UDP:\n\t\tprefix = \"udp:\"\n\tcase Network_UNIX:\n\t\tprefix = \"unix:\"\n\t}\n\treturn prefix + d.NetAddr()\n}\n\n// IsValid returns true if this Destination is valid.\nfunc (d Destination) IsValid() bool {\n\treturn d.Network != Network_Unknown\n}\n\n// AsDestination converts current Endpoint into Destination.\nfunc (p *Endpoint) AsDestination() Destination {\n\treturn Destination{\n\t\tNetwork: p.Network,\n\t\tAddress: p.Address.AsAddress(),\n\t\tPort:    Port(p.Port),\n\t}\n}\n"
  },
  {
    "path": "common/net/destination.pb.go",
    "content": "package net\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// Endpoint of a network connection.\ntype Endpoint struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tNetwork       Network                `protobuf:\"varint,1,opt,name=network,proto3,enum=v2ray.core.common.net.Network\" json:\"network,omitempty\"`\n\tAddress       *IPOrDomain            `protobuf:\"bytes,2,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,3,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Endpoint) Reset() {\n\t*x = Endpoint{}\n\tmi := &file_common_net_destination_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Endpoint) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Endpoint) ProtoMessage() {}\n\nfunc (x *Endpoint) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_net_destination_proto_msgTypes[0]\n\tif 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 Endpoint.ProtoReflect.Descriptor instead.\nfunc (*Endpoint) Descriptor() ([]byte, []int) {\n\treturn file_common_net_destination_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Endpoint) GetNetwork() Network {\n\tif x != nil {\n\t\treturn x.Network\n\t}\n\treturn Network_Unknown\n}\n\nfunc (x *Endpoint) GetAddress() *IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *Endpoint) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nvar File_common_net_destination_proto protoreflect.FileDescriptor\n\nconst file_common_net_destination_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1ccommon/net/destination.proto\\x12\\x15v2ray.core.common.net\\x1a\\x18common/net/network.proto\\x1a\\x18common/net/address.proto\\\"\\x95\\x01\\n\" +\n\t\"\\bEndpoint\\x128\\n\" +\n\t\"\\anetwork\\x18\\x01 \\x01(\\x0e2\\x1e.v2ray.core.common.net.NetworkR\\anetwork\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x02 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x03 \\x01(\\rR\\x04portB`\\n\" +\n\t\"\\x19com.v2ray.core.common.netP\\x01Z)github.com/v2fly/v2ray-core/v5/common/net\\xaa\\x02\\x15V2Ray.Core.Common.Netb\\x06proto3\"\n\nvar (\n\tfile_common_net_destination_proto_rawDescOnce sync.Once\n\tfile_common_net_destination_proto_rawDescData []byte\n)\n\nfunc file_common_net_destination_proto_rawDescGZIP() []byte {\n\tfile_common_net_destination_proto_rawDescOnce.Do(func() {\n\t\tfile_common_net_destination_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_net_destination_proto_rawDesc), len(file_common_net_destination_proto_rawDesc)))\n\t})\n\treturn file_common_net_destination_proto_rawDescData\n}\n\nvar file_common_net_destination_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_net_destination_proto_goTypes = []any{\n\t(*Endpoint)(nil),   // 0: v2ray.core.common.net.Endpoint\n\t(Network)(0),       // 1: v2ray.core.common.net.Network\n\t(*IPOrDomain)(nil), // 2: v2ray.core.common.net.IPOrDomain\n}\nvar file_common_net_destination_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.common.net.Endpoint.network:type_name -> v2ray.core.common.net.Network\n\t2, // 1: v2ray.core.common.net.Endpoint.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_common_net_destination_proto_init() }\nfunc file_common_net_destination_proto_init() {\n\tif File_common_net_destination_proto != nil {\n\t\treturn\n\t}\n\tfile_common_net_network_proto_init()\n\tfile_common_net_address_proto_init()\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: unsafe.Slice(unsafe.StringData(file_common_net_destination_proto_rawDesc), len(file_common_net_destination_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_net_destination_proto_goTypes,\n\t\tDependencyIndexes: file_common_net_destination_proto_depIdxs,\n\t\tMessageInfos:      file_common_net_destination_proto_msgTypes,\n\t}.Build()\n\tFile_common_net_destination_proto = out.File\n\tfile_common_net_destination_proto_goTypes = nil\n\tfile_common_net_destination_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/net/destination.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.net;\noption csharp_namespace = \"V2Ray.Core.Common.Net\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/net\";\noption java_package = \"com.v2ray.core.common.net\";\noption java_multiple_files = true;\n\nimport \"common/net/network.proto\";\nimport \"common/net/address.proto\";\n\n// Endpoint of a network connection.\nmessage Endpoint {\n  Network network = 1;\n  IPOrDomain address = 2;\n  uint32 port = 3;\n}\n"
  },
  {
    "path": "common/net/destination_test.go",
    "content": "package net_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc TestDestinationProperty(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput     Destination\n\t\tNetwork   Network\n\t\tString    string\n\t\tNetString string\n\t}{\n\t\t{\n\t\t\tInput:     TCPDestination(IPAddress([]byte{1, 2, 3, 4}), 80),\n\t\t\tNetwork:   Network_TCP,\n\t\t\tString:    \"tcp:1.2.3.4:80\",\n\t\t\tNetString: \"1.2.3.4:80\",\n\t\t},\n\t\t{\n\t\t\tInput:     UDPDestination(IPAddress([]byte{0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88}), 53),\n\t\t\tNetwork:   Network_UDP,\n\t\t\tString:    \"udp:[2001:4860:4860::8888]:53\",\n\t\t\tNetString: \"[2001:4860:4860::8888]:53\",\n\t\t},\n\t\t{\n\t\t\tInput:     UnixDestination(DomainAddress(\"/tmp/test.sock\")),\n\t\t\tNetwork:   Network_UNIX,\n\t\t\tString:    \"unix:/tmp/test.sock\",\n\t\t\tNetString: \"/tmp/test.sock\",\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tdest := testCase.Input\n\t\tif r := cmp.Diff(dest.Network, testCase.Network); r != \"\" {\n\t\t\tt.Error(\"unexpected Network in \", dest.String(), \": \", r)\n\t\t}\n\t\tif r := cmp.Diff(dest.String(), testCase.String); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t\tif r := cmp.Diff(dest.NetAddr(), testCase.NetString); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t}\n}\n\nfunc TestDestinationParse(t *testing.T) {\n\tcases := []struct {\n\t\tInput  string\n\t\tOutput Destination\n\t\tError  bool\n\t}{\n\t\t{\n\t\t\tInput:  \"tcp:127.0.0.1:80\",\n\t\t\tOutput: TCPDestination(LocalHostIP, Port(80)),\n\t\t},\n\t\t{\n\t\t\tInput:  \"udp:8.8.8.8:53\",\n\t\t\tOutput: UDPDestination(IPAddress([]byte{8, 8, 8, 8}), Port(53)),\n\t\t},\n\t\t{\n\t\t\tInput:  \"unix:/tmp/test.sock\",\n\t\t\tOutput: UnixDestination(DomainAddress(\"/tmp/test.sock\")),\n\t\t},\n\t\t{\n\t\t\tInput: \"8.8.8.8:53\",\n\t\t\tOutput: Destination{\n\t\t\t\tAddress: IPAddress([]byte{8, 8, 8, 8}),\n\t\t\t\tPort:    Port(53),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: \":53\",\n\t\t\tOutput: Destination{\n\t\t\t\tAddress: AnyIP,\n\t\t\t\tPort:    Port(53),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: \"8.8.8.8\",\n\t\t\tError: true,\n\t\t},\n\t\t{\n\t\t\tInput: \"8.8.8.8:http\",\n\t\t\tError: true,\n\t\t},\n\t\t{\n\t\t\tInput: \"/tmp/test.sock\",\n\t\t\tError: true,\n\t\t},\n\t}\n\n\tfor _, testcase := range cases {\n\t\td, err := ParseDestination(testcase.Input)\n\t\tif !testcase.Error {\n\t\t\tif err != nil {\n\t\t\t\tt.Error(\"for test case: \", testcase.Input, \" expected no error, but got \", err)\n\t\t\t}\n\t\t\tif d != testcase.Output {\n\t\t\t\tt.Error(\"for test case: \", testcase.Input, \" expected output: \", testcase.Output.String(), \" but got \", d.String())\n\t\t\t}\n\t\t} else if err == nil {\n\t\t\tt.Error(\"for test case: \", testcase.Input, \" expected error, but got nil\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/net/errors.generated.go",
    "content": "package net\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/net/net.go",
    "content": "// Package net is a drop-in replacement to Golang's net package, with some more functionalities.\npackage net\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/net/network.go",
    "content": "package net\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n)\n\nfunc (n Network) SystemString() string {\n\tswitch n {\n\tcase Network_TCP:\n\t\treturn \"tcp\"\n\tcase Network_UDP:\n\t\treturn \"udp\"\n\tcase Network_UNIX:\n\t\treturn \"unix\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\nfunc (nl *NetworkList) UnmarshalJSONPB(unmarshaler *jsonpb.Unmarshaler, bytes []byte) error {\n\tvar networkStrList []string\n\tif err := json.Unmarshal(bytes, &networkStrList); err == nil {\n\t\tnl.Network = ParseNetworkStringList(networkStrList)\n\t\treturn nil\n\t}\n\n\tvar networkStr string\n\tif err := json.Unmarshal(bytes, &networkStr); err == nil {\n\t\tstrList := strings.Split(networkStr, \",\")\n\t\tnl.Network = ParseNetworkStringList(strList)\n\t\treturn nil\n\t}\n\n\treturn newError(\"unknown format of a string list: \" + string(bytes))\n}\n\nfunc (nl *NetworkList) MarshalJSONPB(marshaler *jsonpb.Marshaler) ([]byte, error) {\n\tnetworkStrList := make([]string, len(nl.Network))\n\n\tfor idx, network := range nl.Network {\n\t\tnetworkStrList[idx] = network.String()\n\t}\n\n\treturn json.Marshal(networkStrList)\n}\n\n// HasNetwork returns true if the network list has a certain network.\nfunc HasNetwork(list []Network, network Network) bool {\n\tfor _, value := range list {\n\t\tif value == network {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc ParseNetwork(net string) Network {\n\tswitch strings.ToLower(net) {\n\tcase \"tcp\":\n\t\treturn Network_TCP\n\tcase \"udp\":\n\t\treturn Network_UDP\n\tcase \"unix\":\n\t\treturn Network_UNIX\n\tdefault:\n\t\treturn Network_Unknown\n\t}\n}\n\nfunc ParseNetworkStringList(strList []string) []Network {\n\tlist := make([]Network, len(strList))\n\tfor idx, str := range strList {\n\t\tlist[idx] = ParseNetwork(str)\n\t}\n\n\treturn list\n}\n"
  },
  {
    "path": "common/net/network.pb.go",
    "content": "package net\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Network int32\n\nconst (\n\tNetwork_Unknown Network = 0\n\t// Deprecated: Marked as deprecated in common/net/network.proto.\n\tNetwork_RawTCP Network = 1\n\tNetwork_TCP    Network = 2\n\tNetwork_UDP    Network = 3\n\tNetwork_UNIX   Network = 4\n)\n\n// Enum value maps for Network.\nvar (\n\tNetwork_name = map[int32]string{\n\t\t0: \"Unknown\",\n\t\t1: \"RawTCP\",\n\t\t2: \"TCP\",\n\t\t3: \"UDP\",\n\t\t4: \"UNIX\",\n\t}\n\tNetwork_value = map[string]int32{\n\t\t\"Unknown\": 0,\n\t\t\"RawTCP\":  1,\n\t\t\"TCP\":     2,\n\t\t\"UDP\":     3,\n\t\t\"UNIX\":    4,\n\t}\n)\n\nfunc (x Network) Enum() *Network {\n\tp := new(Network)\n\t*p = x\n\treturn p\n}\n\nfunc (x Network) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Network) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_common_net_network_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Network) Type() protoreflect.EnumType {\n\treturn &file_common_net_network_proto_enumTypes[0]\n}\n\nfunc (x Network) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Network.Descriptor instead.\nfunc (Network) EnumDescriptor() ([]byte, []int) {\n\treturn file_common_net_network_proto_rawDescGZIP(), []int{0}\n}\n\n// NetworkList is a list of Networks.\ntype NetworkList struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tNetwork       []Network              `protobuf:\"varint,1,rep,packed,name=network,proto3,enum=v2ray.core.common.net.Network\" json:\"network,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *NetworkList) Reset() {\n\t*x = NetworkList{}\n\tmi := &file_common_net_network_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *NetworkList) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NetworkList) ProtoMessage() {}\n\nfunc (x *NetworkList) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_net_network_proto_msgTypes[0]\n\tif 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 NetworkList.ProtoReflect.Descriptor instead.\nfunc (*NetworkList) Descriptor() ([]byte, []int) {\n\treturn file_common_net_network_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *NetworkList) GetNetwork() []Network {\n\tif x != nil {\n\t\treturn x.Network\n\t}\n\treturn nil\n}\n\nvar File_common_net_network_proto protoreflect.FileDescriptor\n\nconst file_common_net_network_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x18common/net/network.proto\\x12\\x15v2ray.core.common.net\\\"G\\n\" +\n\t\"\\vNetworkList\\x128\\n\" +\n\t\"\\anetwork\\x18\\x01 \\x03(\\x0e2\\x1e.v2ray.core.common.net.NetworkR\\anetwork*B\\n\" +\n\t\"\\aNetwork\\x12\\v\\n\" +\n\t\"\\aUnknown\\x10\\x00\\x12\\x0e\\n\" +\n\t\"\\x06RawTCP\\x10\\x01\\x1a\\x02\\b\\x01\\x12\\a\\n\" +\n\t\"\\x03TCP\\x10\\x02\\x12\\a\\n\" +\n\t\"\\x03UDP\\x10\\x03\\x12\\b\\n\" +\n\t\"\\x04UNIX\\x10\\x04B`\\n\" +\n\t\"\\x19com.v2ray.core.common.netP\\x01Z)github.com/v2fly/v2ray-core/v5/common/net\\xaa\\x02\\x15V2Ray.Core.Common.Netb\\x06proto3\"\n\nvar (\n\tfile_common_net_network_proto_rawDescOnce sync.Once\n\tfile_common_net_network_proto_rawDescData []byte\n)\n\nfunc file_common_net_network_proto_rawDescGZIP() []byte {\n\tfile_common_net_network_proto_rawDescOnce.Do(func() {\n\t\tfile_common_net_network_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_net_network_proto_rawDesc), len(file_common_net_network_proto_rawDesc)))\n\t})\n\treturn file_common_net_network_proto_rawDescData\n}\n\nvar file_common_net_network_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_common_net_network_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_net_network_proto_goTypes = []any{\n\t(Network)(0),        // 0: v2ray.core.common.net.Network\n\t(*NetworkList)(nil), // 1: v2ray.core.common.net.NetworkList\n}\nvar file_common_net_network_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.common.net.NetworkList.network:type_name -> v2ray.core.common.net.Network\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_common_net_network_proto_init() }\nfunc file_common_net_network_proto_init() {\n\tif File_common_net_network_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: unsafe.Slice(unsafe.StringData(file_common_net_network_proto_rawDesc), len(file_common_net_network_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_net_network_proto_goTypes,\n\t\tDependencyIndexes: file_common_net_network_proto_depIdxs,\n\t\tEnumInfos:         file_common_net_network_proto_enumTypes,\n\t\tMessageInfos:      file_common_net_network_proto_msgTypes,\n\t}.Build()\n\tFile_common_net_network_proto = out.File\n\tfile_common_net_network_proto_goTypes = nil\n\tfile_common_net_network_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/net/network.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.net;\noption csharp_namespace = \"V2Ray.Core.Common.Net\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/net\";\noption java_package = \"com.v2ray.core.common.net\";\noption java_multiple_files = true;\n\nenum Network {\n  Unknown = 0;\n\n  RawTCP = 1 [deprecated = true];\n  TCP = 2;\n  UDP = 3;\n  UNIX = 4;\n}\n\n// NetworkList is a list of Networks.\nmessage NetworkList { repeated Network network = 1; }\n"
  },
  {
    "path": "common/net/packetaddr/config.pb.go",
    "content": "package packetaddr\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 PacketAddrType int32\n\nconst (\n\tPacketAddrType_None   PacketAddrType = 0\n\tPacketAddrType_Packet PacketAddrType = 1\n)\n\n// Enum value maps for PacketAddrType.\nvar (\n\tPacketAddrType_name = map[int32]string{\n\t\t0: \"None\",\n\t\t1: \"Packet\",\n\t}\n\tPacketAddrType_value = map[string]int32{\n\t\t\"None\":   0,\n\t\t\"Packet\": 1,\n\t}\n)\n\nfunc (x PacketAddrType) Enum() *PacketAddrType {\n\tp := new(PacketAddrType)\n\t*p = x\n\treturn p\n}\n\nfunc (x PacketAddrType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (PacketAddrType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_common_net_packetaddr_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (PacketAddrType) Type() protoreflect.EnumType {\n\treturn &file_common_net_packetaddr_config_proto_enumTypes[0]\n}\n\nfunc (x PacketAddrType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use PacketAddrType.Descriptor instead.\nfunc (PacketAddrType) EnumDescriptor() ([]byte, []int) {\n\treturn file_common_net_packetaddr_config_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_common_net_packetaddr_config_proto protoreflect.FileDescriptor\n\nconst file_common_net_packetaddr_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\\"common/net/packetaddr/config.proto\\x12\\x19v2ray.core.net.packetaddr*&\\n\" +\n\t\"\\x0ePacketAddrType\\x12\\b\\n\" +\n\t\"\\x04None\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06Packet\\x10\\x01B\\x81\\x01\\n\" +\n\t\"$com.v2ray.core.common.net.packetaddrP\\x01Z4github.com/v2fly/v2ray-core/v5/common/net/packetaddr\\xaa\\x02 V2Ray.Core.Common.Net.Packetaddrb\\x06proto3\"\n\nvar (\n\tfile_common_net_packetaddr_config_proto_rawDescOnce sync.Once\n\tfile_common_net_packetaddr_config_proto_rawDescData []byte\n)\n\nfunc file_common_net_packetaddr_config_proto_rawDescGZIP() []byte {\n\tfile_common_net_packetaddr_config_proto_rawDescOnce.Do(func() {\n\t\tfile_common_net_packetaddr_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_net_packetaddr_config_proto_rawDesc), len(file_common_net_packetaddr_config_proto_rawDesc)))\n\t})\n\treturn file_common_net_packetaddr_config_proto_rawDescData\n}\n\nvar file_common_net_packetaddr_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_common_net_packetaddr_config_proto_goTypes = []any{\n\t(PacketAddrType)(0), // 0: v2ray.core.net.packetaddr.PacketAddrType\n}\nvar file_common_net_packetaddr_config_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_common_net_packetaddr_config_proto_init() }\nfunc file_common_net_packetaddr_config_proto_init() {\n\tif File_common_net_packetaddr_config_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: unsafe.Slice(unsafe.StringData(file_common_net_packetaddr_config_proto_rawDesc), len(file_common_net_packetaddr_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   0,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_net_packetaddr_config_proto_goTypes,\n\t\tDependencyIndexes: file_common_net_packetaddr_config_proto_depIdxs,\n\t\tEnumInfos:         file_common_net_packetaddr_config_proto_enumTypes,\n\t}.Build()\n\tFile_common_net_packetaddr_config_proto = out.File\n\tfile_common_net_packetaddr_config_proto_goTypes = nil\n\tfile_common_net_packetaddr_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/net/packetaddr/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.net.packetaddr;\noption csharp_namespace = \"V2Ray.Core.Common.Net.Packetaddr\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\";\noption java_package = \"com.v2ray.core.common.net.packetaddr\";\noption java_multiple_files = true;\n\nenum PacketAddrType {\n  None = 0;\n  Packet = 1;\n}"
  },
  {
    "path": "common/net/packetaddr/connection_adaptor.go",
    "content": "package packetaddr\n\nimport (\n\t\"context\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\nvar (\n\terrNotPacketConn = errors.New(\"not a packet connection\")\n\terrUnsupported   = errors.New(\"unsupported action\")\n)\n\nfunc ToPacketAddrConn(link *transport.Link, dest net.Destination) (net.PacketConn, error) {\n\tif !dest.Address.Family().IsDomain() {\n\t\treturn nil, errNotPacketConn\n\t}\n\tswitch dest.Address.Domain() {\n\tcase seqPacketMagicAddress:\n\t\treturn &packetConnectionAdaptor{\n\t\t\treaderAccess: &sync.Mutex{},\n\t\t\treaderBuffer: nil,\n\t\t\tlink:         link,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, errNotPacketConn\n\t}\n}\n\nfunc CreatePacketAddrConn(ctx context.Context, dispatcher routing.Dispatcher, isStream bool) (net.PacketConn, error) {\n\tif isStream {\n\t\treturn nil, errUnsupported\n\t}\n\tpacketDest := net.Destination{\n\t\tAddress: net.DomainAddress(seqPacketMagicAddress),\n\t\tPort:    0,\n\t\tNetwork: net.Network_UDP,\n\t}\n\tlink, err := dispatcher.Dispatch(ctx, packetDest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &packetConnectionAdaptor{\n\t\treaderAccess: &sync.Mutex{},\n\t\treaderBuffer: nil,\n\t\tlink:         link,\n\t}, nil\n}\n\ntype packetConnectionAdaptor struct {\n\treaderAccess *sync.Mutex\n\treaderBuffer buf.MultiBuffer\n\tlink         *transport.Link\n}\n\nfunc (c *packetConnectionAdaptor) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) {\n\tc.readerAccess.Lock()\n\tdefer c.readerAccess.Unlock()\n\tif c.readerBuffer.IsEmpty() {\n\t\tc.readerBuffer, err = c.link.Reader.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t}\n\tc.readerBuffer, n = buf.SplitFirstBytes(c.readerBuffer, p)\n\tvar w *buf.Buffer\n\tw, addr, err = ExtractAddressFromPacket(buf.FromBytes(p[:n]))\n\tn = copy(p, w.Bytes())\n\tw.Release()\n\treturn\n}\n\nfunc (c *packetConnectionAdaptor) WriteTo(p []byte, addr gonet.Addr) (n int, err error) {\n\t_, ok := addr.(*gonet.UDPAddr)\n\tif !ok {\n\t\t// address other than UDPAddr is not supported, and will be dropped.\n\t\treturn 0, nil\n\t}\n\tpayloadLen := len(p)\n\tvar buffer *buf.Buffer\n\tbuffer, err = AttachAddressToPacket(buf.FromBytes(p), addr)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tmb := buf.MultiBuffer{buffer}\n\terr = c.link.Writer.WriteMultiBuffer(mb)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn payloadLen, nil\n}\n\nfunc (c *packetConnectionAdaptor) Close() error {\n\tc.readerAccess.Lock()\n\tdefer c.readerAccess.Unlock()\n\tc.readerBuffer = buf.ReleaseMulti(c.readerBuffer)\n\treturn common.Interrupt(c.link)\n}\n\nfunc (c packetConnectionAdaptor) LocalAddr() gonet.Addr {\n\treturn &gonet.UnixAddr{Name: \"unsupported\"}\n}\n\nfunc (c packetConnectionAdaptor) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (c packetConnectionAdaptor) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (c packetConnectionAdaptor) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc ToPacketAddrConnWrapper(conn net.PacketConn, isStream bool) FusedConnection {\n\treturn &packetConnWrapper{conn}\n}\n\ntype packetConnWrapper struct {\n\tnet.PacketConn\n}\n\nfunc (pc *packetConnWrapper) RemoteAddr() gonet.Addr {\n\treturn nil\n}\n\ntype FusedConnection interface {\n\tnet.PacketConn\n\tnet.Conn\n}\n\nfunc (pc *packetConnWrapper) Read(p []byte) (n int, err error) {\n\trecbuf := buf.StackNew()\n\trecbuf.Extend(2048)\n\tn, addr, err := pc.PacketConn.ReadFrom(recbuf.Bytes())\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\trecbuf.Resize(0, int32(n))\n\tresult, err := AttachAddressToPacket(&recbuf, addr)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn = copy(p, result.Bytes())\n\tresult.Release()\n\treturn n, nil\n}\n\nfunc (pc *packetConnWrapper) Write(p []byte) (n int, err error) {\n\tdata, addr, err := ExtractAddressFromPacket(buf.FromBytes(p))\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t_, err = pc.PacketConn.WriteTo(data.Bytes(), addr)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdata.Release()\n\treturn len(p), nil\n}\n\nfunc (pc *packetConnWrapper) Close() error {\n\treturn pc.PacketConn.Close()\n}\n\nfunc GetDestinationSubsetOf(dest net.Destination) (bool, error) {\n\tif !dest.Address.Family().IsDomain() {\n\t\treturn false, errNotPacketConn\n\t}\n\tswitch dest.Address.Domain() {\n\tcase seqPacketMagicAddress:\n\t\treturn false, nil\n\tdefault:\n\t\treturn false, errNotPacketConn\n\t}\n}\n"
  },
  {
    "path": "common/net/packetaddr/packetaddr.go",
    "content": "package packetaddr\n\nimport (\n\t\"bytes\"\n\tgonet \"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(0x02, net.AddressFamilyIPv6),\n)\n\n// AttachAddressToPacket\n// relinquish ownership of data\n// gain ownership of the returning value\nfunc AttachAddressToPacket(data *buf.Buffer, address gonet.Addr) (*buf.Buffer, error) {\n\tpacketBuf := buf.New()\n\tudpaddr := address.(*gonet.UDPAddr)\n\tport, err := net.PortFromInt(uint32(udpaddr.Port))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = addrParser.WriteAddressPort(packetBuf, net.IPAddress(udpaddr.IP), port)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t_, err = packetBuf.Write(data.Bytes())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdata.Release()\n\treturn packetBuf, nil\n}\n\n// ExtractAddressFromPacket\n// relinquish ownership of data\n// gain ownership of the returning value\nfunc ExtractAddressFromPacket(data *buf.Buffer) (*buf.Buffer, gonet.Addr, error) {\n\tpacketBuf := buf.StackNew()\n\taddress, port, err := addrParser.ReadAddressPort(&packetBuf, bytes.NewReader(data.Bytes()))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif address.Family().IsDomain() {\n\t\treturn nil, nil, errors.New(\"invalid address type\")\n\t}\n\taddr := &gonet.UDPAddr{\n\t\tIP:   address.IP(),\n\t\tPort: int(port.Value()),\n\t\tZone: \"\",\n\t}\n\tdata.Advance(packetBuf.Len())\n\tpacketBuf.Release()\n\treturn data, addr, nil\n}\n"
  },
  {
    "path": "common/net/packetaddr/packetaddr_test.go",
    "content": "package packetaddr\n\nimport (\n\tsysnet \"net\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\nfunc TestPacketEncodingIPv4(t *testing.T) {\n\tpacketAddress := &sysnet.UDPAddr{\n\t\tIP:   sysnet.IPv4(1, 2, 3, 4).To4(),\n\t\tPort: 1234,\n\t}\n\tvar packetData [256]byte\n\twrapped, err := AttachAddressToPacket(buf.FromBytes(packetData[:]), packetAddress)\n\tassert.NoError(t, err)\n\n\tpacketPayload, decodedAddress, err := ExtractAddressFromPacket(wrapped)\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, packetPayload.Bytes(), packetData[:])\n\tassert.Equal(t, packetAddress, decodedAddress)\n}\n\nfunc TestPacketEncodingIPv6(t *testing.T) {\n\tpacketAddress := &sysnet.UDPAddr{\n\t\tIP:   sysnet.IPv6linklocalallrouters,\n\t\tPort: 1234,\n\t}\n\tvar packetData [256]byte\n\twrapped, err := AttachAddressToPacket(buf.FromBytes(packetData[:]), packetAddress)\n\tassert.NoError(t, err)\n\n\tpacketPayload, decodedAddress, err := ExtractAddressFromPacket(wrapped)\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, packetPayload.Bytes(), packetData[:])\n\tassert.Equal(t, packetAddress, decodedAddress)\n}\n"
  },
  {
    "path": "common/net/packetaddr/special_address.go",
    "content": "package packetaddr\n\nconst seqPacketMagicAddress = \"sp.packet-addr.v2fly.arpa\"\n"
  },
  {
    "path": "common/net/port.go",
    "content": "package net\n\nimport (\n\t\"encoding/binary\"\n\t\"strconv\"\n)\n\n// Port represents a network port in TCP and UDP protocol.\ntype Port uint16\n\n// PortFromBytes converts a byte array to a Port, assuming bytes are in big endian order.\n// @unsafe Caller must ensure that the byte array has at least 2 elements.\nfunc PortFromBytes(port []byte) Port {\n\treturn Port(binary.BigEndian.Uint16(port))\n}\n\n// PortFromInt converts an integer to a Port.\n// @error when the integer is not positive or larger then 65535\nfunc PortFromInt(val uint32) (Port, error) {\n\tif val > 65535 {\n\t\treturn Port(0), newError(\"invalid port range: \", val)\n\t}\n\treturn Port(val), nil\n}\n\n// PortFromString converts a string to a Port.\n// @error when the string is not an integer or the integral value is a not a valid Port.\nfunc PortFromString(s string) (Port, error) {\n\tval, err := strconv.ParseUint(s, 10, 32)\n\tif err != nil {\n\t\treturn Port(0), newError(\"invalid port range: \", s)\n\t}\n\treturn PortFromInt(uint32(val))\n}\n\n// Value return the corresponding uint16 value of a Port.\nfunc (p Port) Value() uint16 {\n\treturn uint16(p)\n}\n\n// String returns the string presentation of a Port.\nfunc (p Port) String() string {\n\treturn strconv.Itoa(int(p))\n}\n\n// FromPort returns the beginning port of this PortRange.\nfunc (p *PortRange) FromPort() Port {\n\treturn Port(p.From)\n}\n\n// ToPort returns the end port of this PortRange.\nfunc (p *PortRange) ToPort() Port {\n\treturn Port(p.To)\n}\n\n// Contains returns true if the given port is within the range of a PortRange.\nfunc (p *PortRange) Contains(port Port) bool {\n\treturn p.FromPort() <= port && port <= p.ToPort()\n}\n\n// SinglePortRange returns a PortRange contains a single port.\nfunc SinglePortRange(p Port) *PortRange {\n\treturn &PortRange{\n\t\tFrom: uint32(p),\n\t\tTo:   uint32(p),\n\t}\n}\n\ntype MemoryPortRange struct {\n\tFrom Port\n\tTo   Port\n}\n\nfunc (r MemoryPortRange) Contains(port Port) bool {\n\treturn r.From <= port && port <= r.To\n}\n\ntype MemoryPortList []MemoryPortRange\n\nfunc PortListFromProto(l *PortList) MemoryPortList {\n\tmpl := make(MemoryPortList, 0, len(l.Range))\n\tfor _, r := range l.Range {\n\t\tmpl = append(mpl, MemoryPortRange{From: Port(r.From), To: Port(r.To)})\n\t}\n\treturn mpl\n}\n\nfunc (mpl MemoryPortList) Contains(port Port) bool {\n\tfor _, pr := range mpl {\n\t\tif pr.Contains(port) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "common/net/port.pb.go",
    "content": "package net\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// PortRange represents a range of ports.\ntype PortRange struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// The port that this range starts from.\n\tFrom uint32 `protobuf:\"varint,1,opt,name=From,proto3\" json:\"From,omitempty\"`\n\t// The port that this range ends with (inclusive).\n\tTo            uint32 `protobuf:\"varint,2,opt,name=To,proto3\" json:\"To,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PortRange) Reset() {\n\t*x = PortRange{}\n\tmi := &file_common_net_port_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PortRange) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PortRange) ProtoMessage() {}\n\nfunc (x *PortRange) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_net_port_proto_msgTypes[0]\n\tif 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 PortRange.ProtoReflect.Descriptor instead.\nfunc (*PortRange) Descriptor() ([]byte, []int) {\n\treturn file_common_net_port_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *PortRange) GetFrom() uint32 {\n\tif x != nil {\n\t\treturn x.From\n\t}\n\treturn 0\n}\n\nfunc (x *PortRange) GetTo() uint32 {\n\tif x != nil {\n\t\treturn x.To\n\t}\n\treturn 0\n}\n\n// PortList is a list of ports.\ntype PortList struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tRange         []*PortRange           `protobuf:\"bytes,1,rep,name=range,proto3\" json:\"range,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PortList) Reset() {\n\t*x = PortList{}\n\tmi := &file_common_net_port_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PortList) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PortList) ProtoMessage() {}\n\nfunc (x *PortList) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_net_port_proto_msgTypes[1]\n\tif 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 PortList.ProtoReflect.Descriptor instead.\nfunc (*PortList) Descriptor() ([]byte, []int) {\n\treturn file_common_net_port_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *PortList) GetRange() []*PortRange {\n\tif x != nil {\n\t\treturn x.Range\n\t}\n\treturn nil\n}\n\nvar File_common_net_port_proto protoreflect.FileDescriptor\n\nconst file_common_net_port_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x15common/net/port.proto\\x12\\x15v2ray.core.common.net\\\"/\\n\" +\n\t\"\\tPortRange\\x12\\x12\\n\" +\n\t\"\\x04From\\x18\\x01 \\x01(\\rR\\x04From\\x12\\x0e\\n\" +\n\t\"\\x02To\\x18\\x02 \\x01(\\rR\\x02To\\\"B\\n\" +\n\t\"\\bPortList\\x126\\n\" +\n\t\"\\x05range\\x18\\x01 \\x03(\\v2 .v2ray.core.common.net.PortRangeR\\x05rangeB`\\n\" +\n\t\"\\x19com.v2ray.core.common.netP\\x01Z)github.com/v2fly/v2ray-core/v5/common/net\\xaa\\x02\\x15V2Ray.Core.Common.Netb\\x06proto3\"\n\nvar (\n\tfile_common_net_port_proto_rawDescOnce sync.Once\n\tfile_common_net_port_proto_rawDescData []byte\n)\n\nfunc file_common_net_port_proto_rawDescGZIP() []byte {\n\tfile_common_net_port_proto_rawDescOnce.Do(func() {\n\t\tfile_common_net_port_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_net_port_proto_rawDesc), len(file_common_net_port_proto_rawDesc)))\n\t})\n\treturn file_common_net_port_proto_rawDescData\n}\n\nvar file_common_net_port_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_common_net_port_proto_goTypes = []any{\n\t(*PortRange)(nil), // 0: v2ray.core.common.net.PortRange\n\t(*PortList)(nil),  // 1: v2ray.core.common.net.PortList\n}\nvar file_common_net_port_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.common.net.PortList.range:type_name -> v2ray.core.common.net.PortRange\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_common_net_port_proto_init() }\nfunc file_common_net_port_proto_init() {\n\tif File_common_net_port_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: unsafe.Slice(unsafe.StringData(file_common_net_port_proto_rawDesc), len(file_common_net_port_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_net_port_proto_goTypes,\n\t\tDependencyIndexes: file_common_net_port_proto_depIdxs,\n\t\tMessageInfos:      file_common_net_port_proto_msgTypes,\n\t}.Build()\n\tFile_common_net_port_proto = out.File\n\tfile_common_net_port_proto_goTypes = nil\n\tfile_common_net_port_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/net/port.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.net;\noption csharp_namespace = \"V2Ray.Core.Common.Net\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/net\";\noption java_package = \"com.v2ray.core.common.net\";\noption java_multiple_files = true;\n\n// PortRange represents a range of ports.\nmessage PortRange {\n  // The port that this range starts from.\n  uint32 From = 1;\n  // The port that this range ends with (inclusive).\n  uint32 To = 2;\n}\n\n// PortList is a list of ports.\nmessage PortList {\n  repeated PortRange range = 1;\n}\n"
  },
  {
    "path": "common/net/port_test.go",
    "content": "package net_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc TestPortRangeContains(t *testing.T) {\n\tportRange := &PortRange{\n\t\tFrom: 53,\n\t\tTo:   53,\n\t}\n\n\tif !portRange.Contains(Port(53)) {\n\t\tt.Error(\"expected port range containing 53, but actually not\")\n\t}\n}\n"
  },
  {
    "path": "common/net/system.go",
    "content": "package net\n\nimport \"net\"\n\nconst (\n\tIPv4len = net.IPv4len\n\tIPv6len = net.IPv6len\n)\n\nvar (\n\tCIDRMask        = net.CIDRMask\n\tDial            = net.Dial\n\tDialTCP         = net.DialTCP\n\tDialUDP         = net.DialUDP\n\tDialUnix        = net.DialUnix\n\tFileConn        = net.FileConn\n\tFileListener    = net.FileListener\n\tListen          = net.Listen\n\tListenTCP       = net.ListenTCP\n\tListenUDP       = net.ListenUDP\n\tListenUnix      = net.ListenUnix\n\tLookupIP        = net.LookupIP\n\tParseCIDR       = net.ParseCIDR\n\tParseIP         = net.ParseIP\n\tResolveUDPAddr  = net.ResolveUDPAddr\n\tResolveUnixAddr = net.ResolveUnixAddr\n\tSplitHostPort   = net.SplitHostPort\n)\n\ntype (\n\tAddr         = net.Addr\n\tAddrError    = net.AddrError\n\tConn         = net.Conn\n\tDialer       = net.Dialer\n\tError        = net.Error\n\tIP           = net.IP\n\tIPMask       = net.IPMask\n\tIPNet        = net.IPNet\n\tListenConfig = net.ListenConfig\n\tListener     = net.Listener\n\tPacketConn   = net.PacketConn\n\tResolver     = net.Resolver\n\tTCPAddr      = net.TCPAddr\n\tTCPConn      = net.TCPConn\n\tTCPListener  = net.TCPListener\n\tUDPAddr      = net.UDPAddr\n\tUDPConn      = net.UDPConn\n\tUnixAddr     = net.UnixAddr\n\tUnixConn     = net.UnixConn\n\tUnixListener = net.UnixListener\n)\n"
  },
  {
    "path": "common/packetswitch/gvisorstack/adapter.go",
    "content": "package gvisorstack\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"gvisor.dev/gvisor/pkg/buffer\"\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/header\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\nfunc NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(_ context.Context, mtu int, networkLayerSwitch packetswitch.NetworkLayerDevice) *NetworkLayerDeviceToGvisorLinkEndpointAdaptor {\n\treturn &NetworkLayerDeviceToGvisorLinkEndpointAdaptor{\n\t\tmtu:                mtu,\n\t\tnetworkLayerSwitch: networkLayerSwitch,\n\t\twaitCh:             make(chan struct{}),\n\t}\n}\n\n// NetworkLayerDeviceToGvisorLinkEndpointAdaptor is primarily machine generated.\ntype NetworkLayerDeviceToGvisorLinkEndpointAdaptor struct {\n\tmtu                int\n\tnetworkLayerSwitch packetswitch.NetworkLayerDevice\n\n\tmu         sync.RWMutex\n\tdispatcher stack.NetworkDispatcher\n\tattached   bool\n\tclosed     bool\n\tonClose    func()\n\twaitCh     chan struct{}\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) MTU() uint32 {\n\tn.mu.RLock()\n\tdefer n.mu.RUnlock()\n\treturn uint32(n.mtu)\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) SetMTU(mtu uint32) {\n\tn.mu.Lock()\n\tdefer n.mu.Unlock()\n\tn.mtu = int(mtu)\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) MaxHeaderLength() uint16 {\n\t// No additional link-layer header.\n\treturn 0\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) LinkAddress() tcpip.LinkAddress {\n\t// Not applicable for network-layer device.\n\treturn \"\"\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) SetLinkAddress(_ tcpip.LinkAddress) {\n\t// no-op\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) Capabilities() stack.LinkEndpointCapabilities {\n\treturn stack.CapabilityNone\n}\n\n// networkLayerWriter adapts packets from NetworkLayerDevice into gVisor Stack.\ntype networkLayerWriter struct {\n\tparent *NetworkLayerDeviceToGvisorLinkEndpointAdaptor\n}\n\nfunc (w *networkLayerWriter) Write(packet []byte) (int, error) {\n\tif len(packet) == 0 {\n\t\treturn 0, nil\n\t}\n\n\tbuf := buffer.MakeWithData(packet)\n\tpkt := stack.NewPacketBuffer(stack.PacketBufferOptions{\n\t\tPayload: buf,\n\t\t// Do not call buf.Release here; PacketBuffer.DecRef will release internal buffer.\n\t})\n\n\t// Determine network protocol by IP version.\n\tver := packet[0] >> 4\n\tvar proto tcpip.NetworkProtocolNumber\n\tswitch ver {\n\tcase 4:\n\t\tproto = ipv4.ProtocolNumber\n\tcase 6:\n\t\tproto = ipv6.ProtocolNumber\n\tdefault:\n\t\t// Unknown network packet, drop.\n\t\tpkt.DecRef()\n\t\treturn 0, nil\n\t}\n\n\tw.parent.mu.RLock()\n\td := w.parent.dispatcher\n\tw.parent.mu.RUnlock()\n\tif d == nil {\n\t\t// No dispatcher attached, drop.\n\t\tpkt.DecRef()\n\t\treturn 0, nil\n\t}\n\n\t// Deliver to network layer. The dispatcher takes ownership of pkt\n\t// and is responsible for releasing it.\n\td.DeliverNetworkPacket(proto, pkt)\n\treturn len(packet), nil\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) Attach(dispatcher stack.NetworkDispatcher) {\n\tn.mu.Lock()\n\tdefer n.mu.Unlock()\n\tif dispatcher == nil {\n\t\t// Detaching.\n\t\tn.dispatcher = nil\n\t\tn.attached = false\n\t\treturn\n\t}\n\n\tn.dispatcher = dispatcher\n\twriter := &networkLayerWriter{parent: n}\n\t// Let the network layer device know where to write incoming packets.\n\tif err := n.networkLayerSwitch.OnAttach(writer); err == nil {\n\t\tn.attached = true\n\t} else {\n\t\t// OnAttach failed; keep attached false.\n\t\tn.attached = false\n\t}\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) IsAttached() bool {\n\tn.mu.RLock()\n\tdefer n.mu.RUnlock()\n\treturn n.attached\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) Wait() {\n\t// If closed, return immediately.\n\tn.mu.RLock()\n\tclosed := n.closed\n\tch := n.waitCh\n\tn.mu.RUnlock()\n\tif closed {\n\t\treturn\n\t}\n\t// Wait until closed is signaled.\n\t<-ch\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) ARPHardwareType() header.ARPHardwareType {\n\treturn header.ARPHardwareNone\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) AddHeader(_ *stack.PacketBuffer) {\n\t// No link-layer header to add.\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) ParseHeader(_ *stack.PacketBuffer) bool {\n\t// Nothing to parse; packet is a bare network packet.\n\treturn true\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) Close() {\n\tn.mu.Lock()\n\tif n.closed {\n\t\tn.mu.Unlock()\n\t\treturn\n\t}\n\tn.closed = true\n\tn.attached = false\n\tn.mu.Unlock()\n\n\t// Close underlying network device if any.\n\t_ = common.Close(n.networkLayerSwitch)\n\n\t// Run onClose action if set.\n\tn.mu.RLock()\n\tonc := n.onClose\n\tch := n.waitCh\n\tn.mu.RUnlock()\n\tif onc != nil {\n\t\tonc()\n\t}\n\n\t// Signal waiters.\n\tclose(ch)\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) SetOnCloseAction(f func()) {\n\tn.mu.Lock()\n\tdefer n.mu.Unlock()\n\tn.onClose = f\n}\n\nfunc (n *NetworkLayerDeviceToGvisorLinkEndpointAdaptor) WritePackets(list stack.PacketBufferList) (int, tcpip.Error) {\n\t// Defensive: if receiver is nil, treat as closed.\n\tif n == nil {\n\t\treturn 0, &tcpip.ErrClosedForSend{}\n\t}\n\t// Convert each packet to bytes and write to networkLayerSwitch.\n\tslice := list.AsSlice()\n\tif len(slice) == 0 {\n\t\treturn 0, nil\n\t}\n\n\tn.mu.RLock()\n\tdev := n.networkLayerSwitch\n\tmtu := n.mtu\n\tn.mu.RUnlock()\n\tif dev == nil {\n\t\treturn 0, &tcpip.ErrClosedForSend{}\n\t}\n\n\twritten := 0\n\tfor _, pkt := range slice {\n\t\tif pkt == nil {\n\t\t\tcontinue\n\t\t}\n\t\t// Get slices and copy into a contiguous buffer.\n\t\tslices := pkt.AsSlices()\n\t\ttotal := 0\n\t\tfor _, s := range slices {\n\t\t\ttotal += len(s)\n\t\t}\n\t\tif mtu > 0 && total > mtu {\n\t\t\treturn written, &tcpip.ErrMessageTooLong{}\n\t\t}\n\t\tcp := make([]byte, total)\n\t\toff := 0\n\t\tfor _, s := range slices {\n\t\t\tcopy(cp[off:], s)\n\t\t\toff += len(s)\n\t\t}\n\t\t_, err := dev.Write(cp)\n\t\tif err != nil {\n\t\t\t// Map writer error to tcpip error.\n\t\t\treturn written, &tcpip.ErrNoBufferSpace{}\n\t\t}\n\t\twritten++\n\t}\n\n\treturn written, nil\n}\n"
  },
  {
    "path": "common/packetswitch/gvisorstack/adapter_test.go",
    "content": "package gvisorstack\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"gvisor.dev/gvisor/pkg/buffer\"\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\n// fakeDevice implements packetswitch.NetworkLayerDevice for testing.\ntype fakeDevice struct {\n\tmu       sync.Mutex\n\twriter   packetswitch.NetworkLayerPacketWriter\n\twrites   [][]byte\n\tclosed   bool\n\tonAttach func(packetswitch.NetworkLayerPacketWriter) error\n}\n\nfunc (f *fakeDevice) OnAttach(w packetswitch.NetworkLayerPacketWriter) error {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tf.writer = w\n\tif f.onAttach != nil {\n\t\treturn f.onAttach(w)\n\t}\n\treturn nil\n}\n\nfunc (f *fakeDevice) Write(packet []byte) (int, error) {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tif f.closed {\n\t\treturn 0, errors.New(\"closed\")\n\t}\n\t// make a copy to avoid aliasing test buffer.\n\tcp := make([]byte, len(packet))\n\tcopy(cp, packet)\n\tf.writes = append(f.writes, cp)\n\treturn len(packet), nil\n}\n\nfunc (f *fakeDevice) Close() error {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tf.closed = true\n\treturn nil\n}\n\nfunc (f *fakeDevice) getWriter() packetswitch.NetworkLayerPacketWriter {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\treturn f.writer\n}\n\nfunc (f *fakeDevice) lastWrite() []byte {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tif len(f.writes) == 0 {\n\t\treturn nil\n\t}\n\treturn f.writes[len(f.writes)-1]\n}\n\n// fakeDispatcher implements stack.NetworkDispatcher, capturing delivered packets.\ntype fakeDispatcher struct {\n\tmu        sync.Mutex\n\tprotocols []tcpip.NetworkProtocolNumber\n\tpkts      [][]byte\n}\n\nfunc (d *fakeDispatcher) DeliverNetworkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {\n\t// capture packet payload safely by copying from AsSlices\n\tslices := pkt.AsSlices()\n\ttotal := 0\n\tfor _, s := range slices {\n\t\ttotal += len(s)\n\t}\n\tcp := make([]byte, total)\n\toff := 0\n\tfor _, s := range slices {\n\t\tcopy(cp[off:], s)\n\t\toff += len(s)\n\t}\n\t// record\n\td.mu.Lock()\n\td.protocols = append(d.protocols, protocol)\n\td.pkts = append(d.pkts, cp)\n\td.mu.Unlock()\n\t// release the packet\n\tpkt.DecRef()\n}\n\nfunc (d *fakeDispatcher) DeliverLinkPacket(protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {\n\t// not used in these tests\n\tpkt.DecRef()\n}\n\nfunc (d *fakeDispatcher) last() (tcpip.NetworkProtocolNumber, []byte) {\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\tif len(d.protocols) == 0 {\n\t\treturn 0, nil\n\t}\n\treturn d.protocols[len(d.protocols)-1], d.pkts[len(d.pkts)-1]\n}\n\nfunc TestAttachAndInboundIPv4IPv6(t *testing.T) {\n\tdev := &fakeDevice{}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\td := &fakeDispatcher{}\n\t// Initially not attached\n\tif a.IsAttached() {\n\t\tt.Fatal(\"expected not attached\")\n\t}\n\n\t// Attach should call device.OnAttach and store writer\n\ta.Attach(d)\n\tw := dev.getWriter()\n\tif w == nil {\n\t\tt.Fatal(\"device did not receive writer on attach\")\n\t}\n\tif !a.IsAttached() {\n\t\tt.Fatal(\"expected attached after successful OnAttach\")\n\t}\n\n\t// Send an IPv4 packet (first byte 0x45 = version 4, IHL 5)\n\tipv4pkt := []byte{0x45, 0x00, 0x00, 0x04}\n\tif _, err := w.Write(ipv4pkt); err != nil {\n\t\tt.Fatalf(\"writer.Write failed: %v\", err)\n\t}\n\t// Check dispatcher received it\n\tproto, payload := d.last()\n\tif proto != ipv4.ProtocolNumber {\n\t\tt.Fatalf(\"expected ipv4 protocol, got %v\", proto)\n\t}\n\tif !reflect.DeepEqual(payload, ipv4pkt) {\n\t\tt.Fatalf(\"unexpected payload: %v\", payload)\n\t}\n\n\t// IPv6 packet (first byte 0x60)\n\tipv6pkt := []byte{0x60, 0x00, 0x00, 0x00}\n\tif _, err := w.Write(ipv6pkt); err != nil {\n\t\tt.Fatalf(\"writer.Write failed: %v\", err)\n\t}\n\tproto2, payload2 := d.last()\n\tif proto2 != ipv6.ProtocolNumber {\n\t\tt.Fatalf(\"expected ipv6 protocol, got %v\", proto2)\n\t}\n\tif !reflect.DeepEqual(payload2, ipv6pkt) {\n\t\tt.Fatalf(\"unexpected payload: %v\", payload2)\n\t}\n}\n\nfunc TestInboundNonIPIsDropped(t *testing.T) {\n\tdev := &fakeDevice{}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\td := &fakeDispatcher{}\n\ta.Attach(d)\n\tw := dev.getWriter()\n\tif w == nil {\n\t\tt.Fatal(\"device did not receive writer on attach\")\n\t}\n\n\t// Non-IP packet: first nibble 0\n\tpkt := []byte{0x00, 0x01, 0x02}\n\tif _, err := w.Write(pkt); err != nil {\n\t\tt.Fatalf(\"writer.Write failed: %v\", err)\n\t}\n\t// Dispatcher should not have any packets\n\tproto, payload := d.last()\n\tif payload != nil || proto != 0 {\n\t\tt.Fatalf(\"expected no delivery for non-ip packet, got proto=%v payload=%v\", proto, payload)\n\t}\n}\n\nfunc makePacketBufferPayload(b []byte) *stack.PacketBuffer {\n\tbuf := buffer.MakeWithData(b)\n\tpkt := stack.NewPacketBuffer(stack.PacketBufferOptions{\n\t\tPayload: buf,\n\t})\n\treturn pkt\n}\n\nfunc TestOutboundWritePacketsOk(t *testing.T) {\n\tdev := &fakeDevice{}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\n\t// Prepare a PacketBufferList with one packet\n\tlist := stack.PacketBufferList{}\n\tpayload := []byte{0x45, 0x01, 0x02, 0x03}\n\tpkt := makePacketBufferPayload(payload)\n\tlist.PushBack(pkt)\n\n\twritten, err := a.WritePackets(list)\n\tif err != nil {\n\t\tt.Fatalf(\"WritePackets returned error: %v\", err)\n\t}\n\tif written != 1 {\n\t\tt.Fatalf(\"expected 1 written, got %d\", written)\n\t}\n\t// Device should have received the payload\n\tlw := dev.lastWrite()\n\tif !reflect.DeepEqual(lw, payload) {\n\t\tt.Fatalf(\"device write mismatch: got %v, want %v\", lw, payload)\n\t}\n}\n\nfunc TestWritePacketsMTUExceeded(t *testing.T) {\n\tdev := &fakeDevice{}\n\t// mtu set to 2\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 2, dev)\n\n\tlist := stack.PacketBufferList{}\n\tpayload := []byte{0x45, 0x01, 0x02} // len 3 > mtu 2\n\tpkt := makePacketBufferPayload(payload)\n\tlist.PushBack(pkt)\n\n\twritten, err := a.WritePackets(list)\n\tif err == nil {\n\t\tt.Fatalf(\"expected error due to message too long, got nil\")\n\t}\n\tif _, ok := err.(*tcpip.ErrMessageTooLong); !ok {\n\t\tt.Fatalf(\"expected ErrMessageTooLong, got %T\", err)\n\t}\n\tif written != 0 {\n\t\tt.Fatalf(\"expected 0 written, got %d\", written)\n\t}\n}\n\nfunc TestCloseAndOnCloseActionAndWait(t *testing.T) {\n\tdev := &fakeDevice{}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\tcalled := make(chan struct{})\n\ta.SetOnCloseAction(func() { close(called) })\n\n\t// Wait should block until Close is called. Run Wait in goroutine.\n\tdone := make(chan struct{})\n\tgo func() {\n\t\ta.Wait()\n\t\tclose(done)\n\t}()\n\n\t// Give goroutine a moment to start\n\ttime.Sleep(5 * time.Millisecond)\n\t// Now close\n\ta.Close()\n\n\t// onClose action should be called\n\tselect {\n\tcase <-called:\n\t\t// ok\n\tcase <-time.After(100 * time.Millisecond):\n\t\tt.Fatal(\"onClose was not called\")\n\t}\n\n\t// Wait should return\n\tselect {\n\tcase <-done:\n\t\t// ok\n\tcase <-time.After(100 * time.Millisecond):\n\t\tt.Fatal(\"Wait did not return after Close\")\n\t}\n}\n\nfunc TestAttachOnAttachFailLeavesNotAttached(t *testing.T) {\n\tdev := &fakeDevice{}\n\t// make OnAttach return error\n\tdev.onAttach = func(w packetswitch.NetworkLayerPacketWriter) error {\n\t\treturn errors.New(\"attach fail\")\n\t}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\td := &fakeDispatcher{}\n\ta.Attach(d)\n\tif a.IsAttached() {\n\t\tt.Fatal(\"expected not attached when OnAttach fails\")\n\t}\n}\n\nfunc TestWritePacketsWhenNoDevice(t *testing.T) {\n\t// Create adaptor with nil device\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, nil)\n\tlist := stack.PacketBufferList{}\n\tpayload := []byte{0x45}\n\tpkt := makePacketBufferPayload(payload)\n\tlist.PushBack(pkt)\n\twritten, err := a.WritePackets(list)\n\tif err == nil {\n\t\tt.Fatalf(\"expected ErrClosedForSend, got nil\")\n\t}\n\tif _, ok := err.(*tcpip.ErrClosedForSend); !ok {\n\t\tt.Fatalf(\"expected ErrClosedForSend, got %T\", err)\n\t}\n\tif written != 0 {\n\t\tt.Fatalf(\"expected 0 written, got %d\", written)\n\t}\n}\n\nfunc TestSetMTUAndCapsAndHeaders(t *testing.T) {\n\t// Create adaptor and test MTU setter\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, nil)\n\tif a.MTU() != 1500 {\n\t\tt.Fatalf(\"initial MTU mismatch: %d\", a.MTU())\n\t}\n\ta.SetMTU(9000)\n\tif a.MTU() != 9000 {\n\t\tt.Fatalf(\"MTU not updated: %d\", a.MTU())\n\t}\n\n\t// Caps and headers\n\tif a.MaxHeaderLength() != 0 {\n\t\tt.Fatalf(\"MaxHeaderLength expected 0, got %d\", a.MaxHeaderLength())\n\t}\n\tif a.Capabilities() != stack.CapabilityNone {\n\t\tt.Fatalf(\"Capabilities expected CapabilityNone, got %v\", a.Capabilities())\n\t}\n\tif a.LinkAddress() != \"\" {\n\t\tt.Fatalf(\"LinkAddress expected empty, got %v\", a.LinkAddress())\n\t}\n\t// AddHeader/ParseHeader should not panic and parse returns true\n\tpkt := makePacketBufferPayload([]byte{0x45})\n\t// Should be no-op\n\ta.AddHeader(pkt)\n\tif !a.ParseHeader(pkt) {\n\t\tt.Fatalf(\"ParseHeader expected true\")\n\t}\n\tpkt.DecRef()\n}\n\n// errDevice fails after a certain number of writes to simulate partial failures.\ntype errDevice struct {\n\tmu        sync.Mutex\n\twriter    packetswitch.NetworkLayerPacketWriter\n\twrites    [][]byte\n\tfailAfter int\n\tcalls     int\n\tclosed    bool\n}\n\nfunc (e *errDevice) OnAttach(w packetswitch.NetworkLayerPacketWriter) error {\n\te.mu.Lock()\n\tdefer e.mu.Unlock()\n\te.writer = w\n\treturn nil\n}\n\nfunc (e *errDevice) Write(packet []byte) (int, error) {\n\te.mu.Lock()\n\tdefer e.mu.Unlock()\n\tif e.closed {\n\t\treturn 0, errors.New(\"closed\")\n\t}\n\te.calls++\n\tif e.failAfter > 0 && e.calls > e.failAfter {\n\t\treturn 0, errors.New(\"injected write error\")\n\t}\n\tcp := make([]byte, len(packet))\n\tcopy(cp, packet)\n\te.writes = append(e.writes, cp)\n\treturn len(packet), nil\n}\n\nfunc (e *errDevice) Close() error {\n\te.mu.Lock()\n\tdefer e.mu.Unlock()\n\te.closed = true\n\treturn nil\n}\n\nfunc TestWritePacketsPartialOnError(t *testing.T) {\n\te := &errDevice{failAfter: 1}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, e)\n\n\tlist := stack.PacketBufferList{}\n\tp1 := makePacketBufferPayload([]byte{0x45, 0x01})\n\tp2 := makePacketBufferPayload([]byte{0x45, 0x02})\n\tlist.PushBack(p1)\n\tlist.PushBack(p2)\n\n\twritten, err := a.WritePackets(list)\n\tif err == nil {\n\t\tt.Fatalf(\"expected error due to injected write error\")\n\t}\n\t// We mapped device write errors to ErrNoBufferSpace\n\tif _, ok := err.(*tcpip.ErrNoBufferSpace); !ok {\n\t\tt.Fatalf(\"expected ErrNoBufferSpace, got %T\", err)\n\t}\n\tif written != 1 {\n\t\tt.Fatalf(\"expected 1 written, got %d\", written)\n\t}\n}\n\nfunc TestMultiplePacketsWrite(t *testing.T) {\n\tdev := &fakeDevice{}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\n\tlist := stack.PacketBufferList{}\n\tp1 := makePacketBufferPayload([]byte{0x45, 0x01})\n\tp2 := makePacketBufferPayload([]byte{0x45, 0x02})\n\tp3 := makePacketBufferPayload([]byte{0x45, 0x03})\n\tlist.PushBack(p1)\n\tlist.PushBack(p2)\n\tlist.PushBack(p3)\n\n\twritten, err := a.WritePackets(list)\n\tif err != nil {\n\t\tt.Fatalf(\"WritePackets returned error: %v\", err)\n\t}\n\tif written != 3 {\n\t\tt.Fatalf(\"expected 3 written, got %d\", written)\n\t}\n\t// last write should be p3\n\tlw := dev.lastWrite()\n\tif !reflect.DeepEqual(lw, []byte{0x45, 0x03}) {\n\t\tt.Fatalf(\"unexpected last write: %v\", lw)\n\t}\n}\n\nfunc TestConcurrentWritePacketsAndClose(t *testing.T) {\n\tdev := &fakeDevice{}\n\ta := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(context.Background(), 1500, dev)\n\n\twg := sync.WaitGroup{}\n\tnWorkers := 5\n\tnPerWorker := 50\n\twg.Add(nWorkers)\n\n\tfor i := 0; i < nWorkers; i++ {\n\t\tgo func(id int) {\n\t\t\tdefer wg.Done()\n\t\t\tfor j := 0; j < nPerWorker; j++ {\n\t\t\t\tlist := stack.PacketBufferList{}\n\t\t\t\tpayload := []byte{0x45, byte(id), byte(j)}\n\t\t\t\tpkt := makePacketBufferPayload(payload)\n\t\t\t\tlist.PushBack(pkt)\n\t\t\t\t_, _ = a.WritePackets(list)\n\t\t\t}\n\t\t}(i)\n\t}\n\n\t// Close after a short delay\n\tgo func() {\n\t\ttime.Sleep(10 * time.Millisecond)\n\t\ta.Close()\n\t}()\n\n\twg.Wait()\n\t// Wait should return quickly after Close\n\ta.Wait()\n}\n"
  },
  {
    "path": "common/packetswitch/gvisorstack/config.pb.go",
    "content": "package gvisorstack\n\nimport (\n\troutercommon \"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tinternet \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 TCPListener struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tPort          uint32                 `protobuf:\"varint,1,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tAddress       *routercommon.CIDR     `protobuf:\"bytes,2,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tTag           string                 `protobuf:\"bytes,3,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *TCPListener) Reset() {\n\t*x = TCPListener{}\n\tmi := &file_common_packetswitch_gvisorstack_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TCPListener) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TCPListener) ProtoMessage() {}\n\nfunc (x *TCPListener) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_packetswitch_gvisorstack_config_proto_msgTypes[0]\n\tif 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 TCPListener.ProtoReflect.Descriptor instead.\nfunc (*TCPListener) Descriptor() ([]byte, []int) {\n\treturn file_common_packetswitch_gvisorstack_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *TCPListener) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *TCPListener) GetAddress() *routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *TCPListener) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate                 protoimpl.MessageState `protogen:\"open.v1\"`\n\tMtu                   uint32                 `protobuf:\"varint,2,opt,name=mtu,proto3\" json:\"mtu,omitempty\"`\n\tUserLevel             uint32                 `protobuf:\"varint,3,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tIps                   []*routercommon.CIDR   `protobuf:\"bytes,6,rep,name=ips,proto3\" json:\"ips,omitempty\"`\n\tRoutes                []*routercommon.CIDR   `protobuf:\"bytes,7,rep,name=routes,proto3\" json:\"routes,omitempty\"`\n\tEnablePromiscuousMode bool                   `protobuf:\"varint,8,opt,name=enable_promiscuous_mode,json=enablePromiscuousMode,proto3\" json:\"enable_promiscuous_mode,omitempty\"`\n\tEnableSpoofing        bool                   `protobuf:\"varint,9,opt,name=enable_spoofing,json=enableSpoofing,proto3\" json:\"enable_spoofing,omitempty\"`\n\tSocketSettings        *internet.SocketConfig `protobuf:\"bytes,10,opt,name=socket_settings,json=socketSettings,proto3\" json:\"socket_settings,omitempty\"`\n\tPreferIpv6ForUdp      bool                   `protobuf:\"varint,11,opt,name=prefer_ipv6_for_udp,json=preferIpv6ForUdp,proto3\" json:\"prefer_ipv6_for_udp,omitempty\"`\n\tDualStackUdp          bool                   `protobuf:\"varint,12,opt,name=dual_stack_udp,json=dualStackUdp,proto3\" json:\"dual_stack_udp,omitempty\"`\n\tTcpListener           []*TCPListener         `protobuf:\"bytes,13,rep,name=tcp_listener,json=tcpListener,proto3\" json:\"tcp_listener,omitempty\"`\n\tunknownFields         protoimpl.UnknownFields\n\tsizeCache             protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_common_packetswitch_gvisorstack_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_packetswitch_gvisorstack_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_common_packetswitch_gvisorstack_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetMtu() uint32 {\n\tif x != nil {\n\t\treturn x.Mtu\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetIps() []*routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.Ips\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetRoutes() []*routercommon.CIDR {\n\tif x != nil {\n\t\treturn x.Routes\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetEnablePromiscuousMode() bool {\n\tif x != nil {\n\t\treturn x.EnablePromiscuousMode\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetEnableSpoofing() bool {\n\tif x != nil {\n\t\treturn x.EnableSpoofing\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetSocketSettings() *internet.SocketConfig {\n\tif x != nil {\n\t\treturn x.SocketSettings\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetPreferIpv6ForUdp() bool {\n\tif x != nil {\n\t\treturn x.PreferIpv6ForUdp\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetDualStackUdp() bool {\n\tif x != nil {\n\t\treturn x.DualStackUdp\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetTcpListener() []*TCPListener {\n\tif x != nil {\n\t\treturn x.TcpListener\n\t}\n\treturn nil\n}\n\nvar File_common_packetswitch_gvisorstack_config_proto protoreflect.FileDescriptor\n\nconst file_common_packetswitch_gvisorstack_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\",common/packetswitch/gvisorstack/config.proto\\x12*v2ray.core.common.packetswitch.gvisorstack\\x1a$app/router/routercommon/common.proto\\x1a\\x1ftransport/internet/config.proto\\x1a common/protoext/extensions.proto\\\"w\\n\" +\n\t\"\\vTCPListener\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x01 \\x01(\\rR\\x04port\\x12B\\n\" +\n\t\"\\aaddress\\x18\\x02 \\x01(\\v2(.v2ray.core.app.router.routercommon.CIDRR\\aaddress\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x03 \\x01(\\tR\\x03tag\\\"\\x9f\\x04\\n\" +\n\t\"\\x06Config\\x12\\x10\\n\" +\n\t\"\\x03mtu\\x18\\x02 \\x01(\\rR\\x03mtu\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x03 \\x01(\\rR\\tuserLevel\\x12:\\n\" +\n\t\"\\x03ips\\x18\\x06 \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRR\\x03ips\\x12@\\n\" +\n\t\"\\x06routes\\x18\\a \\x03(\\v2(.v2ray.core.app.router.routercommon.CIDRR\\x06routes\\x126\\n\" +\n\t\"\\x17enable_promiscuous_mode\\x18\\b \\x01(\\bR\\x15enablePromiscuousMode\\x12'\\n\" +\n\t\"\\x0fenable_spoofing\\x18\\t \\x01(\\bR\\x0eenableSpoofing\\x12T\\n\" +\n\t\"\\x0fsocket_settings\\x18\\n\" +\n\t\" \\x01(\\v2+.v2ray.core.transport.internet.SocketConfigR\\x0esocketSettings\\x12-\\n\" +\n\t\"\\x13prefer_ipv6_for_udp\\x18\\v \\x01(\\bR\\x10preferIpv6ForUdp\\x12$\\n\" +\n\t\"\\x0edual_stack_udp\\x18\\f \\x01(\\bR\\fdualStackUdp\\x12Z\\n\" +\n\t\"\\ftcp_listener\\x18\\r \\x03(\\v27.v2ray.core.common.packetswitch.gvisorstack.TCPListenerR\\vtcpListenerB\\x9f\\x01\\n\" +\n\t\".com.v2ray.core.common.packetswitch.gvisorstackP\\x01Z>github.com/v2fly/v2ray-core/v5/common/packetswitch/gvisorstack\\xaa\\x02*V2Ray.Core.Common.Packetswitch.Gvisorstackb\\x06proto3\"\n\nvar (\n\tfile_common_packetswitch_gvisorstack_config_proto_rawDescOnce sync.Once\n\tfile_common_packetswitch_gvisorstack_config_proto_rawDescData []byte\n)\n\nfunc file_common_packetswitch_gvisorstack_config_proto_rawDescGZIP() []byte {\n\tfile_common_packetswitch_gvisorstack_config_proto_rawDescOnce.Do(func() {\n\t\tfile_common_packetswitch_gvisorstack_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_packetswitch_gvisorstack_config_proto_rawDesc), len(file_common_packetswitch_gvisorstack_config_proto_rawDesc)))\n\t})\n\treturn file_common_packetswitch_gvisorstack_config_proto_rawDescData\n}\n\nvar file_common_packetswitch_gvisorstack_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_common_packetswitch_gvisorstack_config_proto_goTypes = []any{\n\t(*TCPListener)(nil),           // 0: v2ray.core.common.packetswitch.gvisorstack.TCPListener\n\t(*Config)(nil),                // 1: v2ray.core.common.packetswitch.gvisorstack.Config\n\t(*routercommon.CIDR)(nil),     // 2: v2ray.core.app.router.routercommon.CIDR\n\t(*internet.SocketConfig)(nil), // 3: v2ray.core.transport.internet.SocketConfig\n}\nvar file_common_packetswitch_gvisorstack_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.common.packetswitch.gvisorstack.TCPListener.address:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t2, // 1: v2ray.core.common.packetswitch.gvisorstack.Config.ips:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t2, // 2: v2ray.core.common.packetswitch.gvisorstack.Config.routes:type_name -> v2ray.core.app.router.routercommon.CIDR\n\t3, // 3: v2ray.core.common.packetswitch.gvisorstack.Config.socket_settings:type_name -> v2ray.core.transport.internet.SocketConfig\n\t0, // 4: v2ray.core.common.packetswitch.gvisorstack.Config.tcp_listener:type_name -> v2ray.core.common.packetswitch.gvisorstack.TCPListener\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_common_packetswitch_gvisorstack_config_proto_init() }\nfunc file_common_packetswitch_gvisorstack_config_proto_init() {\n\tif File_common_packetswitch_gvisorstack_config_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: unsafe.Slice(unsafe.StringData(file_common_packetswitch_gvisorstack_config_proto_rawDesc), len(file_common_packetswitch_gvisorstack_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_packetswitch_gvisorstack_config_proto_goTypes,\n\t\tDependencyIndexes: file_common_packetswitch_gvisorstack_config_proto_depIdxs,\n\t\tMessageInfos:      file_common_packetswitch_gvisorstack_config_proto_msgTypes,\n\t}.Build()\n\tFile_common_packetswitch_gvisorstack_config_proto = out.File\n\tfile_common_packetswitch_gvisorstack_config_proto_goTypes = nil\n\tfile_common_packetswitch_gvisorstack_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/packetswitch/gvisorstack/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.packetswitch.gvisorstack;\noption csharp_namespace = \"V2Ray.Core.Common.Packetswitch.Gvisorstack\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/packetswitch/gvisorstack\";\noption java_package = \"com.v2ray.core.common.packetswitch.gvisorstack\";\noption java_multiple_files = true;\n\nimport \"app/router/routercommon/common.proto\";\nimport \"transport/internet/config.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage TCPListener {\n  uint32 port = 1;\n  v2ray.core.app.router.routercommon.CIDR address = 2;\n  string tag = 3;\n}\n\nmessage Config {\n  uint32 mtu = 2;\n  uint32 user_level = 3;\n  repeated v2ray.core.app.router.routercommon.CIDR ips = 6;\n  repeated v2ray.core.app.router.routercommon.CIDR routes = 7;\n  bool enable_promiscuous_mode = 8;\n  bool enable_spoofing = 9;\n  v2ray.core.transport.internet.SocketConfig socket_settings = 10;\n  bool prefer_ipv6_for_udp = 11;\n  bool dual_stack_udp = 12;\n  repeated TCPListener tcp_listener = 13;\n}"
  },
  {
    "path": "common/packetswitch/gvisorstack/dialer.go",
    "content": "package gvisorstack\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dualStack/fusedPacketConn\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n// DialTCP will create a connection to the given destination, using the stack.\n// Machine Generated\nfunc (w *WrappedStack) DialTCP(ctx context.Context, remoteAddress net.Destination) (net.Conn, error) {\n\tif w == nil || w.stack == nil {\n\t\treturn nil, fmt.Errorf(\"gvisor stack not initialized\")\n\t}\n\n\tif remoteAddress.Network != net.Network_TCP {\n\t\treturn nil, fmt.Errorf(\"destination is not tcp: %v\", remoteAddress.Network)\n\t}\n\n\t// Resolve address to IP if necessary.\n\tvar ipBytes []byte\n\tswitch remoteAddress.Address.Family() {\n\tcase net.AddressFamilyIPv4:\n\t\tipBytes = remoteAddress.Address.IP().To4()\n\tcase net.AddressFamilyIPv6:\n\t\tipBytes = remoteAddress.Address.IP().To16()\n\tcase net.AddressFamilyDomain:\n\t\t// Do not resolve domain names here. Return explicit error.\n\t\treturn nil, fmt.Errorf(\"domain address not supported for gVisor dial: %s\", remoteAddress.Address.String())\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported address family: %v\", remoteAddress.Address.Family())\n\t}\n\n\tif ipBytes == nil {\n\t\treturn nil, fmt.Errorf(\"failed to obtain IP bytes for %v\", remoteAddress.Address)\n\t}\n\n\t// Choose network protocol number based on IP length.\n\tnetProto := ipv4.ProtocolNumber\n\tif len(ipBytes) == 16 {\n\t\tnetProto = ipv6.ProtocolNumber\n\t}\n\n\tremote := tcpip.FullAddress{\n\t\tAddr: tcpip.AddrFromSlice(ipBytes),\n\t\tPort: uint16(remoteAddress.Port),\n\t}\n\n\t// Use gonet dialer to create a TCP connection on the in-memory stack.\n\tconn, err := gonet.DialContextTCP(ctx, w.stack, remote, netProto)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\n// ListenUDP will create a connection to the given destination, using the stack.\n// Machine Generated\nfunc (w *WrappedStack) ListenUDP(ctx context.Context, localAddress net.Destination) (net.PacketConn, error) {\n\t// allow ctx to be accepted by the function signature\n\t_ = ctx\n\n\tif w == nil || w.stack == nil {\n\t\treturn nil, fmt.Errorf(\"gvisor stack not initialized\")\n\t}\n\n\tif localAddress.Network != net.Network_UDP {\n\t\treturn nil, fmt.Errorf(\"destination is not udp: %v\", localAddress.Network)\n\t}\n\n\t// Determine local address bytes.\n\tvar ipBytes []byte\n\tspecified := false\n\tif localAddress.Address == nil {\n\t\t// If address is nil, treat as unspecified (zero) address.\n\t\tspecified = false\n\t} else {\n\t\tswitch localAddress.Address.Family() {\n\t\tcase net.AddressFamilyIPv4:\n\t\t\tspecified = true\n\t\t\tipBytes = localAddress.Address.IP().To4()\n\t\tcase net.AddressFamilyIPv6:\n\t\t\tspecified = true\n\t\t\tipBytes = localAddress.Address.IP().To16()\n\t\tcase net.AddressFamilyDomain:\n\t\t\t// Listening on a domain name is not supported.\n\t\t\treturn nil, fmt.Errorf(\"listening on domain address not supported: %s\", localAddress.Address.String())\n\t\tdefault:\n\t\t\t// If unspecified (zero) address, allow kernel (stack) to choose.\n\t\t\tspecified = false\n\t\t}\n\t}\n\n\tvar laddr *tcpip.FullAddress\n\tif specified {\n\t\tif ipBytes == nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to obtain IP bytes for %v\", localAddress.Address)\n\t\t}\n\t\tnetProto := ipv4.ProtocolNumber\n\t\tif len(ipBytes) == 16 {\n\t\t\tnetProto = ipv6.ProtocolNumber\n\t\t}\n\t\tl := tcpip.FullAddress{Addr: tcpip.AddrFromSlice(ipBytes), Port: uint16(localAddress.Port)}\n\t\tladdr = &l\n\t\t// Create UDP endpoint bound to local address.\n\t\tudpConn, err := gonet.DialUDP(w.stack, laddr, nil, netProto)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn udpConn, nil\n\t}\n\n\tif w.config.DualStackUdp {\n\t\tudpConn4, err := gonet.DialUDP(w.stack, nil, nil, ipv4.ProtocolNumber)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create IPv4 UDP conn for dual stack: %w\", err)\n\t\t}\n\t\tudpConn6, err := gonet.DialUDP(w.stack, nil, nil, ipv6.ProtocolNumber)\n\t\tif err != nil {\n\t\t\tudpConn4.Close()\n\t\t\treturn nil, fmt.Errorf(\"failed to create IPv6 UDP conn for dual stack: %w\", err)\n\t\t}\n\t\tpreferIPv6 := w.config.GetPreferIpv6ForUdp()\n\t\treturn fusedPacketConn.NewFusedPacketConn(udpConn4, udpConn6, int(w.config.Mtu), preferIPv6), nil\n\t}\n\n\t// If not specified, let the stack choose the local address (pass nil laddr).\n\t// Default network selection honors PreferIpv6ForUdp if configured.\n\tdefaultNet := ipv4.ProtocolNumber\n\tif w.config != nil && w.config.GetPreferIpv6ForUdp() {\n\t\tdefaultNet = ipv6.ProtocolNumber\n\t}\n\tudpConn, err := gonet.DialUDP(w.stack, nil, nil, defaultNet)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn udpConn, nil\n}\n"
  },
  {
    "path": "common/packetswitch/gvisorstack/stack.go",
    "content": "package gvisorstack\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/stack\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/icmp\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/tcp\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/transport/udp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype WrappedStack struct {\n\tconfig *Config\n\tctx    context.Context\n\tstack  *stack.Stack\n\n\tstackTCPListeners []*gonet.TCPListener\n}\n\nfunc NewStack(ctx context.Context, config *Config) (*WrappedStack, error) {\n\treturn &WrappedStack{\n\t\tconfig: config,\n\t\tctx:    ctx,\n\t}, nil\n}\n\nfunc (w *WrappedStack) CreateStackFromNetworkLayerDevice(packetSwitchDevice packetswitch.NetworkLayerDevice) error {\n\t// Validate\n\tif w == nil || w.config == nil {\n\t\treturn fmt.Errorf(\"no config\")\n\t}\n\n\t// Determine MTU from config (0 means unspecified)\n\tmtu := int(w.config.GetMtu())\n\n\t// Create adaptor that implements stack.LinkEndpoint\n\tadaptor := NewNetworkLayerDeviceToGvisorLinkEndpointAdaptor(w.ctx, mtu, packetSwitchDevice)\n\n\t// Create stack using adaptor as link endpoint\n\ts, err := w.createStack(adaptor)\n\tif err != nil {\n\t\t// cleanup adaptor on error\n\t\tadaptor.Close()\n\t\treturn fmt.Errorf(\"failed to create gvisor stack: %v\", err)\n\t}\n\n\t// When the adaptor is closed, close the stack as well.\n\tadaptor.SetOnCloseAction(func() {\n\t\tif s != nil {\n\t\t\ts.Close()\n\t\t}\n\t})\n\n\tw.stack = s\n\n\tif err := w.ApplyListeners(); err != nil {\n\t\treturn fmt.Errorf(\"failed to apply listeners: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc (w *WrappedStack) createStack(linkedEndpoint stack.LinkEndpoint) (*stack.Stack, error) {\n\t// Machine Generated\n\tif w == nil || w.config == nil {\n\t\treturn nil, fmt.Errorf(\"no config\")\n\t}\n\n\ts := stack.New(stack.Options{\n\t\tNetworkProtocols: []stack.NetworkProtocolFactory{\n\t\t\tipv4.NewProtocol,\n\t\t\tipv6.NewProtocol,\n\t\t},\n\t\tTransportProtocols: []stack.TransportProtocolFactory{\n\t\t\ttcp.NewProtocol,\n\t\t\tudp.NewProtocol,\n\t\t\ticmp.NewProtocol4,\n\t\t\ticmp.NewProtocol6,\n\t\t},\n\t})\n\n\tnicID := s.NextNICID()\n\n\t// Create NIC\n\tif err := s.CreateNICWithOptions(nicID, linkedEndpoint, stack.NICOptions{Disabled: false, QDisc: nil}); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create NIC: %v\", err)\n\t}\n\n\t// Add protocol addresses\n\tfor _, ip := range w.config.Ips {\n\t\ttcpIPAddr := tcpip.AddrFromSlice(ip.Ip)\n\t\tprotocolAddress := tcpip.ProtocolAddress{\n\t\t\tAddressWithPrefix: tcpip.AddressWithPrefix{\n\t\t\t\tAddress:   tcpIPAddr,\n\t\t\t\tPrefixLen: int(ip.Prefix),\n\t\t\t},\n\t\t}\n\n\t\tswitch tcpIPAddr.Len() {\n\t\tcase 4:\n\t\t\tprotocolAddress.Protocol = ipv4.ProtocolNumber\n\t\tcase 16:\n\t\t\tprotocolAddress.Protocol = ipv6.ProtocolNumber\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"invalid IP address length: %d\", tcpIPAddr.Len())\n\t\t}\n\n\t\tif err := s.AddProtocolAddress(nicID, protocolAddress, stack.AddressProperties{}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to add protocol address: %v\", err)\n\t\t}\n\t}\n\n\t// Set route table\n\ts.SetRouteTable(func() (table []tcpip.Route) {\n\t\tfor _, cidrs := range w.config.Routes {\n\t\t\tsubnet := tcpip.AddressWithPrefix{\n\t\t\t\tAddress:   tcpip.AddrFromSlice(cidrs.Ip),\n\t\t\t\tPrefixLen: int(cidrs.Prefix),\n\t\t\t}.Subnet()\n\t\t\troute := tcpip.Route{\n\t\t\t\tDestination: subnet,\n\t\t\t\tNIC:         nicID,\n\t\t\t}\n\t\t\ttable = append(table, route)\n\t\t}\n\t\treturn\n\t}())\n\n\t// Promiscuous & spoofing\n\tif err := s.SetPromiscuousMode(nicID, w.config.EnablePromiscuousMode); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to set promiscuous mode: %v\", err)\n\t}\n\tif err := s.SetSpoofing(nicID, w.config.EnableSpoofing); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to set spoofing: %v\", err)\n\t}\n\n\t// Apply socket buffer sizes if provided\n\tif w.config.SocketSettings != nil {\n\t\tif size := w.config.SocketSettings.TxBufSize; size != 0 {\n\t\t\tsendBufferSizeRangeOption := tcpip.TCPSendBufferSizeRangeOption{Min: tcp.MinBufferSize, Default: int(size), Max: tcp.MaxBufferSize}\n\t\t\tif err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &sendBufferSizeRangeOption); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to set tcp send buffer size: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\tif size := w.config.SocketSettings.RxBufSize; size != 0 {\n\t\t\treceiveBufferSizeRangeOption := tcpip.TCPReceiveBufferSizeRangeOption{Min: tcp.MinBufferSize, Default: int(size), Max: tcp.MaxBufferSize}\n\t\t\tif err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &receiveBufferSizeRangeOption); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to set tcp receive buffer size: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn s, nil\n}\n\nfunc (w *WrappedStack) Close() error {\n\tif w == nil || w.stack == nil {\n\t\treturn nil\n\t}\n\tfor _, l := range w.stackTCPListeners {\n\t\tl.Close()\n\t}\n\tw.stackTCPListeners = nil\n\tw.stack.Close()\n\tw.stack = nil\n\treturn nil\n}\n"
  },
  {
    "path": "common/packetswitch/gvisorstack/tcp_listener.go",
    "content": "package gvisorstack\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"gvisor.dev/gvisor/pkg/tcpip\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv4\"\n\t\"gvisor.dev/gvisor/pkg/tcpip/network/ipv6\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\nfunc (w *WrappedStack) ApplyListeners() error {\n\tfor _, listener := range w.config.TcpListener {\n\t\tlistenerIP := listener.Address.Ip\n\t\tlistenerPort := listener.GetPort()\n\t\tlistenerTag := listener.Tag\n\n\t\taddr := tcpip.FullAddress{\n\t\t\tAddr: tcpip.AddrFromSlice(listenerIP),\n\t\t\tPort: uint16(listenerPort),\n\t\t}\n\n\t\tnetProto := ipv4.ProtocolNumber\n\t\tif len(listenerIP) == net.IPv6len {\n\t\t\tnetProto = ipv6.ProtocolNumber\n\t\t}\n\n\t\ttcpListener, err := w.CreateStackListener(addr, netProto)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create TCP listener on %v:%d: %w\", listenerIP, listenerPort, err)\n\t\t}\n\n\t\tw.stackTCPListeners = append(w.stackTCPListeners, tcpListener)\n\n\t\tgo w.acceptLoop(tcpListener, listenerTag)\n\t}\n\treturn nil\n}\n\nfunc (w *WrappedStack) acceptLoop(listener *gonet.TCPListener, outboundTag string) {\n\tfor {\n\t\tconn, err := listener.Accept()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tgo w.handleTCPConn(conn, outboundTag)\n\t}\n}\n\nfunc (w *WrappedStack) handleTCPConn(conn net.Conn, outboundTag string) {\n\tdefer conn.Close()\n\n\t// Use the connection's local address as the destination,\n\t// representing the address the client was connecting to on the stack.\n\ttcpAddr, ok := conn.LocalAddr().(*net.TCPAddr)\n\tif !ok {\n\t\treturn\n\t}\n\n\tdest := net.TCPDestination(net.IPAddress(tcpAddr.IP), net.Port(tcpAddr.Port))\n\n\toutboundConn, err := tagged.Dialer(w.ctx, dest, outboundTag)\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer outboundConn.Close()\n\n\t// Bidirectional relay\n\tdone := make(chan struct{})\n\tgo func() {\n\t\tio.Copy(outboundConn, conn)\n\t\tclose(done)\n\t}()\n\tio.Copy(conn, outboundConn)\n\t<-done\n}\n\nfunc (w *WrappedStack) CreateStackListener(addr tcpip.FullAddress, netProto tcpip.NetworkProtocolNumber) (*gonet.TCPListener, error) {\n\treturn gonet.ListenTCP(w.stack, addr, netProto)\n}\n"
  },
  {
    "path": "common/packetswitch/interconnect/interconnect.go",
    "content": "package interconnect\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/packetswitch/interconnect/networkLayer_cable.go",
    "content": "package interconnect\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\nfunc NewNetworkLayerCable(ctx context.Context) (*NetworkLayerCable, error) {\n\treturn &NetworkLayerCable{\n\t\tctx: ctx,\n\t}, nil\n}\n\n// NetworkLayerCable is primarily Machine Generated\ntype NetworkLayerCable struct {\n\tlSideWriter packetswitch.NetworkLayerPacketWriter\n\trSideWriter packetswitch.NetworkLayerPacketWriter\n\tctx         context.Context\n\tlock        sync.RWMutex\n}\n\n// NetworkLayerCableDevice is Machine Generated\ntype NetworkLayerCableDevice struct {\n\tcable  *NetworkLayerCable\n\tisLeft bool\n}\n\nfunc (c *NetworkLayerCable) GetLSideDevice() *NetworkLayerCableDevice {\n\treturn &NetworkLayerCableDevice{\n\t\tcable:  c,\n\t\tisLeft: true,\n\t}\n}\n\nfunc (c *NetworkLayerCable) GetRSideDevice() *NetworkLayerCableDevice {\n\treturn &NetworkLayerCableDevice{\n\t\tcable:  c,\n\t\tisLeft: false,\n\t}\n}\n\n// OnAttach implements NetworkLayerPacketReader.OnAttach\nfunc (d *NetworkLayerCableDevice) OnAttach(writer packetswitch.NetworkLayerPacketWriter) error {\n\tif writer == nil {\n\t\treturn errors.New(\"nil writer\")\n\t}\n\td.cable.lock.Lock()\n\tdefer d.cable.lock.Unlock()\n\tif d.isLeft {\n\t\tif d.cable.lSideWriter != nil {\n\t\t\treturn errors.New(\"left writer already attached\")\n\t\t}\n\t\td.cable.lSideWriter = writer\n\t} else {\n\t\tif d.cable.rSideWriter != nil {\n\t\t\treturn errors.New(\"right writer already attached\")\n\t\t}\n\t\td.cable.rSideWriter = writer\n\t}\n\treturn nil\n}\n\n// Write implements NetworkLayerPacketWriter.Write\nfunc (d *NetworkLayerCableDevice) Write(packet []byte) (int, error) {\n\td.cable.lock.RLock()\n\tvar peer packetswitch.NetworkLayerPacketWriter\n\tif d.isLeft {\n\t\tpeer = d.cable.rSideWriter\n\t} else {\n\t\tpeer = d.cable.lSideWriter\n\t}\n\td.cable.lock.RUnlock()\n\tif peer == nil {\n\t\treturn 0, errors.New(\"no peer attached\")\n\t}\n\treturn peer.Write(packet)\n}\n\n// Close implements common.Closable.Close\nfunc (d *NetworkLayerCableDevice) Close() error {\n\td.cable.lock.Lock()\n\tdefer d.cable.lock.Unlock()\n\tif d.isLeft {\n\t\td.cable.lSideWriter = nil\n\t} else {\n\t\td.cable.rSideWriter = nil\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "common/packetswitch/interconnect/networkLayer_cable_test.go",
    "content": "package interconnect\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\ntype testWriter struct {\n\tmu       sync.Mutex\n\treceived [][]byte\n\tch       chan []byte\n}\n\nfunc newTestWriter(bufSize int) *testWriter {\n\tw := &testWriter{ch: make(chan []byte, bufSize)}\n\treturn w\n}\n\nfunc (w *testWriter) Write(p []byte) (int, error) {\n\t// copy payload\n\tcp := make([]byte, len(p))\n\tcopy(cp, p)\n\tw.mu.Lock()\n\tw.received = append(w.received, cp)\n\tw.mu.Unlock()\n\tselect {\n\tcase w.ch <- cp:\n\tdefault:\n\t}\n\treturn len(p), nil\n}\n\nfunc (w *testWriter) ReceivedAll() [][]byte {\n\tw.mu.Lock()\n\tdefer w.mu.Unlock()\n\tout := make([][]byte, len(w.received))\n\tcopy(out, w.received)\n\treturn out\n}\n\nfunc TestCable_HappyPath(t *testing.T) {\n\tc, err := NewNetworkLayerCable(context.Background())\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create cable: %v\", err)\n\t}\n\tl := c.GetLSideDevice()\n\tr := c.GetRSideDevice()\n\n\twL := newTestWriter(4)\n\twR := newTestWriter(4)\n\n\tif err := l.OnAttach(wL); err != nil {\n\t\tt.Fatalf(\"attach left failed: %v\", err)\n\t}\n\tif err := r.OnAttach(wR); err != nil {\n\t\tt.Fatalf(\"attach right failed: %v\", err)\n\t}\n\n\tpayloadL := []byte(\"from-left\")\n\tn, err := l.Write(payloadL)\n\tif err != nil {\n\t\tt.Fatalf(\"write left failed: %v\", err)\n\t}\n\tif n != len(payloadL) {\n\t\tt.Fatalf(\"write returned wrong length: %d\", n)\n\t}\n\n\tselect {\n\tcase got := <-wR.ch:\n\t\tif string(got) != string(payloadL) {\n\t\t\tt.Fatalf(\"unexpected payload at right: %s\", string(got))\n\t\t}\n\tcase <-time.After(500 * time.Millisecond):\n\t\tt.Fatalf(\"timeout waiting for payload on right\")\n\t}\n\n\tpayloadR := []byte(\"from-right\")\n\tn, err = r.Write(payloadR)\n\tif err != nil {\n\t\tt.Fatalf(\"write right failed: %v\", err)\n\t}\n\tif n != len(payloadR) {\n\t\tt.Fatalf(\"write returned wrong length: %d\", n)\n\t}\n\tselect {\n\tcase got := <-wL.ch:\n\t\tif string(got) != string(payloadR) {\n\t\t\tt.Fatalf(\"unexpected payload at left: %s\", string(got))\n\t\t}\n\tcase <-time.After(500 * time.Millisecond):\n\t\tt.Fatalf(\"timeout waiting for payload on left\")\n\t}\n}\n\nfunc TestCable_NoPeer(t *testing.T) {\n\tc, _ := NewNetworkLayerCable(context.Background())\n\tl := c.GetLSideDevice()\n\twL := newTestWriter(1)\n\tif err := l.OnAttach(wL); err != nil {\n\t\tt.Fatalf(\"attach left failed: %v\", err)\n\t}\n\tif n, err := l.Write([]byte(\"x\")); err == nil || n != 0 {\n\t\tt.Fatalf(\"expected write to fail when no peer attached got n=%d err=%v\", n, err)\n\t}\n}\n\nfunc TestCable_DoubleAttachAndClose(t *testing.T) {\n\tc, _ := NewNetworkLayerCable(context.Background())\n\tl := c.GetLSideDevice()\n\tw1 := newTestWriter(1)\n\tw2 := newTestWriter(1)\n\tif err := l.OnAttach(w1); err != nil {\n\t\tt.Fatalf(\"attach left failed: %v\", err)\n\t}\n\tif err := l.OnAttach(w2); err == nil {\n\t\tt.Fatalf(\"expected second attach to fail\")\n\t}\n\n\tr := c.GetRSideDevice()\n\twr := newTestWriter(2)\n\tif err := r.OnAttach(wr); err != nil {\n\t\tt.Fatalf(\"attach right failed: %v\", err)\n\t}\n\n\t// close left and ensure right cannot write\n\tif err := l.Close(); err != nil {\n\t\tt.Fatalf(\"close left failed: %v\", err)\n\t}\n\tif n, err := r.Write([]byte(\"hello\")); err == nil || n != 0 {\n\t\tt.Fatalf(\"expected write from right to fail after left closed got n=%d err=%v\", n, err)\n\t}\n}\n\nfunc TestCable_ConcurrentWrites(t *testing.T) {\n\tc, _ := NewNetworkLayerCable(context.Background())\n\tl := c.GetLSideDevice()\n\tr := c.GetRSideDevice()\n\twL := newTestWriter(100)\n\twR := newTestWriter(100)\n\tif err := l.OnAttach(wL); err != nil {\n\t\tt.Fatalf(\"attach left failed: %v\", err)\n\t}\n\tif err := r.OnAttach(wR); err != nil {\n\t\tt.Fatalf(\"attach right failed: %v\", err)\n\t}\n\n\tvar wg sync.WaitGroup\n\tcount := 200\n\twg.Add(count * 2)\n\tfor i := 0; i < count; i++ {\n\t\tpayloadL := []byte(fmt.Sprintf(\"L-%d\", i%10))\n\t\tpayloadR := []byte(fmt.Sprintf(\"R-%d\", i%10))\n\t\tgo func(p []byte) {\n\t\t\tdefer wg.Done()\n\t\t\t_, _ = l.Write(p)\n\t\t}(payloadL)\n\t\tgo func(p []byte) {\n\t\t\tdefer wg.Done()\n\t\t\t_, _ = r.Write(p)\n\t\t}(payloadR)\n\t}\n\twg.Wait()\n\n\t// drain channels (best-effort)\n\ttimed := time.After(500 * time.Millisecond)\n\tfor {\n\t\tselect {\n\t\tcase <-wL.ch:\n\t\tcase <-wR.ch:\n\t\tcase <-timed:\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// ensure testWriter implements the interface\nvar _ packetswitch.NetworkLayerPacketWriter = (*testWriter)(nil)\n"
  },
  {
    "path": "common/packetswitch/packetswitch.go",
    "content": "package packetswitch\n\nimport \"github.com/v2fly/v2ray-core/v5/common\"\n\ntype NetworkLayerDevice interface {\n\tcommon.Closable\n\tNetworkLayerPacketWriter\n\tNetworkLayerPacketReader\n}\n\ntype NetworkLayerPacketWriter interface {\n\tWrite(packet []byte) (n int, err error)\n}\n\ntype NetworkLayerPacketReader interface {\n\tOnAttach(writer NetworkLayerPacketWriter) error\n}\n"
  },
  {
    "path": "common/peer/latency.go",
    "content": "package peer\n\nimport (\n\t\"sync\"\n)\n\ntype Latency interface {\n\tValue() uint64\n}\n\ntype HasLatency interface {\n\tConnectionLatency() Latency\n\tHandshakeLatency() Latency\n}\n\ntype AverageLatency struct {\n\taccess sync.Mutex\n\tvalue  uint64\n}\n\nfunc (al *AverageLatency) Update(newValue uint64) {\n\tal.access.Lock()\n\tdefer al.access.Unlock()\n\n\tal.value = (al.value + newValue*2) / 3\n}\n\nfunc (al *AverageLatency) Value() uint64 {\n\treturn al.value\n}\n"
  },
  {
    "path": "common/peer/peer.go",
    "content": "package peer\n"
  },
  {
    "path": "common/platform/ctlcmd/attr_other.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage ctlcmd\n\nimport \"syscall\"\n\nfunc getSysProcAttr() *syscall.SysProcAttr {\n\treturn nil\n}\n"
  },
  {
    "path": "common/platform/filesystem/file.go",
    "content": "package filesystem\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem/fsifce\"\n)\n\nvar NewFileSeeker fsifce.FileSeekerFunc = func(path string) (io.ReadSeekCloser, error) {\n\treturn os.Open(path)\n}\n\nvar NewFileReader fsifce.FileReaderFunc = func(path string) (io.ReadCloser, error) {\n\treturn os.Open(path)\n}\n\nvar NewFileWriter fsifce.FileWriterFunc = func(path string) (io.WriteCloser, error) {\n\tbasePath := filepath.Dir(path)\n\tif err := os.MkdirAll(basePath, 0o700); err != nil {\n\t\treturn nil, err\n\t}\n\treturn os.Create(path)\n}\n\nvar NewFileRemover fsifce.FileRemoveFunc = os.Remove\n\nvar NewFileReadDir fsifce.FileReadDirFunc = os.ReadDir\n\nfunc ReadFile(path string) ([]byte, error) {\n\treader, err := NewFileReader(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer reader.Close()\n\n\treturn buf.ReadAllToBytes(reader)\n}\n\nfunc WriteFile(path string, payload []byte) error {\n\twriter, err := NewFileWriter(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer writer.Close()\n\n\treturn buf.WriteAllBytes(writer, payload)\n}\n\nfunc ReadAsset(file string) ([]byte, error) {\n\treturn ReadFile(platform.GetAssetLocation(file))\n}\n\nfunc CopyFile(dst string, src string, perm os.FileMode) error {\n\tbytes, err := ReadFile(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tf, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, perm)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\t_, err = f.Write(bytes)\n\treturn err\n}\n"
  },
  {
    "path": "common/platform/filesystem/fsifce/ifce.go",
    "content": "package fsifce\n\nimport (\n\t\"io\"\n\t\"io/fs\"\n)\n\ntype FileSeekerFunc func(path string) (io.ReadSeekCloser, error)\n\ntype FileReaderFunc func(path string) (io.ReadCloser, error)\n\ntype FileWriterFunc func(path string) (io.WriteCloser, error)\n\ntype FileReadDirFunc func(path string) ([]fs.DirEntry, error)\n\ntype FileRemoveFunc func(path string) error\n"
  },
  {
    "path": "common/platform/others.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage platform\n\nimport (\n\t\"path/filepath\"\n\n\t\"github.com/adrg/xdg\"\n)\n\nfunc LineSeparator() string {\n\treturn \"\\n\"\n}\n\n// GetAssetLocation search for `file` in certain locations\nfunc GetAssetLocation(file string) string {\n\tconst name = \"v2ray.location.asset\"\n\tassetPath := NewEnvFlag(name).GetValue(getExecutableDir)\n\tdefPath := filepath.Join(assetPath, file)\n\trelPath := filepath.Join(\"v2ray\", file)\n\tfullPath, err := xdg.SearchDataFile(relPath)\n\tif err != nil {\n\t\treturn defPath\n\t}\n\treturn fullPath\n}\n"
  },
  {
    "path": "common/platform/platform.go",
    "content": "package platform\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype EnvFlag struct {\n\tName    string\n\tAltName string\n}\n\nfunc NewEnvFlag(name string) EnvFlag {\n\treturn EnvFlag{\n\t\tName:    name,\n\t\tAltName: NormalizeEnvName(name),\n\t}\n}\n\nfunc (f EnvFlag) GetValue(defaultValue func() string) string {\n\tif v, found := os.LookupEnv(f.Name); found {\n\t\treturn v\n\t}\n\tif len(f.AltName) > 0 {\n\t\tif v, found := os.LookupEnv(f.AltName); found {\n\t\t\treturn v\n\t\t}\n\t}\n\n\treturn defaultValue()\n}\n\nfunc (f EnvFlag) GetValueAsInt(defaultValue int) int {\n\tuseDefaultValue := false\n\ts := f.GetValue(func() string {\n\t\tuseDefaultValue = true\n\t\treturn \"\"\n\t})\n\tif useDefaultValue {\n\t\treturn defaultValue\n\t}\n\tv, err := strconv.ParseInt(s, 10, 32)\n\tif err != nil {\n\t\treturn defaultValue\n\t}\n\treturn int(v)\n}\n\nfunc NormalizeEnvName(name string) string {\n\treturn strings.ReplaceAll(strings.ToUpper(strings.TrimSpace(name)), \".\", \"_\")\n}\n\nfunc getExecutableDir() string {\n\texec, err := os.Executable()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\treturn filepath.Dir(exec)\n}\n\nfunc getExecutableSubDir(dir string) func() string {\n\treturn func() string {\n\t\treturn filepath.Join(getExecutableDir(), dir)\n\t}\n}\n\nfunc GetPluginDirectory() string {\n\tconst name = \"v2ray.location.plugin\"\n\tpluginDir := NewEnvFlag(name).GetValue(getExecutableSubDir(\"plugins\"))\n\treturn pluginDir\n}\n\nfunc GetConfigurationPath() string {\n\tconst name = \"v2ray.location.config\"\n\tconfigPath := NewEnvFlag(name).GetValue(getExecutableDir)\n\treturn filepath.Join(configPath, \"config.json\")\n}\n\n// GetConfDirPath reads \"v2ray.location.confdir\"\nfunc GetConfDirPath() string {\n\tconst name = \"v2ray.location.confdir\"\n\tconfigPath := NewEnvFlag(name).GetValue(func() string { return \"\" })\n\treturn configPath\n}\n"
  },
  {
    "path": "common/platform/platform_test.go",
    "content": "package platform_test\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n)\n\nfunc TestNormalizeEnvName(t *testing.T) {\n\tcases := []struct {\n\t\tinput  string\n\t\toutput string\n\t}{\n\t\t{\n\t\t\tinput:  \"a\",\n\t\t\toutput: \"A\",\n\t\t},\n\t\t{\n\t\t\tinput:  \"a.a\",\n\t\t\toutput: \"A_A\",\n\t\t},\n\t\t{\n\t\t\tinput:  \"A.A.B\",\n\t\t\toutput: \"A_A_B\",\n\t\t},\n\t}\n\tfor _, test := range cases {\n\t\tif v := platform.NormalizeEnvName(test.input); v != test.output {\n\t\t\tt.Error(\"unexpected output: \", v, \" want \", test.output)\n\t\t}\n\t}\n}\n\nfunc TestEnvFlag(t *testing.T) {\n\tif v := (platform.EnvFlag{\n\t\tName: \"xxxxx.y\",\n\t}.GetValueAsInt(10)); v != 10 {\n\t\tt.Error(\"env value: \", v)\n\t}\n}\n\n// TestWrongErrorCheckOnOSStat is a test to detect the misuse of error handling\n// in os.Stat, which will lead to failure to find & read geoip & geosite files.\nfunc TestWrongErrorCheckOnOSStat(t *testing.T) {\n\ttheExpectedDir := filepath.Join(\"usr\", \"local\", \"share\", \"v2ray\")\n\tgetAssetLocation := func(file string) string {\n\t\tfor _, p := range []string{\n\t\t\tfilepath.Join(theExpectedDir, file),\n\t\t} {\n\t\t\t// errors.Is(fs.ErrNotExist, err) is a mistake supposed Not to\n\t\t\t// be discovered by the Go runtime, which will lead to failure to\n\t\t\t// find & read geoip & geosite files.\n\t\t\t// The correct code is `errors.Is(err, fs.ErrNotExist)`\n\t\t\tif _, err := os.Stat(p); err != nil && errors.Is(fs.ErrNotExist, err) { //nolint: staticcheck\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// asset found\n\t\t\treturn p\n\t\t}\n\t\treturn filepath.Join(\"the\", \"wrong\", \"path\", \"not-exist.txt\")\n\t}\n\n\tnotExist := getAssetLocation(\"not-exist.txt\")\n\tif filepath.Dir(notExist) != theExpectedDir {\n\t\tt.Error(\"asset dir:\", notExist, \"not in\", theExpectedDir)\n\t}\n}\n\nfunc TestGetAssetLocation(t *testing.T) {\n\texec, err := os.Executable()\n\tcommon.Must(err)\n\tloc := platform.GetAssetLocation(\"t\")\n\tif filepath.Dir(loc) != filepath.Dir(exec) {\n\t\tt.Error(\"asset dir: \", loc, \" not in \", exec)\n\t}\n\n\tos.Setenv(\"v2ray.location.asset\", \"/v2ray\")\n\tif runtime.GOOS == \"windows\" {\n\t\tif v := platform.GetAssetLocation(\"t\"); v != \"\\\\v2ray\\\\t\" {\n\t\t\tt.Error(\"asset loc: \", v)\n\t\t}\n\t} else {\n\t\tif v := platform.GetAssetLocation(\"t\"); v != \"/v2ray/t\" {\n\t\t\tt.Error(\"asset loc: \", v)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/platform/securedload/embedded.go",
    "content": "package securedload\n\nconst allowedHashes = `SHA256 (!#project==v2fly) = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nSHA256 (!#version==embedded) = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nSHA256 (subscriptions/subscriptionsDefinition.v2flyTemplate) = 3f165dba7de0d7c506fbdff3275ea64b76f307df435316a3ea0914ee957793ab\nSHA256 (browserforwarder/index.html) = 34f2c573724256421ade769bda18eeac85172bf0aaed00d7b90e41e843a2caef\nSHA256 (browserforwarder/index.js) = cb587a075bb0addcdc0d22c9222a48d2c7004b54935b5021379d3d35dc1f2927\n\n`\n"
  },
  {
    "path": "common/platform/securedload/embeddedhash.go",
    "content": "package securedload\n\nimport (\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/v2fly/VSign/insmgr\"\n\t\"github.com/v2fly/VSign/signerVerify\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n)\n\ntype EmbeddedHashProtectedLoader struct {\n\tcheckedFile map[string]string\n}\n\nfunc (e EmbeddedHashProtectedLoader) VerifyAndLoad(filename string) ([]byte, error) {\n\tplatformFileName := filepath.FromSlash(filename)\n\tfileContent, err := filesystem.ReadFile(platform.GetAssetLocation(platformFileName))\n\tif err != nil {\n\t\treturn nil, newError(\"Cannot find file\", filename).Base(err)\n\t}\n\tfileHash := sha256.Sum256(fileContent)\n\tfileHashAsString := hex.EncodeToString(fileHash[:])\n\tif fileNameVerified, ok := e.checkedFile[fileHashAsString]; ok {\n\t\tfor _, filenameVerifiedIndividual := range strings.Split(fileNameVerified, \";\") {\n\t\t\tif strings.HasSuffix(filenameVerifiedIndividual, filename) {\n\t\t\t\treturn fileContent, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, newError(\"Unrecognized file at \", filename, \" can not be loaded for execution\")\n}\n\nfunc NewEmbeddedHashProtectedLoader() *EmbeddedHashProtectedLoader {\n\tinstructions := insmgr.ReadAllIns(bytes.NewReader([]byte(allowedHashes)))\n\tcheckedFile, _, ok := signerVerify.CheckAsClient(instructions, \"v2fly\", true)\n\tif !ok {\n\t\tpanic(\"Embedded Hash data is invalid\")\n\t}\n\treturn &EmbeddedHashProtectedLoader{checkedFile: checkedFile}\n}\n\nfunc init() {\n\tRegisterProtectedLoader(\"embedded\", NewEmbeddedHashProtectedLoader())\n}\n"
  },
  {
    "path": "common/platform/securedload/errors.generated.go",
    "content": "package securedload\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/platform/securedload/file.go",
    "content": "package securedload\n\nfunc GetAssetSecured(name string) ([]byte, error) {\n\tvar err error\n\tfor k, v := range knownProtectedLoader {\n\t\tloadedData, errLoad := v.VerifyAndLoad(name)\n\t\tif errLoad == nil {\n\t\t\treturn loadedData, nil\n\t\t}\n\t\terr = newError(k, \" is not loading executable file\").Base(errLoad)\n\t}\n\treturn nil, err\n}\n"
  },
  {
    "path": "common/platform/securedload/securedload.go",
    "content": "package securedload\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/platform/securedload/verify.go",
    "content": "package securedload\n\ntype ProtectedLoader interface {\n\tVerifyAndLoad(filename string) ([]byte, error)\n}\n\nvar knownProtectedLoader map[string]ProtectedLoader\n\nfunc RegisterProtectedLoader(name string, sv ProtectedLoader) {\n\tif knownProtectedLoader == nil {\n\t\tknownProtectedLoader = map[string]ProtectedLoader{}\n\t}\n\tknownProtectedLoader[name] = sv\n}\n"
  },
  {
    "path": "common/platform/windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage platform\n\nimport \"path/filepath\"\n\nfunc LineSeparator() string {\n\treturn \"\\r\\n\"\n}\n\n// GetAssetLocation search for `file` in the excutable dir\nfunc GetAssetLocation(file string) string {\n\tconst name = \"v2ray.location.asset\"\n\tassetPath := NewEnvFlag(name).GetValue(getExecutableDir)\n\treturn filepath.Join(assetPath, file)\n}\n"
  },
  {
    "path": "common/protocol/account.go",
    "content": "package protocol\n\n// Account is a user identity used for authentication.\ntype Account interface {\n\tEquals(Account) bool\n}\n\n// AsAccount is an object can be converted into account.\ntype AsAccount interface {\n\tAsAccount() (Account, error)\n}\n"
  },
  {
    "path": "common/protocol/address.go",
    "content": "package protocol\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype AddressOption func(*option)\n\nfunc PortThenAddress() AddressOption {\n\treturn func(p *option) {\n\t\tp.portFirst = true\n\t}\n}\n\nfunc AddressFamilyByte(b byte, f net.AddressFamily) AddressOption {\n\tif b >= 16 {\n\t\tpanic(\"address family byte too big\")\n\t}\n\treturn func(p *option) {\n\t\tp.addrTypeMap[b] = f\n\t\tp.addrByteMap[f] = b\n\t}\n}\n\ntype AddressTypeParser func(byte) byte\n\nfunc WithAddressTypeParser(atp AddressTypeParser) AddressOption {\n\treturn func(p *option) {\n\t\tp.typeParser = atp\n\t}\n}\n\ntype AddressSerializer interface {\n\tReadAddressPort(buffer *buf.Buffer, input io.Reader) (net.Address, net.Port, error)\n\tWriteAddressPort(writer io.Writer, addr net.Address, port net.Port) error\n}\n\nconst afInvalid = 255\n\ntype option struct {\n\taddrTypeMap [16]net.AddressFamily\n\taddrByteMap [16]byte\n\tportFirst   bool\n\ttypeParser  AddressTypeParser\n}\n\n// NewAddressParser creates a new AddressParser\nfunc NewAddressParser(options ...AddressOption) AddressSerializer {\n\tvar o option\n\tfor i := range o.addrByteMap {\n\t\to.addrByteMap[i] = afInvalid\n\t}\n\tfor i := range o.addrTypeMap {\n\t\to.addrTypeMap[i] = net.AddressFamily(afInvalid)\n\t}\n\tfor _, opt := range options {\n\t\topt(&o)\n\t}\n\n\tap := &addressParser{\n\t\taddrByteMap: o.addrByteMap,\n\t\taddrTypeMap: o.addrTypeMap,\n\t}\n\n\tif o.typeParser != nil {\n\t\tap.typeParser = o.typeParser\n\t}\n\n\tif o.portFirst {\n\t\treturn portFirstAddressParser{ap: ap}\n\t}\n\n\treturn portLastAddressParser{ap: ap}\n}\n\ntype portFirstAddressParser struct {\n\tap *addressParser\n}\n\nfunc (p portFirstAddressParser) ReadAddressPort(buffer *buf.Buffer, input io.Reader) (net.Address, net.Port, error) {\n\tif buffer == nil {\n\t\tbuffer = buf.New()\n\t\tdefer buffer.Release()\n\t}\n\n\tport, err := readPort(buffer, input)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\taddr, err := p.ap.readAddress(buffer, input)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\treturn addr, port, nil\n}\n\nfunc (p portFirstAddressParser) WriteAddressPort(writer io.Writer, addr net.Address, port net.Port) error {\n\tif err := writePort(writer, port); err != nil {\n\t\treturn err\n\t}\n\n\treturn p.ap.writeAddress(writer, addr)\n}\n\ntype portLastAddressParser struct {\n\tap *addressParser\n}\n\nfunc (p portLastAddressParser) ReadAddressPort(buffer *buf.Buffer, input io.Reader) (net.Address, net.Port, error) {\n\tif buffer == nil {\n\t\tbuffer = buf.New()\n\t\tdefer buffer.Release()\n\t}\n\n\taddr, err := p.ap.readAddress(buffer, input)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\tport, err := readPort(buffer, input)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\treturn addr, port, nil\n}\n\nfunc (p portLastAddressParser) WriteAddressPort(writer io.Writer, addr net.Address, port net.Port) error {\n\tif err := p.ap.writeAddress(writer, addr); err != nil {\n\t\treturn err\n\t}\n\n\treturn writePort(writer, port)\n}\n\nfunc readPort(b *buf.Buffer, reader io.Reader) (net.Port, error) {\n\tif _, err := b.ReadFullFrom(reader, 2); err != nil {\n\t\treturn 0, err\n\t}\n\treturn net.PortFromBytes(b.BytesFrom(-2)), nil\n}\n\nfunc writePort(writer io.Writer, port net.Port) error {\n\treturn common.Error2(serial.WriteUint16(writer, port.Value()))\n}\n\nfunc maybeIPPrefix(b byte) bool {\n\treturn b == '[' || (b >= '0' && b <= '9')\n}\n\nfunc isValidDomain(d string) bool {\n\tfor _, c := range d {\n\t\tif !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '-' || c == '.' || c == '_') {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\ntype addressParser struct {\n\taddrTypeMap [16]net.AddressFamily\n\taddrByteMap [16]byte\n\ttypeParser  AddressTypeParser\n}\n\nfunc (p *addressParser) readAddress(b *buf.Buffer, reader io.Reader) (net.Address, error) {\n\tif _, err := b.ReadFullFrom(reader, 1); err != nil {\n\t\treturn nil, err\n\t}\n\n\taddrType := b.Byte(b.Len() - 1)\n\tif p.typeParser != nil {\n\t\taddrType = p.typeParser(addrType)\n\t}\n\n\tif addrType >= 16 {\n\t\treturn nil, newError(\"unknown address type: \", addrType)\n\t}\n\n\taddrFamily := p.addrTypeMap[addrType]\n\tif addrFamily == net.AddressFamily(afInvalid) {\n\t\treturn nil, newError(\"unknown address type: \", addrType)\n\t}\n\n\tswitch addrFamily {\n\tcase net.AddressFamilyIPv4:\n\t\tif _, err := b.ReadFullFrom(reader, 4); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn net.IPAddress(b.BytesFrom(-4)), nil\n\tcase net.AddressFamilyIPv6:\n\t\tif _, err := b.ReadFullFrom(reader, 16); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn net.IPAddress(b.BytesFrom(-16)), nil\n\tcase net.AddressFamilyDomain:\n\t\tif _, err := b.ReadFullFrom(reader, 1); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdomainLength := int32(b.Byte(b.Len() - 1))\n\t\tif _, err := b.ReadFullFrom(reader, domainLength); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdomain := string(b.BytesFrom(-domainLength))\n\t\tif maybeIPPrefix(domain[0]) {\n\t\t\taddr := net.ParseAddress(domain)\n\t\t\tif addr.Family().IsIP() {\n\t\t\t\treturn addr, nil\n\t\t\t}\n\t\t}\n\t\tif !isValidDomain(domain) {\n\t\t\treturn nil, newError(\"invalid domain name: \", domain)\n\t\t}\n\t\treturn net.DomainAddress(domain), nil\n\tdefault:\n\t\tpanic(\"impossible case\")\n\t}\n}\n\nfunc (p *addressParser) writeAddress(writer io.Writer, address net.Address) error {\n\ttb := p.addrByteMap[address.Family()]\n\tif tb == afInvalid {\n\t\treturn newError(\"unknown address family\", address.Family())\n\t}\n\n\tswitch address.Family() {\n\tcase net.AddressFamilyIPv4, net.AddressFamilyIPv6:\n\t\tif _, err := writer.Write([]byte{tb}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := writer.Write(address.IP()); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase net.AddressFamilyDomain:\n\t\tdomain := address.Domain()\n\t\tif IsDomainTooLong(domain) {\n\t\t\treturn newError(\"Super long domain is not supported: \", domain)\n\t\t}\n\n\t\tif _, err := writer.Write([]byte{tb, byte(len(domain))}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := writer.Write([]byte(domain)); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\tpanic(\"Unknown family type.\")\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "common/protocol/address_test.go",
    "content": "package protocol_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nfunc TestAddressReading(t *testing.T) {\n\tdata := []struct {\n\t\tOptions []AddressOption\n\t\tInput   []byte\n\t\tAddress net.Address\n\t\tPort    net.Port\n\t\tError   bool\n\t}{\n\t\t{\n\t\t\tOptions: []AddressOption{},\n\t\t\tInput:   []byte{},\n\t\t\tError:   true,\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{},\n\t\t\tInput:   []byte{0, 0, 0, 0, 0},\n\t\t\tError:   true,\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4)},\n\t\t\tInput:   []byte{1, 0, 0, 0, 0, 0, 53},\n\t\t\tAddress: net.IPAddress([]byte{0, 0, 0, 0}),\n\t\t\tPort:    net.Port(53),\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4), PortThenAddress()},\n\t\t\tInput:   []byte{0, 53, 1, 0, 0, 0, 0},\n\t\t\tAddress: net.IPAddress([]byte{0, 0, 0, 0}),\n\t\t\tPort:    net.Port(53),\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4)},\n\t\t\tInput:   []byte{1, 0, 0, 0, 0},\n\t\t\tError:   true,\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x04, net.AddressFamilyIPv6)},\n\t\t\tInput:   []byte{4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 0, 80},\n\t\t\tAddress: net.IPAddress([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),\n\t\t\tPort:    net.Port(80),\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},\n\t\t\tInput:   []byte{3, 9, 118, 50, 102, 108, 121, 46, 111, 114, 103, 0, 80},\n\t\t\tAddress: net.DomainAddress(\"v2fly.org\"),\n\t\t\tPort:    net.Port(80),\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},\n\t\t\tInput:   []byte{3, 9, 118, 50, 102, 108, 121, 46, 111, 114, 103, 0},\n\t\t\tError:   true,\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},\n\t\t\tInput:   []byte{3, 7, 56, 46, 56, 46, 56, 46, 56, 0, 80},\n\t\t\tAddress: net.ParseAddress(\"8.8.8.8\"),\n\t\t\tPort:    net.Port(80),\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},\n\t\t\tInput:   []byte{3, 7, 10, 46, 56, 46, 56, 46, 56, 0, 80},\n\t\t\tError:   true,\n\t\t},\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x03, net.AddressFamilyDomain)},\n\t\t\tInput:   append(append([]byte{3, 24}, []byte(\"2a00:1450:4007:816::200e\")...), 0, 80),\n\t\t\tAddress: net.ParseAddress(\"2a00:1450:4007:816::200e\"),\n\t\t\tPort:    net.Port(80),\n\t\t},\n\t}\n\n\tfor _, tc := range data {\n\t\tb := buf.New()\n\t\tparser := NewAddressParser(tc.Options...)\n\t\taddr, port, err := parser.ReadAddressPort(b, bytes.NewReader(tc.Input))\n\t\tb.Release()\n\t\tif tc.Error {\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"Expect error but not: %v\", tc)\n\t\t\t}\n\t\t} else {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"Expect no error but: %s %v\", err.Error(), tc)\n\t\t\t}\n\n\t\t\tif addr != tc.Address {\n\t\t\t\tt.Error(\"Got address \", addr.String(), \" want \", tc.Address.String())\n\t\t\t}\n\n\t\t\tif tc.Port != port {\n\t\t\t\tt.Error(\"Got port \", port, \" want \", tc.Port)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestAddressWriting(t *testing.T) {\n\tdata := []struct {\n\t\tOptions []AddressOption\n\t\tAddress net.Address\n\t\tPort    net.Port\n\t\tBytes   []byte\n\t\tError   bool\n\t}{\n\t\t{\n\t\t\tOptions: []AddressOption{AddressFamilyByte(0x01, net.AddressFamilyIPv4)},\n\t\t\tAddress: net.LocalHostIP,\n\t\t\tPort:    net.Port(80),\n\t\t\tBytes:   []byte{1, 127, 0, 0, 1, 0, 80},\n\t\t},\n\t}\n\n\tfor _, tc := range data {\n\t\tparser := NewAddressParser(tc.Options...)\n\n\t\tb := buf.New()\n\t\terr := parser.WriteAddressPort(b, tc.Address, tc.Port)\n\t\tif tc.Error {\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"Expect error but nil\")\n\t\t\t}\n\t\t} else {\n\t\t\tcommon.Must(err)\n\t\t\tif diff := cmp.Diff(tc.Bytes, b.Bytes()); diff != \"\" {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc BenchmarkAddressReadingIPv4(b *testing.B) {\n\tparser := NewAddressParser(AddressFamilyByte(0x01, net.AddressFamilyIPv4))\n\tcache := buf.New()\n\tdefer cache.Release()\n\n\tpayload := buf.New()\n\tdefer payload.Release()\n\n\traw := []byte{1, 0, 0, 0, 0, 0, 53}\n\tpayload.Write(raw)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, err := parser.ReadAddressPort(cache, payload)\n\t\tcommon.Must(err)\n\t\tcache.Clear()\n\t\tpayload.Clear()\n\t\tpayload.Extend(int32(len(raw)))\n\t}\n}\n\nfunc BenchmarkAddressReadingIPv6(b *testing.B) {\n\tparser := NewAddressParser(AddressFamilyByte(0x04, net.AddressFamilyIPv6))\n\tcache := buf.New()\n\tdefer cache.Release()\n\n\tpayload := buf.New()\n\tdefer payload.Release()\n\n\traw := []byte{4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 0, 80}\n\tpayload.Write(raw)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, err := parser.ReadAddressPort(cache, payload)\n\t\tcommon.Must(err)\n\t\tcache.Clear()\n\t\tpayload.Clear()\n\t\tpayload.Extend(int32(len(raw)))\n\t}\n}\n\nfunc BenchmarkAddressReadingDomain(b *testing.B) {\n\tparser := NewAddressParser(AddressFamilyByte(0x03, net.AddressFamilyDomain))\n\tcache := buf.New()\n\tdefer cache.Release()\n\n\tpayload := buf.New()\n\tdefer payload.Release()\n\n\traw := []byte{3, 9, 118, 50, 114, 97, 121, 46, 99, 111, 109, 0, 80}\n\tpayload.Write(raw)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, err := parser.ReadAddressPort(cache, payload)\n\t\tcommon.Must(err)\n\t\tcache.Clear()\n\t\tpayload.Clear()\n\t\tpayload.Extend(int32(len(raw)))\n\t}\n}\n\nfunc BenchmarkAddressWritingIPv4(b *testing.B) {\n\tparser := NewAddressParser(AddressFamilyByte(0x01, net.AddressFamilyIPv4))\n\twriter := buf.New()\n\tdefer writer.Release()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(parser.WriteAddressPort(writer, net.LocalHostIP, net.Port(80)))\n\t\twriter.Clear()\n\t}\n}\n\nfunc BenchmarkAddressWritingIPv6(b *testing.B) {\n\tparser := NewAddressParser(AddressFamilyByte(0x04, net.AddressFamilyIPv6))\n\twriter := buf.New()\n\tdefer writer.Release()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(parser.WriteAddressPort(writer, net.LocalHostIPv6, net.Port(80)))\n\t\twriter.Clear()\n\t}\n}\n\nfunc BenchmarkAddressWritingDomain(b *testing.B) {\n\tparser := NewAddressParser(AddressFamilyByte(0x02, net.AddressFamilyDomain))\n\twriter := buf.New()\n\tdefer writer.Release()\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(parser.WriteAddressPort(writer, net.DomainAddress(\"www.v2fly.org\"), net.Port(80)))\n\t\twriter.Clear()\n\t}\n}\n"
  },
  {
    "path": "common/protocol/bittorrent/bittorrent.go",
    "content": "package bittorrent\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\ntype SniffHeader struct{}\n\nfunc (h *SniffHeader) Protocol() string {\n\treturn \"bittorrent\"\n}\n\nfunc (h *SniffHeader) Domain() string {\n\treturn \"\"\n}\n\nvar errNotBittorrent = errors.New(\"not bittorrent header\")\n\nfunc SniffBittorrent(b []byte) (*SniffHeader, error) {\n\tif len(b) < 20 {\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\tif b[0] == 19 && string(b[1:20]) == \"BitTorrent protocol\" {\n\t\treturn &SniffHeader{}, nil\n\t}\n\n\treturn nil, errNotBittorrent\n}\n\nfunc SniffUTP(b []byte) (*SniffHeader, error) {\n\tif len(b) < 20 {\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\tbuffer := buf.FromBytes(b)\n\n\tvar typeAndVersion uint8\n\n\tif binary.Read(buffer, binary.BigEndian, &typeAndVersion) != nil {\n\t\treturn nil, common.ErrNoClue\n\t} else if b[0]>>4&0xF > 4 || b[0]&0xF != 1 {\n\t\treturn nil, errNotBittorrent\n\t}\n\n\tvar extension uint8\n\n\tif binary.Read(buffer, binary.BigEndian, &extension) != nil {\n\t\treturn nil, common.ErrNoClue\n\t} else if extension != 0 && extension != 1 {\n\t\treturn nil, errNotBittorrent\n\t}\n\n\tfor extension != 0 {\n\t\tif extension != 1 {\n\t\t\treturn nil, errNotBittorrent\n\t\t}\n\t\tif binary.Read(buffer, binary.BigEndian, &extension) != nil {\n\t\t\treturn nil, common.ErrNoClue\n\t\t}\n\n\t\tvar length uint8\n\t\tif err := binary.Read(buffer, binary.BigEndian, &length); err != nil {\n\t\t\treturn nil, common.ErrNoClue\n\t\t}\n\t\tif common.Error2(buffer.ReadBytes(int32(length))) != nil {\n\t\t\treturn nil, common.ErrNoClue\n\t\t}\n\t}\n\n\tif common.Error2(buffer.ReadBytes(2)) != nil {\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\tvar timestamp uint32\n\tif err := binary.Read(buffer, binary.BigEndian, &timestamp); err != nil {\n\t\treturn nil, common.ErrNoClue\n\t}\n\tif math.Abs(float64(time.Now().UnixMicro()-int64(timestamp))) > float64(24*time.Hour) {\n\t\treturn nil, errNotBittorrent\n\t}\n\n\treturn &SniffHeader{}, nil\n}\n"
  },
  {
    "path": "common/protocol/context.go",
    "content": "package protocol\n\nimport (\n\t\"context\"\n)\n\ntype key int\n\nconst (\n\trequestKey key = iota\n)\n\nfunc ContextWithRequestHeader(ctx context.Context, request *RequestHeader) context.Context {\n\treturn context.WithValue(ctx, requestKey, request)\n}\n\nfunc RequestHeaderFromContext(ctx context.Context) *RequestHeader {\n\trequest := ctx.Value(requestKey)\n\tif request == nil {\n\t\treturn nil\n\t}\n\treturn request.(*RequestHeader)\n}\n"
  },
  {
    "path": "common/protocol/dns/errors.generated.go",
    "content": "package dns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/protocol/dns/io.go",
    "content": "package dns\n\nimport (\n\t\"encoding/binary\"\n\t\"sync\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc PackMessage(msg *dnsmessage.Message) (*buf.Buffer, error) {\n\tbuffer := buf.New()\n\trawBytes := buffer.Extend(buf.Size)\n\tpacked, err := msg.AppendPack(rawBytes[:0])\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, err\n\t}\n\tbuffer.Resize(0, int32(len(packed)))\n\treturn buffer, nil\n}\n\ntype MessageReader interface {\n\tReadMessage() (*buf.Buffer, error)\n}\n\ntype UDPReader struct {\n\tbuf.Reader\n\n\taccess sync.Mutex\n\tcache  buf.MultiBuffer\n}\n\nfunc (r *UDPReader) readCache() *buf.Buffer {\n\tr.access.Lock()\n\tdefer r.access.Unlock()\n\n\tmb, b := buf.SplitFirst(r.cache)\n\tr.cache = mb\n\treturn b\n}\n\nfunc (r *UDPReader) refill() error {\n\tmb, err := r.Reader.ReadMultiBuffer()\n\tif err != nil {\n\t\treturn err\n\t}\n\tr.access.Lock()\n\tr.cache = mb\n\tr.access.Unlock()\n\treturn nil\n}\n\n// ReadMessage implements MessageReader.\nfunc (r *UDPReader) ReadMessage() (*buf.Buffer, error) {\n\tfor {\n\t\tb := r.readCache()\n\t\tif b != nil {\n\t\t\treturn b, nil\n\t\t}\n\t\tif err := r.refill(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n}\n\n// Close implements common.Closable.\nfunc (r *UDPReader) Close() error {\n\tdefer func() {\n\t\tr.access.Lock()\n\t\tbuf.ReleaseMulti(r.cache)\n\t\tr.cache = nil\n\t\tr.access.Unlock()\n\t}()\n\n\treturn common.Close(r.Reader)\n}\n\ntype TCPReader struct {\n\treader *buf.BufferedReader\n}\n\nfunc NewTCPReader(reader buf.Reader) *TCPReader {\n\treturn &TCPReader{\n\t\treader: &buf.BufferedReader{\n\t\t\tReader: reader,\n\t\t},\n\t}\n}\n\nfunc (r *TCPReader) ReadMessage() (*buf.Buffer, error) {\n\tsize, err := serial.ReadUint16(r.reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif size > buf.Size {\n\t\treturn nil, newError(\"message size too large: \", size)\n\t}\n\tb := buf.New()\n\tif _, err := b.ReadFullFrom(r.reader, int32(size)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn b, nil\n}\n\nfunc (r *TCPReader) Interrupt() {\n\tcommon.Interrupt(r.reader)\n}\n\nfunc (r *TCPReader) Close() error {\n\treturn common.Close(r.reader)\n}\n\ntype MessageWriter interface {\n\tWriteMessage(msg *buf.Buffer) error\n}\n\ntype UDPWriter struct {\n\tbuf.Writer\n}\n\nfunc (w *UDPWriter) WriteMessage(b *buf.Buffer) error {\n\treturn w.WriteMultiBuffer(buf.MultiBuffer{b})\n}\n\ntype TCPWriter struct {\n\tbuf.Writer\n}\n\nfunc (w *TCPWriter) WriteMessage(b *buf.Buffer) error {\n\tif b.IsEmpty() {\n\t\treturn nil\n\t}\n\n\tmb := make(buf.MultiBuffer, 0, 2)\n\n\tsize := buf.New()\n\tbinary.BigEndian.PutUint16(size.Extend(2), uint16(b.Len()))\n\tmb = append(mb, size, b)\n\treturn w.WriteMultiBuffer(mb)\n}\n"
  },
  {
    "path": "common/protocol/errors.generated.go",
    "content": "package protocol\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/protocol/headers.go",
    "content": "package protocol\n\nimport (\n\t\"runtime\"\n\n\t\"golang.org/x/sys/cpu\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/bitmask\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\n// RequestCommand is a custom command in a proxy request.\ntype RequestCommand byte\n\nconst (\n\tRequestCommandTCP = RequestCommand(0x01)\n\tRequestCommandUDP = RequestCommand(0x02)\n\tRequestCommandMux = RequestCommand(0x03)\n)\n\nfunc (c RequestCommand) TransferType() TransferType {\n\tswitch c {\n\tcase RequestCommandTCP, RequestCommandMux:\n\t\treturn TransferTypeStream\n\tcase RequestCommandUDP:\n\t\treturn TransferTypePacket\n\tdefault:\n\t\treturn TransferTypeStream\n\t}\n}\n\nconst (\n\t// RequestOptionChunkStream indicates request payload is chunked. Each chunk consists of length, authentication and payload.\n\tRequestOptionChunkStream bitmask.Byte = 0x01\n\n\t// RequestOptionConnectionReuse indicates client side expects to reuse the connection.\n\tRequestOptionConnectionReuse bitmask.Byte = 0x02\n\n\tRequestOptionChunkMasking bitmask.Byte = 0x04\n\n\tRequestOptionGlobalPadding bitmask.Byte = 0x08\n\n\tRequestOptionAuthenticatedLength bitmask.Byte = 0x10\n)\n\ntype RequestHeader struct {\n\tVersion  byte\n\tCommand  RequestCommand\n\tOption   bitmask.Byte\n\tSecurity SecurityType\n\tPort     net.Port\n\tAddress  net.Address\n\tUser     *MemoryUser\n}\n\nfunc (h *RequestHeader) Destination() net.Destination {\n\tif h.Command == RequestCommandUDP {\n\t\treturn net.UDPDestination(h.Address, h.Port)\n\t}\n\treturn net.TCPDestination(h.Address, h.Port)\n}\n\nconst (\n\tResponseOptionConnectionReuse bitmask.Byte = 0x01\n)\n\ntype ResponseCommand interface{}\n\ntype ResponseHeader struct {\n\tOption  bitmask.Byte\n\tCommand ResponseCommand\n}\n\ntype CommandSwitchAccount struct {\n\tHost     net.Address\n\tPort     net.Port\n\tID       uuid.UUID\n\tLevel    uint32\n\tAlterIds uint16\n\tValidMin byte\n}\n\nvar (\n\thasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ\n\thasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL\n\t// Keep in sync with crypto/aes/cipher_s390x.go.\n\thasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&\n\t\t(cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)\n\n\thasAESGCMHardwareSupport = runtime.GOARCH == \"amd64\" && hasGCMAsmAMD64 ||\n\t\truntime.GOARCH == \"arm64\" && hasGCMAsmARM64 ||\n\t\truntime.GOARCH == \"s390x\" && hasGCMAsmS390X\n)\n\nfunc (sc *SecurityConfig) GetSecurityType() SecurityType {\n\tif sc == nil || sc.Type == SecurityType_AUTO {\n\t\tif hasAESGCMHardwareSupport {\n\t\t\treturn SecurityType_AES128_GCM\n\t\t}\n\t\treturn SecurityType_CHACHA20_POLY1305\n\t}\n\treturn sc.Type\n}\n\nfunc IsDomainTooLong(domain string) bool {\n\treturn len(domain) > 255\n}\n"
  },
  {
    "path": "common/protocol/headers.pb.go",
    "content": "package protocol\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 SecurityType int32\n\nconst (\n\tSecurityType_UNKNOWN           SecurityType = 0\n\tSecurityType_LEGACY            SecurityType = 1\n\tSecurityType_AUTO              SecurityType = 2\n\tSecurityType_AES128_GCM        SecurityType = 3\n\tSecurityType_CHACHA20_POLY1305 SecurityType = 4\n\tSecurityType_NONE              SecurityType = 5\n\tSecurityType_ZERO              SecurityType = 6\n)\n\n// Enum value maps for SecurityType.\nvar (\n\tSecurityType_name = map[int32]string{\n\t\t0: \"UNKNOWN\",\n\t\t1: \"LEGACY\",\n\t\t2: \"AUTO\",\n\t\t3: \"AES128_GCM\",\n\t\t4: \"CHACHA20_POLY1305\",\n\t\t5: \"NONE\",\n\t\t6: \"ZERO\",\n\t}\n\tSecurityType_value = map[string]int32{\n\t\t\"UNKNOWN\":           0,\n\t\t\"LEGACY\":            1,\n\t\t\"AUTO\":              2,\n\t\t\"AES128_GCM\":        3,\n\t\t\"CHACHA20_POLY1305\": 4,\n\t\t\"NONE\":              5,\n\t\t\"ZERO\":              6,\n\t}\n)\n\nfunc (x SecurityType) Enum() *SecurityType {\n\tp := new(SecurityType)\n\t*p = x\n\treturn p\n}\n\nfunc (x SecurityType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (SecurityType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_common_protocol_headers_proto_enumTypes[0].Descriptor()\n}\n\nfunc (SecurityType) Type() protoreflect.EnumType {\n\treturn &file_common_protocol_headers_proto_enumTypes[0]\n}\n\nfunc (x SecurityType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use SecurityType.Descriptor instead.\nfunc (SecurityType) EnumDescriptor() ([]byte, []int) {\n\treturn file_common_protocol_headers_proto_rawDescGZIP(), []int{0}\n}\n\ntype SecurityConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tType          SecurityType           `protobuf:\"varint,1,opt,name=type,proto3,enum=v2ray.core.common.protocol.SecurityType\" json:\"type,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SecurityConfig) Reset() {\n\t*x = SecurityConfig{}\n\tmi := &file_common_protocol_headers_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SecurityConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecurityConfig) ProtoMessage() {}\n\nfunc (x *SecurityConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_protocol_headers_proto_msgTypes[0]\n\tif 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 SecurityConfig.ProtoReflect.Descriptor instead.\nfunc (*SecurityConfig) Descriptor() ([]byte, []int) {\n\treturn file_common_protocol_headers_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *SecurityConfig) GetType() SecurityType {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn SecurityType_UNKNOWN\n}\n\nvar File_common_protocol_headers_proto protoreflect.FileDescriptor\n\nconst file_common_protocol_headers_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1dcommon/protocol/headers.proto\\x12\\x1av2ray.core.common.protocol\\\"N\\n\" +\n\t\"\\x0eSecurityConfig\\x12<\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\x0e2(.v2ray.core.common.protocol.SecurityTypeR\\x04type*l\\n\" +\n\t\"\\fSecurityType\\x12\\v\\n\" +\n\t\"\\aUNKNOWN\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06LEGACY\\x10\\x01\\x12\\b\\n\" +\n\t\"\\x04AUTO\\x10\\x02\\x12\\x0e\\n\" +\n\t\"\\n\" +\n\t\"AES128_GCM\\x10\\x03\\x12\\x15\\n\" +\n\t\"\\x11CHACHA20_POLY1305\\x10\\x04\\x12\\b\\n\" +\n\t\"\\x04NONE\\x10\\x05\\x12\\b\\n\" +\n\t\"\\x04ZERO\\x10\\x06Bo\\n\" +\n\t\"\\x1ecom.v2ray.core.common.protocolP\\x01Z.github.com/v2fly/v2ray-core/v5/common/protocol\\xaa\\x02\\x1aV2Ray.Core.Common.Protocolb\\x06proto3\"\n\nvar (\n\tfile_common_protocol_headers_proto_rawDescOnce sync.Once\n\tfile_common_protocol_headers_proto_rawDescData []byte\n)\n\nfunc file_common_protocol_headers_proto_rawDescGZIP() []byte {\n\tfile_common_protocol_headers_proto_rawDescOnce.Do(func() {\n\t\tfile_common_protocol_headers_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_protocol_headers_proto_rawDesc), len(file_common_protocol_headers_proto_rawDesc)))\n\t})\n\treturn file_common_protocol_headers_proto_rawDescData\n}\n\nvar file_common_protocol_headers_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_common_protocol_headers_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_protocol_headers_proto_goTypes = []any{\n\t(SecurityType)(0),      // 0: v2ray.core.common.protocol.SecurityType\n\t(*SecurityConfig)(nil), // 1: v2ray.core.common.protocol.SecurityConfig\n}\nvar file_common_protocol_headers_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.common.protocol.SecurityConfig.type:type_name -> v2ray.core.common.protocol.SecurityType\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_common_protocol_headers_proto_init() }\nfunc file_common_protocol_headers_proto_init() {\n\tif File_common_protocol_headers_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: unsafe.Slice(unsafe.StringData(file_common_protocol_headers_proto_rawDesc), len(file_common_protocol_headers_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_protocol_headers_proto_goTypes,\n\t\tDependencyIndexes: file_common_protocol_headers_proto_depIdxs,\n\t\tEnumInfos:         file_common_protocol_headers_proto_enumTypes,\n\t\tMessageInfos:      file_common_protocol_headers_proto_msgTypes,\n\t}.Build()\n\tFile_common_protocol_headers_proto = out.File\n\tfile_common_protocol_headers_proto_goTypes = nil\n\tfile_common_protocol_headers_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/protocol/headers.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.protocol;\noption csharp_namespace = \"V2Ray.Core.Common.Protocol\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/protocol\";\noption java_package = \"com.v2ray.core.common.protocol\";\noption java_multiple_files = true;\n\nenum SecurityType {\n  UNKNOWN = 0;\n  LEGACY = 1;\n  AUTO = 2;\n  AES128_GCM = 3;\n  CHACHA20_POLY1305 = 4;\n  NONE = 5;\n  ZERO = 6;\n}\n\nmessage SecurityConfig {\n  SecurityType type = 1;\n}\n"
  },
  {
    "path": "common/protocol/http/headers.go",
    "content": "package http\n\nimport (\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n// ParseXForwardedFor parses X-Forwarded-For header in http headers, and return the IP list in it.\nfunc ParseXForwardedFor(header http.Header) []net.Address {\n\txff := header.Get(\"X-Forwarded-For\")\n\tif xff == \"\" {\n\t\treturn nil\n\t}\n\tlist := strings.Split(xff, \",\")\n\taddrs := make([]net.Address, 0, len(list))\n\tfor _, proxy := range list {\n\t\taddrs = append(addrs, net.ParseAddress(proxy))\n\t}\n\treturn addrs\n}\n\n// RemoveHopByHopHeaders remove hop by hop headers in http header list.\nfunc RemoveHopByHopHeaders(header http.Header) {\n\t// Strip hop-by-hop header based on RFC:\n\t// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1\n\t// https://www.mnot.net/blog/2011/07/11/what_proxies_must_do\n\n\theader.Del(\"Proxy-Connection\")\n\theader.Del(\"Proxy-Authenticate\")\n\theader.Del(\"Proxy-Authorization\")\n\theader.Del(\"TE\")\n\theader.Del(\"Trailers\")\n\theader.Del(\"Transfer-Encoding\")\n\theader.Del(\"Upgrade\")\n\theader.Del(\"Keep-Alive\")\n\n\tconnections := header.Get(\"Connection\")\n\theader.Del(\"Connection\")\n\tif connections == \"\" {\n\t\treturn\n\t}\n\tfor _, h := range strings.Split(connections, \",\") {\n\t\theader.Del(strings.TrimSpace(h))\n\t}\n}\n\n// ParseHost splits host and port from a raw string. Default port is used when raw string doesn't contain port.\nfunc ParseHost(rawHost string, defaultPort net.Port) (net.Destination, error) {\n\tport := defaultPort\n\thost, rawPort, err := net.SplitHostPort(rawHost)\n\tif err != nil {\n\t\tif addrError, ok := err.(*net.AddrError); ok && strings.Contains(addrError.Err, \"missing port\") {\n\t\t\thost = rawHost\n\t\t} else {\n\t\t\treturn net.Destination{}, err\n\t\t}\n\t} else if len(rawPort) > 0 {\n\t\tintPort, err := strconv.ParseUint(rawPort, 0, 16)\n\t\tif err != nil {\n\t\t\treturn net.Destination{}, err\n\t\t}\n\t\tport = net.Port(intPort)\n\t}\n\n\treturn net.TCPDestination(net.ParseAddress(host), port), nil\n}\n"
  },
  {
    "path": "common/protocol/http/headers_test.go",
    "content": "package http_test\n\nimport (\n\t\"bufio\"\n\t\"net/http\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n)\n\nfunc TestParseXForwardedFor(t *testing.T) {\n\theader := http.Header{}\n\theader.Add(\"X-Forwarded-For\", \"129.78.138.66, 129.78.64.103\")\n\taddrs := ParseXForwardedFor(header)\n\tif r := cmp.Diff(addrs, []net.Address{net.ParseAddress(\"129.78.138.66\"), net.ParseAddress(\"129.78.64.103\")}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestHopByHopHeadersRemoving(t *testing.T) {\n\trawRequest := `GET /pkg/net/http/ HTTP/1.1\nHost: golang.org\nConnection: keep-alive,Foo, Bar\nFoo: foo\nBar: bar\nProxy-Connection: keep-alive\nProxy-Authenticate: abc\nAccept-Encoding: gzip\nAccept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7\nCache-Control: no-cache\nAccept-Language: de,en;q=0.7,en-us;q=0.3\n\n`\n\tb := bufio.NewReader(strings.NewReader(rawRequest))\n\treq, err := http.ReadRequest(b)\n\tcommon.Must(err)\n\theaders := []struct {\n\t\tKey   string\n\t\tValue string\n\t}{\n\t\t{\n\t\t\tKey:   \"Foo\",\n\t\t\tValue: \"foo\",\n\t\t},\n\t\t{\n\t\t\tKey:   \"Bar\",\n\t\t\tValue: \"bar\",\n\t\t},\n\t\t{\n\t\t\tKey:   \"Connection\",\n\t\t\tValue: \"keep-alive,Foo, Bar\",\n\t\t},\n\t\t{\n\t\t\tKey:   \"Proxy-Connection\",\n\t\t\tValue: \"keep-alive\",\n\t\t},\n\t\t{\n\t\t\tKey:   \"Proxy-Authenticate\",\n\t\t\tValue: \"abc\",\n\t\t},\n\t}\n\tfor _, header := range headers {\n\t\tif v := req.Header.Get(header.Key); v != header.Value {\n\t\t\tt.Error(\"header \", header.Key, \" = \", v, \" want \", header.Value)\n\t\t}\n\t}\n\n\tRemoveHopByHopHeaders(req.Header)\n\n\tfor _, header := range []string{\"Connection\", \"Foo\", \"Bar\", \"Proxy-Connection\", \"Proxy-Authenticate\"} {\n\t\tif v := req.Header.Get(header); v != \"\" {\n\t\t\tt.Error(\"header \", header, \" = \", v)\n\t\t}\n\t}\n}\n\nfunc TestParseHost(t *testing.T) {\n\ttestCases := []struct {\n\t\tRawHost     string\n\t\tDefaultPort net.Port\n\t\tDestination net.Destination\n\t\tError       bool\n\t}{\n\t\t{\n\t\t\tRawHost:     \"v2fly.org:80\",\n\t\t\tDefaultPort: 443,\n\t\t\tDestination: net.TCPDestination(net.DomainAddress(\"v2fly.org\"), 80),\n\t\t},\n\t\t{\n\t\t\tRawHost:     \"tls.v2fly.org\",\n\t\t\tDefaultPort: 443,\n\t\t\tDestination: net.TCPDestination(net.DomainAddress(\"tls.v2fly.org\"), 443),\n\t\t},\n\t\t{\n\t\t\tRawHost:     \"[2401:1bc0:51f0:ec08::1]:80\",\n\t\t\tDefaultPort: 443,\n\t\t\tDestination: net.TCPDestination(net.ParseAddress(\"[2401:1bc0:51f0:ec08::1]\"), 80),\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tdest, err := ParseHost(testCase.RawHost, testCase.DefaultPort)\n\t\tif testCase.Error {\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"for test case: \", testCase.RawHost, \" expected error, but actually nil\")\n\t\t\t}\n\t\t} else {\n\t\t\tif dest != testCase.Destination {\n\t\t\t\tt.Error(\"for test case: \", testCase.RawHost, \" expected host: \", testCase.Destination.String(), \" but got \", dest.String())\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/protocol/http/sniff.go",
    "content": "package http\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype version byte\n\ntype SniffHeader struct {\n\thost string\n}\n\nfunc (h *SniffHeader) Protocol() string {\n\treturn \"http1\"\n}\n\nfunc (h *SniffHeader) Domain() string {\n\treturn h.host\n}\n\nvar (\n\t// refer to https://pkg.go.dev/net/http@master#pkg-constants\n\tmethods = [...]string{\"get\", \"post\", \"head\", \"put\", \"delete\", \"options\", \"connect\", \"patch\", \"trace\"}\n\n\terrNotHTTPMethod = errors.New(\"not an HTTP method\")\n)\n\nfunc beginWithHTTPMethod(b []byte) error {\n\tfor _, m := range &methods {\n\t\tif len(b) >= len(m) && strings.EqualFold(string(b[:len(m)]), m) {\n\t\t\treturn nil\n\t\t}\n\n\t\tif len(b) < len(m) {\n\t\t\treturn common.ErrNoClue\n\t\t}\n\t}\n\n\treturn errNotHTTPMethod\n}\n\nfunc SniffHTTP(b []byte) (*SniffHeader, error) {\n\tif err := beginWithHTTPMethod(b); err != nil {\n\t\treturn nil, err\n\t}\n\n\tsh := &SniffHeader{}\n\n\theaders := bytes.Split(b, []byte{'\\n'})\n\tfor i := 1; i < len(headers); i++ {\n\t\theader := headers[i]\n\t\tif len(header) == 0 {\n\t\t\tbreak\n\t\t}\n\t\tparts := bytes.SplitN(header, []byte{':'}, 2)\n\t\tif len(parts) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tkey := strings.ToLower(string(parts[0]))\n\t\tif key == \"host\" {\n\t\t\trawHost := strings.ToLower(string(bytes.TrimSpace(parts[1])))\n\t\t\tdest, err := ParseHost(rawHost, net.Port(80))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tsh.host = dest.Address.String()\n\t\t}\n\t}\n\n\tif len(sh.host) > 0 {\n\t\treturn sh, nil\n\t}\n\n\treturn nil, common.ErrNoClue\n}\n"
  },
  {
    "path": "common/protocol/http/sniff_test.go",
    "content": "package http_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n)\n\nfunc TestHTTPHeaders(t *testing.T) {\n\tcases := []struct {\n\t\tinput  string\n\t\tdomain string\n\t\terr    bool\n\t}{\n\t\t{\n\t\t\tinput: `GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\nHost: net.tutsplus.com\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en-us,en;q=0.5\nAccept-Encoding: gzip,deflate\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\nKeep-Alive: 300\nConnection: keep-alive\nCookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\nPragma: no-cache\nCache-Control: no-cache`,\n\t\t\tdomain: \"net.tutsplus.com\",\n\t\t},\n\t\t{\n\t\t\tinput: `POST /foo.php HTTP/1.1\nHost: localhost\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en-us,en;q=0.5\nAccept-Encoding: gzip,deflate\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\nKeep-Alive: 300\nConnection: keep-alive\nReferer: http://localhost/test.php\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 43\n \nfirst_name=John&last_name=Doe&action=Submit`,\n\t\t\tdomain: \"localhost\",\n\t\t},\n\t\t{\n\t\t\tinput: `X /foo.php HTTP/1.1\nHost: localhost\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en-us,en;q=0.5\nAccept-Encoding: gzip,deflate\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\nKeep-Alive: 300\nConnection: keep-alive\nReferer: http://localhost/test.php\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 43\n \nfirst_name=John&last_name=Doe&action=Submit`,\n\t\t\tdomain: \"\",\n\t\t\terr:    true,\n\t\t},\n\t\t{\n\t\t\tinput: `GET /foo.php HTTP/1.1\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en-us,en;q=0.5\nAccept-Encoding: gzip,deflate\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\nKeep-Alive: 300\nConnection: keep-alive\nReferer: http://localhost/test.php\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 43\n\nHost: localhost\nfirst_name=John&last_name=Doe&action=Submit`,\n\t\t\tdomain: \"\",\n\t\t\terr:    true,\n\t\t},\n\t\t{\n\t\t\tinput:  `GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1`,\n\t\t\tdomain: \"\",\n\t\t\terr:    true,\n\t\t},\n\t}\n\n\tfor _, test := range cases {\n\t\theader, err := SniffHTTP([]byte(test.input))\n\t\tif test.err {\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"Expect error but nil, in test: %v\", test)\n\t\t\t}\n\t\t} else {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"Expect no error but actually %s in test %v\", err.Error(), test)\n\t\t\t}\n\t\t\tif header.Domain() != test.domain {\n\t\t\t\tt.Error(\"expected domain \", test.domain, \" but got \", header.Domain())\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/protocol/id.go",
    "content": "package protocol\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/md5\"\n\t\"hash\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\nconst (\n\tIDBytesLen = 16\n)\n\ntype IDHash func(key []byte) hash.Hash\n\nfunc DefaultIDHash(key []byte) hash.Hash {\n\treturn hmac.New(md5.New, key)\n}\n\n// The ID of en entity, in the form of a UUID.\ntype ID struct {\n\tuuid   uuid.UUID\n\tcmdKey [IDBytesLen]byte\n}\n\n// Equals returns true if this ID equals to the other one.\nfunc (id *ID) Equals(another *ID) bool {\n\treturn id.uuid.Equals(&(another.uuid))\n}\n\nfunc (id *ID) Bytes() []byte {\n\treturn id.uuid.Bytes()\n}\n\nfunc (id *ID) String() string {\n\treturn id.uuid.String()\n}\n\nfunc (id *ID) UUID() uuid.UUID {\n\treturn id.uuid\n}\n\nfunc (id ID) CmdKey() []byte {\n\treturn id.cmdKey[:]\n}\n\n// NewID returns an ID with given UUID.\nfunc NewID(uuid uuid.UUID) *ID {\n\tid := &ID{uuid: uuid}\n\tmd5hash := md5.New()\n\tcommon.Must2(md5hash.Write(uuid.Bytes()))\n\tcommon.Must2(md5hash.Write([]byte(\"c48619fe-8f02-49e0-b9e9-edf763e17e21\")))\n\tmd5hash.Sum(id.cmdKey[:0])\n\treturn id\n}\n\nfunc nextID(u *uuid.UUID) uuid.UUID {\n\tmd5hash := md5.New()\n\tcommon.Must2(md5hash.Write(u.Bytes()))\n\tcommon.Must2(md5hash.Write([]byte(\"16167dc8-16b6-4e6d-b8bb-65dd68113a81\")))\n\tvar newid uuid.UUID\n\tfor {\n\t\tmd5hash.Sum(newid[:0])\n\t\tif !newid.Equals(u) {\n\t\t\treturn newid\n\t\t}\n\t\tcommon.Must2(md5hash.Write([]byte(\"533eff8a-4113-4b10-b5ce-0f5d76b98cd2\")))\n\t}\n}\n\nfunc NewAlterIDs(primary *ID, alterIDCount uint16) []*ID {\n\talterIDs := make([]*ID, alterIDCount)\n\tprevID := primary.UUID()\n\tfor idx := range alterIDs {\n\t\tnewid := nextID(&prevID)\n\t\talterIDs[idx] = NewID(newid)\n\t\tprevID = newid\n\t}\n\treturn alterIDs\n}\n"
  },
  {
    "path": "common/protocol/id_test.go",
    "content": "package protocol_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\nfunc TestIdEquals(t *testing.T) {\n\tid1 := NewID(uuid.New())\n\tid2 := NewID(id1.UUID())\n\n\tif !id1.Equals(id2) {\n\t\tt.Error(\"expected id1 to equal id2, but actually not\")\n\t}\n\n\tif id1.String() != id2.String() {\n\t\tt.Error(id1.String(), \" != \", id2.String())\n\t}\n}\n"
  },
  {
    "path": "common/protocol/payload.go",
    "content": "package protocol\n\ntype TransferType byte\n\nconst (\n\tTransferTypeStream TransferType = 0\n\tTransferTypePacket TransferType = 1\n)\n\ntype AddressType byte\n\nconst (\n\tAddressTypeIPv4   AddressType = 1\n\tAddressTypeDomain AddressType = 2\n\tAddressTypeIPv6   AddressType = 3\n)\n"
  },
  {
    "path": "common/protocol/protocol.go",
    "content": "package protocol\n\nimport (\n\t\"errors\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nvar ErrProtoNeedMoreData = errors.New(\"protocol matches, but need more data to complete sniffing\")\n"
  },
  {
    "path": "common/protocol/quic/cipher_suite.go",
    "content": "package quic\n\nimport (\n\t\"crypto\"\n\t\"crypto/cipher\"\n\t_ \"crypto/tls\"\n\t_ \"unsafe\"\n)\n\n// copied from github.com/quic-go/quic-go/internal/qtls/cipher_suite_go121.go\n\ntype cipherSuiteTLS13 struct {\n\tID     uint16\n\tKeyLen int\n\tAEAD   func(key, fixedNonce []byte) cipher.AEAD\n\tHash   crypto.Hash\n}\n\n// github.com/quic-go/quic-go/internal/handshake/cipher_suite.go describes these cipher suite implementations are copied from the standard library crypto/tls package.\n// So we can user go:linkname to implement the same feature.\n\n//go:linkname aeadAESGCMTLS13 crypto/tls.aeadAESGCMTLS13\nfunc aeadAESGCMTLS13(key, nonceMask []byte) cipher.AEAD\n"
  },
  {
    "path": "common/protocol/quic/sniff.go",
    "content": "package quic\n\nimport (\n\t\"crypto\"\n\t\"crypto/aes\"\n\t\"crypto/tls\"\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/quicvarint\"\n\t\"golang.org/x/crypto/hkdf\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tptls \"github.com/v2fly/v2ray-core/v5/common/protocol/tls\"\n)\n\ntype SniffHeader struct {\n\tdomain string\n}\n\nfunc (s SniffHeader) Protocol() string {\n\treturn \"quic\"\n}\n\nfunc (s SniffHeader) Domain() string {\n\treturn s.domain\n}\n\nconst (\n\tversionDraft29 uint32 = 0xff00001d\n\tversion1       uint32 = 0x1\n)\n\nvar (\n\tquicSaltOld  = []byte{0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99}\n\tquicSalt     = []byte{0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a}\n\tinitialSuite = &cipherSuiteTLS13{\n\t\tID:     tls.TLS_AES_128_GCM_SHA256,\n\t\tKeyLen: 16,\n\t\tAEAD:   aeadAESGCMTLS13,\n\t\tHash:   crypto.SHA256,\n\t}\n\terrNotQuic        = errors.New(\"not quic\")\n\terrNotQuicInitial = errors.New(\"not initial packet\")\n)\n\nfunc SniffQUIC(b []byte) (*SniffHeader, error) {\n\tif len(b) == 0 {\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\t// Crypto data separated across packets\n\tcryptoLen := 0\n\tcryptoDataBuf := buf.NewWithSize(32767)\n\tdefer cryptoDataBuf.Release()\n\n\tcache := buf.New()\n\tdefer cache.Release()\n\n\t// Parse QUIC packets\n\tfor len(b) > 0 {\n\t\tbuffer := buf.FromBytes(b)\n\t\ttypeByte, err := buffer.ReadByte()\n\t\tif err != nil {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\n\t\tisLongHeader := typeByte&0x80 > 0\n\t\tif !isLongHeader || typeByte&0x40 == 0 {\n\t\t\treturn nil, errNotQuicInitial\n\t\t}\n\n\t\tvb, err := buffer.ReadBytes(4)\n\t\tif err != nil {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\n\t\tversionNumber := binary.BigEndian.Uint32(vb)\n\t\tif versionNumber != 0 && typeByte&0x40 == 0 {\n\t\t\treturn nil, errNotQuic\n\t\t} else if versionNumber != versionDraft29 && versionNumber != version1 {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\n\t\tpacketType := (typeByte & 0x30) >> 4\n\t\tisQuicInitial := packetType == 0x0\n\n\t\tvar destConnID []byte\n\t\tif l, err := buffer.ReadByte(); err != nil {\n\t\t\treturn nil, errNotQuic\n\t\t} else if destConnID, err = buffer.ReadBytes(int32(l)); err != nil {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\n\t\tif l, err := buffer.ReadByte(); err != nil {\n\t\t\treturn nil, errNotQuic\n\t\t} else if common.Error2(buffer.ReadBytes(int32(l))) != nil {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\n\t\tif isQuicInitial { // Only initial packets have token, see https://datatracker.ietf.org/doc/html/rfc9000#section-17.2.2\n\t\t\ttokenLen, err := quicvarint.Read(buffer)\n\t\t\tif err != nil || tokenLen > uint64(len(b)) {\n\t\t\t\treturn nil, errNotQuic\n\t\t\t}\n\n\t\t\tif _, err = buffer.ReadBytes(int32(tokenLen)); err != nil {\n\t\t\t\treturn nil, errNotQuic\n\t\t\t}\n\t\t}\n\n\t\tpacketLen, err := quicvarint.Read(buffer)\n\t\tif err != nil {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\t\t// packet is impossible to shorter than this\n\t\tif packetLen < 4 {\n\t\t\treturn nil, errNotQuic\n\t\t}\n\n\t\thdrLen := len(b) - int(buffer.Len())\n\t\tif len(b) < hdrLen+int(packetLen) {\n\t\t\treturn nil, common.ErrNoClue // Not enough data to read as a QUIC packet. QUIC is UDP-based, so this is unlikely to happen.\n\t\t}\n\n\t\trestPayload := b[hdrLen+int(packetLen):]\n\t\tif !isQuicInitial { // Skip this packet if it's not initial packet\n\t\t\tb = restPayload\n\t\t\tcontinue\n\t\t}\n\n\t\torigPNBytes := make([]byte, 4)\n\t\tcopy(origPNBytes, b[hdrLen:hdrLen+4])\n\n\t\tvar salt []byte\n\t\tif versionNumber == version1 {\n\t\t\tsalt = quicSalt\n\t\t} else {\n\t\t\tsalt = quicSaltOld\n\t\t}\n\t\tinitialSecret := hkdf.Extract(crypto.SHA256.New, destConnID, salt)\n\t\tsecret := hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, \"client in\", crypto.SHA256.Size())\n\t\thpKey := hkdfExpandLabel(initialSuite.Hash, secret, []byte{}, \"quic hp\", initialSuite.KeyLen)\n\t\tblock, err := aes.NewCipher(hpKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcache.Clear()\n\t\tmask := cache.Extend(int32(block.BlockSize()))\n\t\tblock.Encrypt(mask, b[hdrLen+4:hdrLen+4+16])\n\t\tb[0] ^= mask[0] & 0xf\n\t\tfor i := range b[hdrLen : hdrLen+4] {\n\t\t\tb[hdrLen+i] ^= mask[i+1]\n\t\t}\n\t\tpacketNumberLength := b[0]&0x3 + 1\n\t\tif packetNumberLength != 1 {\n\t\t\treturn nil, errNotQuicInitial\n\t\t}\n\t\tvar packetNumber uint32\n\t\t{\n\t\t\tn, err := buffer.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tpacketNumber = uint32(n)\n\t\t}\n\n\t\textHdrLen := hdrLen + int(packetNumberLength)\n\t\tcopy(b[extHdrLen:hdrLen+4], origPNBytes[packetNumberLength:])\n\t\tdata := b[extHdrLen : int(packetLen)+hdrLen]\n\n\t\tkey := hkdfExpandLabel(crypto.SHA256, secret, []byte{}, \"quic key\", 16)\n\t\tiv := hkdfExpandLabel(crypto.SHA256, secret, []byte{}, \"quic iv\", 12)\n\t\tcipher := aeadAESGCMTLS13(key, iv)\n\t\tnonce := cache.Extend(int32(cipher.NonceSize()))\n\t\tbinary.BigEndian.PutUint64(nonce[len(nonce)-8:], uint64(packetNumber))\n\t\tdecrypted, err := cipher.Open(b[extHdrLen:extHdrLen], nonce, data, b[:extHdrLen])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbuffer = buf.FromBytes(decrypted)\n\t\tfor i := 0; !buffer.IsEmpty(); i++ {\n\t\t\tframeType := byte(0x0) // Default to PADDING frame\n\t\t\tfor frameType == 0x0 && !buffer.IsEmpty() {\n\t\t\t\tframeType, _ = buffer.ReadByte()\n\t\t\t}\n\t\t\tswitch frameType {\n\t\t\tcase 0x00: // PADDING frame\n\t\t\tcase 0x01: // PING frame\n\t\t\tcase 0x02, 0x03: // ACK frame\n\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: Largest Acknowledged\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: ACK Delay\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tackRangeCount, err := quicvarint.Read(buffer) // Field: ACK Range Count\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: First ACK Range\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tfor i := 0; i < int(ackRangeCount); i++ { // Field: ACK Range\n\t\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: ACK Range -> Gap\n\t\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: ACK Range -> ACK Range Length\n\t\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif frameType == 0x03 {\n\t\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: ECN Counts -> ECT0 Count\n\t\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: ECN Counts -> ECT1 Count\n\t\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { //nolint:misspell // Field: ECN Counts -> ECT-CE Count\n\t\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase 0x06: // CRYPTO frame, we will use this frame\n\t\t\t\toffset, err := quicvarint.Read(buffer) // Field: Offset\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tlength, err := quicvarint.Read(buffer) // Field: Length\n\t\t\t\tif err != nil || length > uint64(buffer.Len()) {\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tif cryptoLen < int(offset+length) {\n\t\t\t\t\tcryptoLen = int(offset + length)\n\t\t\t\t\tif cryptoDataBuf.Cap() < int32(cryptoLen) {\n\t\t\t\t\t\treturn nil, io.ErrShortBuffer\n\t\t\t\t\t}\n\t\t\t\t\tif cryptoDataBuf.Len() != int32(cryptoLen) {\n\t\t\t\t\t\tcryptoDataBuf.Extend(int32(cryptoLen) - cryptoDataBuf.Len())\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif _, err := buffer.Read(cryptoDataBuf.BytesRange(int32(offset), int32(offset+length))); err != nil { // Field: Crypto Data\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\tcase 0x1c: // CONNECTION_CLOSE frame, only 0x1c is permitted in initial packet\n\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: Error Code\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tif _, err = quicvarint.Read(buffer); err != nil { // Field: Frame Type\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tlength, err := quicvarint.Read(buffer) // Field: Reason Phrase Length\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tif _, err := buffer.ReadBytes(int32(length)); err != nil { // Field: Reason Phrase\n\t\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\t// Only above frame types are permitted in initial packet.\n\t\t\t\t// See https://www.rfc-editor.org/rfc/rfc9000.html#section-17.2.2-8\n\t\t\t\treturn nil, errNotQuicInitial\n\t\t\t}\n\t\t}\n\n\t\ttlsHdr := &ptls.SniffHeader{}\n\t\terr = ptls.ReadClientHello(cryptoDataBuf.BytesRange(0, int32(cryptoLen)), tlsHdr)\n\t\tif err != nil {\n\t\t\t// The crypto data may have not been fully recovered in current packets,\n\t\t\t// So we continue to sniff rest packets.\n\t\t\tb = restPayload\n\t\t\tcontinue\n\t\t}\n\t\treturn &SniffHeader{domain: tlsHdr.Domain()}, nil\n\t}\n\n\t// All payload is parsed as valid QUIC packets, but we need more packets for crypto data to read client hello.\n\treturn nil, protocol.ErrProtoNeedMoreData\n}\n\nfunc hkdfExpandLabel(hash crypto.Hash, secret, context []byte, label string, length int) []byte {\n\tb := make([]byte, 3, 3+6+len(label)+1+len(context))\n\tbinary.BigEndian.PutUint16(b, uint16(length))\n\tb[2] = uint8(6 + len(label))\n\tb = append(b, []byte(\"tls13 \")...)\n\tb = append(b, []byte(label)...)\n\tb = b[:3+6+len(label)+1]\n\tb[3+6+len(label)] = uint8(len(context))\n\tb = append(b, context...)\n\n\tout := make([]byte, length)\n\tn, err := hkdf.Expand(hash.New, secret, b).Read(out)\n\tif err != nil || n != length {\n\t\tpanic(\"quic: HKDF-Expand-Label invocation failed unexpectedly\")\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "common/protocol/quic/sniff_test.go",
    "content": "package quic_test\n\nimport (\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/quic\"\n)\n\nfunc TestSniffQUIC(t *testing.T) {\n\tpkt, err := hex.DecodeString(\"cd0000000108f1fb7bcc78aa5e7203a8f86400421531fe825b19541876db6c55c38890cd73149d267a084afee6087304095417a3033df6a81bbb71d8512e7a3e16df1e277cae5df3182cb214b8fe982ba3fdffbaa9ffec474547d55945f0fddbeadfb0b5243890b2fa3da45169e2bd34ec04b2e29382f48d612b28432a559757504d158e9e505407a77dd34f4b60b8d3b555ee85aacd6648686802f4de25e7216b19e54c5f78e8a5963380c742d861306db4c16e4f7fc94957aa50b9578a0b61f1e406b2ad5f0cd3cd271c4d99476409797b0c3cb3efec256118912d4b7e4fd79d9cb9016b6e5eaa4f5e57b637b217755daf8968a4092bed0ed5413f5d04904b3a61e4064f9211b2629e5b52a89c7b19f37a713e41e27743ea6dfa736dfa1bb0a4b2bc8c8dc632c6ce963493a20c550e6fdb2475213665e9a85cfc394da9cec0cf41f0c8abed3fc83be5245b2b5aa5e825d29349f721d30774ef5bf965b540f3d8d98febe20956b1fc8fa047e10e7d2f921c9c6622389e02322e80621a1cf5264e245b7276966eb02932584e3f7038bd36aa908766ad3fb98344025dec18670d6db43a1c5daac00937fce7b7c7d61ff4e6efd01a2bdee0ee183108b926393df4f3d74bbcbb015f240e7e346b7d01c41111a401225ce3b095ab4623a5836169bf9599eeca79d1d2e9b2202b5960a09211e978058d6fc0484eff3e91ce4649a5e3ba15b906d334cf66e28d9ff575406e1ae1ac2febafd72870b6f5d58fc5fb949cb1f40feb7c1d9ce5e71b\")\n\tcommon.Must(err)\n\tquicHdr, err := quic.SniffQUIC(pkt)\n\tif err != nil || quicHdr.Domain() != \"www.google.com\" {\n\t\tt.Error(\"failed\")\n\t}\n}\n\nfunc TestSniffQUICComplex(t *testing.T) {\n\ttests := []struct {\n\t\tname          string\n\t\thexData       string\n\t\tdomain        string\n\t\twantErr       bool\n\t\tneedsMoreData bool\n\t}{\n\t\t{\n\t\t\tname:          \"EmptyPacket\",\n\t\t\thexData:       \"0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"NTP Packet Client\",\n\t\t\thexData:       \"23000000000000000000000000000000000000000000000000000000000000000000000000000000acb84a797d4044c9\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"NTP Packet Server\",\n\t\t\thexData:       \"240106ec000000000000000e47505373ea4dcaef2f4b4c31acb84a797d4044c9eb58b8693dd70c27eb58b8693dd7dde2\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"DNS Packet Client\",\n\t\t\thexData:       \"4500004a8e2d40003f1146392a2a2d03080808081eea00350036a8175ad4010000010000000000000675706461746504636f64650c76697375616c73747564696f03636f6d0000010001\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"DNS Packet Client\",\n\t\t\thexData:       \"4500004a667a40003f116dec2a2a2d030808080866980035003605d9b524010000010000000000000675706461746504636f64650c76697375616c73747564696f03636f6d0000410001\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"DNS Packet Server\",\n\t\t\thexData:       \"b524818000010006000100000675706461746504636f64650c76697375616c73747564696f03636f6d0000410001c00c00050001000000ec00301e7673636f64652d7570646174652d67366763623667676474686b63746439037a303107617a7572656664036e657400c03a000500010000000b002311737461722d617a75726566642d70726f640e747261666669636d616e61676572c065c076000500010000003c002c0473686564086475616c2d6c6f770b732d706172742d3030313706742d3030303908742d6d7365646765c065c0a5000500010000006c001411617a75726566642d742d66622d70726f64c088c0dd000500010000003c0026046475616c0b732d706172742d3030313706742d303030390b66622d742d6d7365646765c065c0fd00050001000000300002c102c1150006000100000030002d036e7331c115066d736e687374096d6963726f736f6674c0257848b78d00000708000003840024ea000000003c\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"DNS Packet Server\",\n\t\t\thexData:       \"5ad4818000010007000000000675706461746504636f64650c76697375616c73747564696f03636f6d0000010001c00c000500010000008400301e7673636f64652d7570646174652d67366763623667676474686b63746439037a303107617a7572656664036e657400c03a000500010000001e002311737461722d617a75726566642d70726f640e747261666669636d616e61676572c065c076000500010000003c002c0473686564086475616c2d6c6f770b732d706172742d3030313706742d3030303908742d6d7365646765c065c0a50005000100000010001411617a75726566642d742d66622d70726f64c088c0dd000500010000003c0026046475616c0b732d706172742d3030313706742d303030390b66622d742d6d7365646765c065c0fd00050001000000100002c102c102000100010000001000040d6bfd2d\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC, NonHandshake Packet\",\n\t\t\thexData:       \"548439ba3a0cffd27dabe08ebf9e603dd4801781e133b1a0276d29a047c3b8856adcced0067c4b11a08985bf93c05863305bd4b43ee9168cd5fdae0c392ff74ae06ce13e8d97dabec81ee927a844fa840f781edf9deb22f3162bf77009b3f5800c5e45539ac104368e7df8ba\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC, NonHandshake Packet\",\n\t\t\thexData:       \"53f4144825dab3ba251b83d0089e910210bec1a6507cca92ad9ff539cc21f6c75e3551ca44003d9a\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC, NonHandshake Packet\",\n\t\t\thexData:       \"528dc5524c03e7517949422cc3f6ffbfff74b2ec30a87654a71a\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[1]; packet 1\",\n\t\t\thexData:       \"cb00000001088ca3be26059ca269000044d088950f316207d551c91c88d791557c440a19184322536d2c900034358c1b3964f2d2935337b8d044d35bf62b4eea9ceaac64121aa634c7cd28630722d169fa0f215b940d47d7996ca56f0d463dbf97a4a1b5818c5297a26fe58f5553dfb513ad589750a61682f229996555c7121c8bf48b06b68ab06427b01af485d832f9894099a20d3baadcff7b1cf07e2c059d3e7ba88d4ad35ef0ffea1fdc6ac3db271dfcca892a41ab25284936225c9bc593ce242b11b8abed4a8df902987eef0c6d90669e3606f47dd6ad05f44ba3a0cd356854261bbb1e2d8f6b83cc57cfa57eda3e5d7181b6ec418f6eeca81c259a33e4b0a913de720f2f8782764766ac9602a7f52a1082ec3da30dbefcf38c781a3e033810c4f2babf9b72adf7164159d98142181492e4468c0e10ab29013bf238e7360e09767ca49d59a9eb18f06a372bad711fefa90295f8e0839b1080570648212b321e5bd6f614bf0d3dc2817628b0c052a32820c16cb7f531c49244c48eb1429625246f9c164ae4ee1e83eaa8ff0eef1acf5a3d8ca88f1e4597db5ba5c0cb23d6100dd53da4f439ae64c4d3d43d1fbb5677f4fdc3bd2c2948dfc7e0be1a33c842033da15529cfd3cae00da68343d835db867f746854804410ba68f0dd7711b0fe55817b83f6ce1a12ad38acf2a3156f819f0dc68ea799c05583d9728f2856577811b260dba40d6c5e82c9e558c5b8f3f4599caf05ea591118e0b80ad621e0a76e4926047593a896752cb168420cb1b02d4211de5e5b7c891f319b5c0cf687e1d261a01f2acbade6bd73cd1ade0a02e240e9351384e1a6868c21a4878f39f0fa94ee1e36c5a46449241a3fe0147ff50176787eca7f3a936c901aeef56770bff74feecb985e6670d20dfd8ed17952dca5a5292213345c61db09bb5bcf5bf74565f61f9dccab51a289c3160ffe4a9b29cc76ea46778d9317a890efea2ad905f4219463a3baca3c02f5c3682634be7c2e86e366272a8263fec8e871644a79299d4aa74f1b1414b2f963cce6e059978faf813625af7869c1dec92035478c0e46dc66d938d4131aca27a59b2103b8cefa8e08aeb44b53b205b932902aea8d519faaaa12e354a6f532b4f716d7929e655dc2e98b494a99153854af5732a2659f2c21e4069896a1835ad05c5e53781cab16599cf4af47c196deeff9115c80d13f93aeb28b08023e6a1d3cf7da2a4457a9e443176bcdfef8f8de630c02bd0efdc5ddda56ad8f6b47edbda6353205e6e655f690092a48deb7f8a5254a7d778e07216cd97dfefcf740c1acd2977ef0fa17f798ea9752bae46e3aa3ec9b13f4c95c20a7839b8409000fa1f17e8dc46cc05c41bff696ee03c0371cae8638e8018ff4ebedd9f27d56443e534a72dd3d18a64790b676ddd060376759fa4a12ffc17f4be83492126ec1dc0fcd4aefef73a0b9c443ec3532b9a66b1a60daacf45e6557115edc0cc4d08758754a44beffedaa0d1265e50beed1a01752904ee3f7e706ed290b1a79071b142105b7c02e692ff318710e3ce9c3b9ec557cdecef173796417341ada414faa06b52adf645db454b56468ccf0da50a942ebc09487797cb45a085ec1e2e06fcd1f5b72eac291955a62e5aa379a374aea3a0dec3e4e0ba1dde350a94c72dbea7505922e26e99d62f751c2b301413a73fb6b20a36052151473ebecd04d0a771ec326957bc28c2020fdf6f01d9abed69b3c3e73168b404a1748b15310b167396da01c7d\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[1]; packet 1 - 2\",\n\t\t\thexData:       \"cb00000001088ca3be26059ca269000044d088950f316207d551c91c88d791557c440a19184322536d2c900034358c1b3964f2d2935337b8d044d35bf62b4eea9ceaac64121aa634c7cd28630722d169fa0f215b940d47d7996ca56f0d463dbf97a4a1b5818c5297a26fe58f5553dfb513ad589750a61682f229996555c7121c8bf48b06b68ab06427b01af485d832f9894099a20d3baadcff7b1cf07e2c059d3e7ba88d4ad35ef0ffea1fdc6ac3db271dfcca892a41ab25284936225c9bc593ce242b11b8abed4a8df902987eef0c6d90669e3606f47dd6ad05f44ba3a0cd356854261bbb1e2d8f6b83cc57cfa57eda3e5d7181b6ec418f6eeca81c259a33e4b0a913de720f2f8782764766ac9602a7f52a1082ec3da30dbefcf38c781a3e033810c4f2babf9b72adf7164159d98142181492e4468c0e10ab29013bf238e7360e09767ca49d59a9eb18f06a372bad711fefa90295f8e0839b1080570648212b321e5bd6f614bf0d3dc2817628b0c052a32820c16cb7f531c49244c48eb1429625246f9c164ae4ee1e83eaa8ff0eef1acf5a3d8ca88f1e4597db5ba5c0cb23d6100dd53da4f439ae64c4d3d43d1fbb5677f4fdc3bd2c2948dfc7e0be1a33c842033da15529cfd3cae00da68343d835db867f746854804410ba68f0dd7711b0fe55817b83f6ce1a12ad38acf2a3156f819f0dc68ea799c05583d9728f2856577811b260dba40d6c5e82c9e558c5b8f3f4599caf05ea591118e0b80ad621e0a76e4926047593a896752cb168420cb1b02d4211de5e5b7c891f319b5c0cf687e1d261a01f2acbade6bd73cd1ade0a02e240e9351384e1a6868c21a4878f39f0fa94ee1e36c5a46449241a3fe0147ff50176787eca7f3a936c901aeef56770bff74feecb985e6670d20dfd8ed17952dca5a5292213345c61db09bb5bcf5bf74565f61f9dccab51a289c3160ffe4a9b29cc76ea46778d9317a890efea2ad905f4219463a3baca3c02f5c3682634be7c2e86e366272a8263fec8e871644a79299d4aa74f1b1414b2f963cce6e059978faf813625af7869c1dec92035478c0e46dc66d938d4131aca27a59b2103b8cefa8e08aeb44b53b205b932902aea8d519faaaa12e354a6f532b4f716d7929e655dc2e98b494a99153854af5732a2659f2c21e4069896a1835ad05c5e53781cab16599cf4af47c196deeff9115c80d13f93aeb28b08023e6a1d3cf7da2a4457a9e443176bcdfef8f8de630c02bd0efdc5ddda56ad8f6b47edbda6353205e6e655f690092a48deb7f8a5254a7d778e07216cd97dfefcf740c1acd2977ef0fa17f798ea9752bae46e3aa3ec9b13f4c95c20a7839b8409000fa1f17e8dc46cc05c41bff696ee03c0371cae8638e8018ff4ebedd9f27d56443e534a72dd3d18a64790b676ddd060376759fa4a12ffc17f4be83492126ec1dc0fcd4aefef73a0b9c443ec3532b9a66b1a60daacf45e6557115edc0cc4d08758754a44beffedaa0d1265e50beed1a01752904ee3f7e706ed290b1a79071b142105b7c02e692ff318710e3ce9c3b9ec557cdecef173796417341ada414faa06b52adf645db454b56468ccf0da50a942ebc09487797cb45a085ec1e2e06fcd1f5b72eac291955a62e5aa379a374aea3a0dec3e4e0ba1dde350a94c72dbea7505922e26e99d62f751c2b301413a73fb6b20a36052151473ebecd04d0a771ec326957bc28c2020fdf6f01d9abed69b3c3e73168b404a1748b15310b167396da01c7dc700000001088ca3be26059ca269000044d00a7e7a252620d0fdfb63c0c193d6a9fe6a36aa9ce1b29dfa5f11f2567850b88384a2cc682eca2e292749365b833e5f7540019cd4f3143ed078aec07990b0d6ece18310403e73e1fe2975a8f9cb05796fa6196faaba3ee12a22b63a28a624cf4f7bedd44de000dc5ea698c65664df995b7d5fade0aab1cf0ecc5afd5ecb8fb80deecae3a8c97c20171f00ac3b5dc9a9027ca9c25571c72bb32070f6e3fb583560b0da6041b72e0a9601b8ad17d3c45e9dcc059f9f4758e8c35a839a9f6f4c501cb64e32e886fc733bc51069fbe4406f04d908285974c387d5b3e5f0f674941d05993bf8bda0d5ffd8c4fb528e150ff4bf37e38bd9c6346816fe360d4a206da81e815c1f7905184b6146b33427c6e38f1179981c18b82a3544442dd997c182d956037ae8f106eaf67ba133e7f15f1550b257d431f01ba0472659c6a5c2e6ff5e4ce9e692f4ef9fb169a75df4eb13f0b20e1994f3f8687bdca300c7e749af7b7a3b6597a6b950fe378a68c77766fdabe95248ed41d37805756b7ffa9cee0898bd661f6657cbf1af9aa8c7e437d432ca854c95307e6a7dfb6504ee3f7852fb3c246d168a03810b6c3d4e3d40bdee3def579effb66563f5bac98cfa1b071cd6f33e425e016bb3514a183b72cb3a393e9e519ba60e2177c98f530835e3b6eab78cdcb8abdbc769bc07e10c8e38bea710d5de1bdb2fa8d0d9b19e8cc31d16725a696e55342c89b667497e3d7f90e48f8503d8ead2a32a1930c3b24a4a9dcf2d8ec781705dd97d7df6e26828712fe42114419d5b8346bd86c239bd02f34e55f71400cb10c1fac7d8efa1a2ab258c17ace4288c8576ab92447b648fd15f4e038ec1c81a135e3bbb6f581a994c6a4902aeb1b5588cb1b5b53c8540296d96b6d2eccd67bae9609233f36304b5186d4698b88bb3ce8b1191a62b990436cf10718fd5759cb2281ac122f49ccbef8a3206348c1a930e7fc4bb498a11d89374e1480c7b8725b5f65e8c8d6f58da17f9134abce77eb9a6fcda514e7d3ab2e3610f86945f0dca519a3844da1b3a4b0e03c80528a2f79be478d07ff26166e30294bf0e69bf07a5bbd6d879adf6d618a1ec8365023408980bf67f0525a2fdee97fccc38fe104d4f58ed15e3671dfedf684856a27fbe286adba40ff0336def93f0174e9e35d341f5de73190d330d72227db9a866b69418e17e8e19ec884c1ffe2f0ad6deec37c9d49d536d0242fab282b0cf86cc9b15341757e0d361bddcbe5cbb062b3148d7c3c62af5c5dd5922a49920f351647030f62ed16929a404aa514fcbc38e67ba4f275e02a04c486b1a8e5b5efda197fd63e6f41fdeffa652c690dd6b00ca65df3688672ead9744f7d631e42e3b42f3ed1bff51b30f89211a7467cde65eab3659af7690cf307420a5823f31999d8f63c6c6ba0296ed4a46d5df6404f8db33e7252cc6bfcf7f55fee1f1e3b0573b6c6615793ff0691b7cfd23c195f66eb333d7efb0cfb74cf159787f87ad01fc131c6763bb1117bbfb8c2e8197ffba6b8c747565b1332bdbd6553b840939c2f98aa8eb1c549491c640e012fc549852fa7a93f81e5db152c761fc7d01bce0325619965c09f6730a162e7be53af7d9ce4b5ac0f4eb487361d2ac231d4ce92e5d9a084bc7b609ccf60056ecc82cd0c06a088cfbcf7d764b3109331c42f989da82b05cfe4c134a6784e664fa67a89c0624e3cc73ccfdea3f292db28f7c7b1b109f680f6b537f135c62f764\",\n\t\t\tdomain:        \"dns.google\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[2]; packet 1\",\n\t\t\thexData:       \"cf0000000108452af27900a1723300404600ca8530029a6bc59ff3e85beb5fc838ac3147ba5c2f6421ddcffdd85167d8de70eff2b1fa016dad4918337dec0feb660edb98e078dea51fa914055984b7957bd732fa4c831e448967af34752fd95835e3caba1e022d6d164f3f53f1bd7f60d560a8684079e90626aa1a4d3fe728158f7e1055ff76d1566072113982b193fb932265381e4de7afb35caa4ec56f31595a33fa2eb0bc84feb9f273224050938825fd21aa7317042ad00785ffd36151aee566a5dfe17d72591af1235059171568e5af0d13fc56e7897c3d632be753d8dea184c3d96d92bc56978cc669d94dd4c5e8dc3dcba7f0a39368fb1e87981e54bba7b86fbd8e8023a94d84f0290f402a5244cb4b0eeaaa57610ea59711a43932c521f10edb4560375693cbea60240389b8cebfd94035cabe4fc96ce8a726b979775e06c3bb0e3c4c866fe82e89fb725499e711e39310b93c785b313459f22d4ba37f90b19447165c2584269d98bf47d1f7ca89585797e4d6f1a4a1db7d2b0ae91a93fb15c3bb0ab953c3656b3b2ca20833d15e95329baff6d2ade1b0921b5ed3ae96648bf123b5265e27b049e9a8674455ff5f763f039568026e4fbe9882fef761c573d8f12e342c274a8dd3ad9854a688ce57cdddb52c758161ae3a59f67fc0d5b85f12e27617e7f4366e97a61fcda084e620dde35686f01dac49ce4bd76b986e3223c215919a1b228beeb74b7fcf32827d55be8f1b3b5fed24df2db023faecbb313b18a151cc4af8199d4bb08f8127b8207a0286d52758eaca87fd476ece0e3b17bcd8afb0289e8fd33c4455d4db6f058826c301ea303bfe2c0a6651a8fb6a2e1897852d758076adb04ad907077c5d5f94089da78d8923a34f1022ed672f378fe0dd81a709b372c0a2042a42e683c051c653e42b43c4a0ea8e961074d2901d4157ac9878b13a207b05ec471cff10d922b74d05623513cd6a4ea192ad21d4089de269633d4d2d1388d98d7c8a9e29848d5558b8aa2b73b437446a640230e6adb7f4b317ee5d66681c4aae11f69b1e5f96cb32ca6331405426cb706167d86f6f8fd588a72d7b2a6906798b81f174d808e1e3fc461e598e797c41bced26b87d09282d7b6d95076c285462e0c420a6f0e171ffe2791b5d221c03520409fe36622ff77796d9b7ef82babb25313acda9c621b22bf45ed909f9365b508860645af4c3aca78e6abca2d3a65c9159fbcd577438505d3f65a57c9412c12c069ad4d6db450beb08603abef621a9e029593fb5881dbd524ea2953b4acaaf59269b584c754e88c033247bb7c032e548d34fd9b2678e62fdf953dabf2be21c3e2d7b18ec7e3aedaf2cd082e19a369c1bcd4ca67e3d464e2200ecc3df98b0aa7f349415d68bcab0441ac3366607eff024bb786aec031a4619f8a24f554fe93c8520a03affcf11e40b6d5002f98c1708cac6c56e77eccba85ea6600d1391cfd202cc7914bfbaa3303266d1a820bf2dc84d2dfcdc4cdb79e6de3fbe3c02b288dcf955652f674f3f59b50849ea7dbf755bdafa27fba3db1267fb1354d8bf25a60cacb900b4d7ba913f9ba5f6b00559ad58b2f34a658ff7ef7f7d1ceeffd9c8325f271e6b5ba44d89685b744306963aa5e05ac0e8b00ada772dd5ae5ffb7043109afea86593743564c7acb4c8e7ef0e57d081eb1b9c0916078b113ece8a6036264a9b9781183c035342d50c7b069f3a01a40230e37ed8efde073c07d0e68066541d78c2f3cbe1e603cfcaaa\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[2]; packet 1-2\",\n\t\t\thexData:       \"cf0000000108452af27900a1723300404600ca8530029a6bc59ff3e85beb5fc838ac3147ba5c2f6421ddcffdd85167d8de70eff2b1fa016dad4918337dec0feb660edb98e078dea51fa914055984b7957bd732fa4c831e448967af34752fd95835e3caba1e022d6d164f3f53f1bd7f60d560a8684079e90626aa1a4d3fe728158f7e1055ff76d1566072113982b193fb932265381e4de7afb35caa4ec56f31595a33fa2eb0bc84feb9f273224050938825fd21aa7317042ad00785ffd36151aee566a5dfe17d72591af1235059171568e5af0d13fc56e7897c3d632be753d8dea184c3d96d92bc56978cc669d94dd4c5e8dc3dcba7f0a39368fb1e87981e54bba7b86fbd8e8023a94d84f0290f402a5244cb4b0eeaaa57610ea59711a43932c521f10edb4560375693cbea60240389b8cebfd94035cabe4fc96ce8a726b979775e06c3bb0e3c4c866fe82e89fb725499e711e39310b93c785b313459f22d4ba37f90b19447165c2584269d98bf47d1f7ca89585797e4d6f1a4a1db7d2b0ae91a93fb15c3bb0ab953c3656b3b2ca20833d15e95329baff6d2ade1b0921b5ed3ae96648bf123b5265e27b049e9a8674455ff5f763f039568026e4fbe9882fef761c573d8f12e342c274a8dd3ad9854a688ce57cdddb52c758161ae3a59f67fc0d5b85f12e27617e7f4366e97a61fcda084e620dde35686f01dac49ce4bd76b986e3223c215919a1b228beeb74b7fcf32827d55be8f1b3b5fed24df2db023faecbb313b18a151cc4af8199d4bb08f8127b8207a0286d52758eaca87fd476ece0e3b17bcd8afb0289e8fd33c4455d4db6f058826c301ea303bfe2c0a6651a8fb6a2e1897852d758076adb04ad907077c5d5f94089da78d8923a34f1022ed672f378fe0dd81a709b372c0a2042a42e683c051c653e42b43c4a0ea8e961074d2901d4157ac9878b13a207b05ec471cff10d922b74d05623513cd6a4ea192ad21d4089de269633d4d2d1388d98d7c8a9e29848d5558b8aa2b73b437446a640230e6adb7f4b317ee5d66681c4aae11f69b1e5f96cb32ca6331405426cb706167d86f6f8fd588a72d7b2a6906798b81f174d808e1e3fc461e598e797c41bced26b87d09282d7b6d95076c285462e0c420a6f0e171ffe2791b5d221c03520409fe36622ff77796d9b7ef82babb25313acda9c621b22bf45ed909f9365b508860645af4c3aca78e6abca2d3a65c9159fbcd577438505d3f65a57c9412c12c069ad4d6db450beb08603abef621a9e029593fb5881dbd524ea2953b4acaaf59269b584c754e88c033247bb7c032e548d34fd9b2678e62fdf953dabf2be21c3e2d7b18ec7e3aedaf2cd082e19a369c1bcd4ca67e3d464e2200ecc3df98b0aa7f349415d68bcab0441ac3366607eff024bb786aec031a4619f8a24f554fe93c8520a03affcf11e40b6d5002f98c1708cac6c56e77eccba85ea6600d1391cfd202cc7914bfbaa3303266d1a820bf2dc84d2dfcdc4cdb79e6de3fbe3c02b288dcf955652f674f3f59b50849ea7dbf755bdafa27fba3db1267fb1354d8bf25a60cacb900b4d7ba913f9ba5f6b00559ad58b2f34a658ff7ef7f7d1ceeffd9c8325f271e6b5ba44d89685b744306963aa5e05ac0e8b00ada772dd5ae5ffb7043109afea86593743564c7acb4c8e7ef0e57d081eb1b9c0916078b113ece8a6036264a9b9781183c035342d50c7b069f3a01a40230e37ed8efde073c07d0e68066541d78c2f3cbe1e603cfcaaac40000000108452af27900a1723300404600ca8530029a6bc59ff3e85beb5fc838ac3147ba5c2f6421ddcffdd85167d8de70eff2b1fa016dad4918337dec0feb660edb98e078dea51fa914055984b7957bd732fa4c831e4489522d29bb5c84749f83c8e1edfd9da8d1738164a8a9c59e37a5c9994d90bb982dcfa69b20f868960dc139618f1adc2546d34340ae13d826260c54a456bbf7469ee37b1be1d7177004468d7e92cac62a0b165d6a114ad479861dd58959e094b5a6250359301d4a614d529660760e3d1cdec9bf444a3761309bab40e4a977bc749e0dae431952f5f7e6b1ebc1383d343359a387da4301f7fa4b400475e9b82367e56278376dd1c80349f083988945a13649008109cc12a3acf569ffcc5481fbcd86b544e7dc8434e9dd42bd8e5716a844d37879568db046857389d36cc7550c75f94e314db6749aa987f0fc730fae0fcf465d01c2fb745269dfc10132ddb5404dda2f9455780f5818730834aa9db4740793359884b9927b0bd1a5ca96052b4f17397d8b78aa891401bb8bed6726ea2229d919798c50e24d5f40576ac204847be9244aadbe5c773684c37475036541d209c177d4e9c22a1253292ce4ffb886b925b6cf83cc251976a68887eda2777590f51804b790b51eee77e717b7ef0eea71634594df36e6ae9e7574d65c51ac3196f0b2a3b0f023c81f05f7807f958dda03418ed49e14b645e814b9aa55b37c809be3172ca21fe4c7a78e17e9ece8def2dd2949310ecaa41b1b477f4e85db5288aa144e333f47ef291d0e822941181c13859d9fd6d640904ee764c9276125228c932dff3fb12f564f039b52f5ba1ab4d119641df8fe13f784802b99347f0046da63f471e34b1d12d3111cffe7b5d90cf5999879f6f23e7785f09cb10df32821bb68dd8fdcfcdbedd63f2428b2292b9f0e76ff36403c9644fd43e01112ee6218d0ec1c86f6d147e4b802293e906750c7046f53bf05a144e321d3b45e08e4064fd3828fdd1b5d1ceed74081f61319dc0ad9a6e8a3b9cc802e952d24e2271712e2c2cda7daca2f835e6c804feeef8d918404cc82a1aa9534bddff68a472b208a0d0a7fd68a08fbc411132af47a6b67a32617b7b9991524c21599e8e3cb9395cdab87a3f5bf5d1833a9c7ea021b29cf428c877c6b21d62f99340ac7f85ae721acc10968e7d79f111ca40c75e14060d07cffa046d71151a0b00eab657300344b04bd1a8871650c34ceda8610d7c1ba8d37673da6aaa580400e0230c69fba8ba21927de2f5897656144694550d1df3d268804adc707e7b236501734aeabb2e61cb08012bd96eca5a486d7a55f996992c36233815abd71c30e263ba0c5d9456fe0828df16f6af7929390bb143c426d9dfeaf4bb373554479ebe609b36b4bc3dd08ce216b9cdc5726edb458c5e4036d0edc688d3e39d20f8254b5d1f174518f15b344efc27fc56572c0159aa593d5b46bc33818f986e3df8caebd4c7b702ef50dd582714a2b94ecd1c4e90af37d388445c478a32ff6e8f5852ee115966b708eed04da322b98813a69423e95f90b89ce85518e39bcef36fdd5bd312b2c6c5ee85962675274c18f39ee35155517f70fd74b31bb2de6b5108d369252e6fb289e453833132ef7960da1cc0934790c039b9a1b0c74f23eb3b61fe9b4d0ea67de757b93af451eef303b1373199af446a0fa98d5991bbd4771ee63317e6da86efbe213dfff595c41b98e0e89f4f2df110104e760feebf4cb3361171c9fceb1e1c809a268\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[2]; packet 1-3\",\n\t\t\thexData:       \"cf0000000108452af27900a1723300404600ca8530029a6bc59ff3e85beb5fc838ac3147ba5c2f6421ddcffdd85167d8de70eff2b1fa016dad4918337dec0feb660edb98e078dea51fa914055984b7957bd732fa4c831e448967af34752fd95835e3caba1e022d6d164f3f53f1bd7f60d560a8684079e90626aa1a4d3fe728158f7e1055ff76d1566072113982b193fb932265381e4de7afb35caa4ec56f31595a33fa2eb0bc84feb9f273224050938825fd21aa7317042ad00785ffd36151aee566a5dfe17d72591af1235059171568e5af0d13fc56e7897c3d632be753d8dea184c3d96d92bc56978cc669d94dd4c5e8dc3dcba7f0a39368fb1e87981e54bba7b86fbd8e8023a94d84f0290f402a5244cb4b0eeaaa57610ea59711a43932c521f10edb4560375693cbea60240389b8cebfd94035cabe4fc96ce8a726b979775e06c3bb0e3c4c866fe82e89fb725499e711e39310b93c785b313459f22d4ba37f90b19447165c2584269d98bf47d1f7ca89585797e4d6f1a4a1db7d2b0ae91a93fb15c3bb0ab953c3656b3b2ca20833d15e95329baff6d2ade1b0921b5ed3ae96648bf123b5265e27b049e9a8674455ff5f763f039568026e4fbe9882fef761c573d8f12e342c274a8dd3ad9854a688ce57cdddb52c758161ae3a59f67fc0d5b85f12e27617e7f4366e97a61fcda084e620dde35686f01dac49ce4bd76b986e3223c215919a1b228beeb74b7fcf32827d55be8f1b3b5fed24df2db023faecbb313b18a151cc4af8199d4bb08f8127b8207a0286d52758eaca87fd476ece0e3b17bcd8afb0289e8fd33c4455d4db6f058826c301ea303bfe2c0a6651a8fb6a2e1897852d758076adb04ad907077c5d5f94089da78d8923a34f1022ed672f378fe0dd81a709b372c0a2042a42e683c051c653e42b43c4a0ea8e961074d2901d4157ac9878b13a207b05ec471cff10d922b74d05623513cd6a4ea192ad21d4089de269633d4d2d1388d98d7c8a9e29848d5558b8aa2b73b437446a640230e6adb7f4b317ee5d66681c4aae11f69b1e5f96cb32ca6331405426cb706167d86f6f8fd588a72d7b2a6906798b81f174d808e1e3fc461e598e797c41bced26b87d09282d7b6d95076c285462e0c420a6f0e171ffe2791b5d221c03520409fe36622ff77796d9b7ef82babb25313acda9c621b22bf45ed909f9365b508860645af4c3aca78e6abca2d3a65c9159fbcd577438505d3f65a57c9412c12c069ad4d6db450beb08603abef621a9e029593fb5881dbd524ea2953b4acaaf59269b584c754e88c033247bb7c032e548d34fd9b2678e62fdf953dabf2be21c3e2d7b18ec7e3aedaf2cd082e19a369c1bcd4ca67e3d464e2200ecc3df98b0aa7f349415d68bcab0441ac3366607eff024bb786aec031a4619f8a24f554fe93c8520a03affcf11e40b6d5002f98c1708cac6c56e77eccba85ea6600d1391cfd202cc7914bfbaa3303266d1a820bf2dc84d2dfcdc4cdb79e6de3fbe3c02b288dcf955652f674f3f59b50849ea7dbf755bdafa27fba3db1267fb1354d8bf25a60cacb900b4d7ba913f9ba5f6b00559ad58b2f34a658ff7ef7f7d1ceeffd9c8325f271e6b5ba44d89685b744306963aa5e05ac0e8b00ada772dd5ae5ffb7043109afea86593743564c7acb4c8e7ef0e57d081eb1b9c0916078b113ece8a6036264a9b9781183c035342d50c7b069f3a01a40230e37ed8efde073c07d0e68066541d78c2f3cbe1e603cfcaaac40000000108452af27900a1723300404600ca8530029a6bc59ff3e85beb5fc838ac3147ba5c2f6421ddcffdd85167d8de70eff2b1fa016dad4918337dec0feb660edb98e078dea51fa914055984b7957bd732fa4c831e4489522d29bb5c84749f83c8e1edfd9da8d1738164a8a9c59e37a5c9994d90bb982dcfa69b20f868960dc139618f1adc2546d34340ae13d826260c54a456bbf7469ee37b1be1d7177004468d7e92cac62a0b165d6a114ad479861dd58959e094b5a6250359301d4a614d529660760e3d1cdec9bf444a3761309bab40e4a977bc749e0dae431952f5f7e6b1ebc1383d343359a387da4301f7fa4b400475e9b82367e56278376dd1c80349f083988945a13649008109cc12a3acf569ffcc5481fbcd86b544e7dc8434e9dd42bd8e5716a844d37879568db046857389d36cc7550c75f94e314db6749aa987f0fc730fae0fcf465d01c2fb745269dfc10132ddb5404dda2f9455780f5818730834aa9db4740793359884b9927b0bd1a5ca96052b4f17397d8b78aa891401bb8bed6726ea2229d919798c50e24d5f40576ac204847be9244aadbe5c773684c37475036541d209c177d4e9c22a1253292ce4ffb886b925b6cf83cc251976a68887eda2777590f51804b790b51eee77e717b7ef0eea71634594df36e6ae9e7574d65c51ac3196f0b2a3b0f023c81f05f7807f958dda03418ed49e14b645e814b9aa55b37c809be3172ca21fe4c7a78e17e9ece8def2dd2949310ecaa41b1b477f4e85db5288aa144e333f47ef291d0e822941181c13859d9fd6d640904ee764c9276125228c932dff3fb12f564f039b52f5ba1ab4d119641df8fe13f784802b99347f0046da63f471e34b1d12d3111cffe7b5d90cf5999879f6f23e7785f09cb10df32821bb68dd8fdcfcdbedd63f2428b2292b9f0e76ff36403c9644fd43e01112ee6218d0ec1c86f6d147e4b802293e906750c7046f53bf05a144e321d3b45e08e4064fd3828fdd1b5d1ceed74081f61319dc0ad9a6e8a3b9cc802e952d24e2271712e2c2cda7daca2f835e6c804feeef8d918404cc82a1aa9534bddff68a472b208a0d0a7fd68a08fbc411132af47a6b67a32617b7b9991524c21599e8e3cb9395cdab87a3f5bf5d1833a9c7ea021b29cf428c877c6b21d62f99340ac7f85ae721acc10968e7d79f111ca40c75e14060d07cffa046d71151a0b00eab657300344b04bd1a8871650c34ceda8610d7c1ba8d37673da6aaa580400e0230c69fba8ba21927de2f5897656144694550d1df3d268804adc707e7b236501734aeabb2e61cb08012bd96eca5a486d7a55f996992c36233815abd71c30e263ba0c5d9456fe0828df16f6af7929390bb143c426d9dfeaf4bb373554479ebe609b36b4bc3dd08ce216b9cdc5726edb458c5e4036d0edc688d3e39d20f8254b5d1f174518f15b344efc27fc56572c0159aa593d5b46bc33818f986e3df8caebd4c7b702ef50dd582714a2b94ecd1c4e90af37d388445c478a32ff6e8f5852ee115966b708eed04da322b98813a69423e95f90b89ce85518e39bcef36fdd5bd312b2c6c5ee85962675274c18f39ee35155517f70fd74b31bb2de6b5108d369252e6fb289e453833132ef7960da1cc0934790c039b9a1b0c74f23eb3b61fe9b4d0ea67de757b93af451eef303b1373199af446a0fa98d5991bbd4771ee63317e6da86efbe213dfff595c41b98e0e89f4f2df110104e760feebf4cb3361171c9fceb1e1c809a268c60000000108452af27900a1723300404600ca8530029a6bc59ff3e85beb5fc838ac3147ba5c2f6421ddcffdd85167d8de70eff2b1fa016dad4918337dec0feb660edb98e078dea51fa914055984b7957bd732fa4c831e44892ff5e6b16d8a259a9128c2c0c3c525462781a344c3df7f19a747e0e79ca8714995c867fc697a3cb87b35e769465a8e966bcb35b7e897ad036aa23a6c021e2445a0eb79962151cd20dbb43ae1231847de01caf4e5589dfebf026e95f7d1d742e140d9dda849396a70cc0798f1eef06fd5f4cfbc9a190ddf04cc332c5b7b15e53af311190ced92a1291c12b8799f2b50e076539a8370ee667e1791a78f38e565a48acbaa1c78ba941dba8b0d040f8fb8bbcc9f6bf5705efa613a24b12d6ac9cebb4f3fac1b09a07b49d8a3a62808eb0a324629f13a012e6ad0feb11ad97c1572983c713b62f27584809ba43e64e4af9845af807c0783104838f4e2ac33fa848866f3cc64a7b6203a5c09e8ad231f0f06ae2fb7b39a64cedd823b0ff297ad9be1ccac436777ccb3e22ef6b9c12e6d5e34926f50e8ca8c8c0532c810b074d001c11791a01bf25786b57a5da54065dcee4962822e929f47ee44d3b8c83d45a8b7a936dc2a6fa396e4194fa032d1627eca59f69857fc40dab5835d3613dade1c74b09c345bd32c509e9545d2330b157a7acb76409f3ac8eaa22802414f38c5422fe4c5189caaf5c1b93ce7c0892f0cfc477490d335aa78961d632a973cf106bd974c2714176fb0f98cf12f2887a0d7bd491756dd374331eb3e6adb9f2bd0d6b273403fd14b314eb27ebbb6f6e78ce310437004b757c048149cf04429ae4a6d6e65c9b3e0b9c9c4d4ef52007eaaad9670320f10cd5317b3d3edc374d45c98b217dd28fb3c2c2fb6e74a3aced143e3242084b192ba6df24e69fdb883e850714fe27a45f43883486a986574fd1fc10f259fe90786441554514c8dade1f3b86fdaf5f54ab655e2d803c98aa56073b00c32148a1ed367dff3a2bd934ecba55141389990b661bbd9ce1ef1def13747d45500daf92cec9e60908274703e761cd46affd46622f2a2192a79425ebf51c875fc7ba3598e15e0ba2465fc3e87c8a5da1915d3b8abe4b16d21259f311183eee1e7d2b808a91a7c89b284df0eb6a2a79c610bbe47722b3e04d5a6c0e574816a94d97349b6976010eb8c7debf42210982f78de482b7cd068051bf57908dbf46b5ceaf64f5fb33ede4412c1ce81eb1dfb4e99e10dd9b57ebc6e62ecbf4ee2db04d9e48c62bd45f8fa51704d414296a2d51d25ced6a192034a44c67e09d8985b573f98e03fa36dd8dcce2c04b4d5b1f276b6a642aadbdcafcf09de1d234bf8bbbf64aeadf01519ddafb419b3e62d204e04c3d7ebaf54b09e387ac3e9c4781c11625a2f44fddb7a1886f21929bd01c283f64903b6ccbb463984dfadc00f6af2a421517da023fd319f528195cac5fe907624b70c0172479d07d78e266dbf20ab8fc302228f279ffdba7395a839c4a9d7a4e001a260e1702393968f1e9722f023b204cf09cfee9a7bba045e4a2a449ee9fbb5c36e93028cfc87a2e34914b1b4f01beeded175ac0fa73fea9292f2bc3b1247164d8e05cddc3981bdc24e5f596571c418f6fa00fd9d4d0898cbf0d2f5413bed5f100f1854903017b6bc88bd7e303b5e0e2417bbcc984731128eda550d31f9af0e6e743eb6916466bbd435617d56fa60b05cd7dca66a9f6f4be23d3c5ff5d900822c6d1d8d71b0bab24f57d9682381a87c\",\n\t\t\tdomain:        \"signaler-pa.clients6.google.com\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[3]; packet 1\",\n\t\t\thexData:       \"cb0000000108676ef9ec3514fd5f004046001ae0c831dde6ac72f1337c9ca111f5b32afdf102d75c017d3bccb6fa89902b750b00c51bb226afa517754b72e962ff007c1c8c8749a21be1d8d94f7bf73437c010cd60e0bd4489d0a84868f32ecd4bd0d4c95a8a08d60d8303ef02323bdbcd96a33940824d25b9594bd8ae5716b9d043ab27ba03a2593c4d149b923711dd98e45456db19c8ea71e982562ae787c1b6cbe3ca1b03df2df62aa8e3127c5f68bdf80ed90588e7ec1f41f5a6281b87a12348cb17a04e9eaa461fef2e0e3ae70ebdc7bffa15c6b61ab270173e46dec0fd081f935a5fe6338d3b9cd38fcb52cb159edb66d2927238294313990da25c22f40d40e3cd72e76bbd066de731cf8fb6b4b7bc7639efb788c0b108dbf8280845a2cc62fbaf5fb8e1ecbe5ba7791aab94786c1c71c9058d0153b34a3f5bc8903e0d120f353defbe973cd33568bd03609dcdab8af1e8563897f5dd0251c6e6514bf40bd447d376fed21b2c54ebf74680df241bdc2ea5579bc0736cf3257c20d275746e8e6853aa89dcda8c2dbe523438ab92ca1ed1ab4f109e4ea84de57dfb6c544d695a5b710fe2d432f2b58644f8aeb965752d3a1d1a3057c2229192f89b254f5d292c22f1060642729df3667ef39e27691c82da9be847a59a17ba7345d23a37e31ec135633cc5ea84c752f56d4ec75878a2920b93e9b4e091e0114552712e1e50ade42e26ac0266b84043a493e1ce2e80cd57422de16a88deceaa55385dc2a977ffc9063e7c427200b6d8511ef9004f89412587bd6d0057898f5ae284db78b0ec861fed36dfb7c7a9679ad0480eefe71985ba6f731bd0e816a901e0c017dd0cb7fc8a4606dec2091a51aab16d6f9bbdecf3fea177671e68250a84fe19de8df78d711e22b81372bc22ae21ac7208ed41201f6e26cd6748e9d6e2f4884f5acba736b2432536718891638d43991bd97c232829e26be6e6bb303d44849b245ef758eb2813bc87cf21a30f132360111e3015de5d1e4f0c5a98aff159c29f6debed7c2f18f455dfc7f33995a90b7625688507ecef1e7db48e7030ea6c4fa835bbc1dfbea6c0a6c704d658d4866a42b9860b1c8b5b64cb669e102c81e369b5f07b8fa08816a566a99f4d2910f6e8d751d52f1e2889f0ec9acfcb4627e0da5c35452be05c7766eddf3c42ceb6a312044075a4231b4203718c886498a313f3ba12e44e368b04ec3ea6e72d6fed9b6b334cbc0ba89f0aa9a129b1bad5b0ad8690291a344967f58e52415859852c6ca3ea24bc93ec1041fd1dc8a6a181326d3026098db0cddec90b3cd6df1e7638a3703f70c9a3baff8f005b90f362459a275a8b39daa78ff24613434594f96b8023a41a17d815e5c0319a39e07d32841339f14f404030b4a22551b86ba94832a1c49053d63140b503f2f64354ce10abe6c08f6cdaf6d8dc361c3c9d1a8077ad34dccc699b6fe07c16f8f7743d04003d672f82e643b3f1d5e263495504e11e6b2e676c11b3d0033d5f837e6bfd01602584ff181e3cb86f081015a9311eed546b42a8280680aa538353949f89674c554b43241e36536430ae9e0190729ce902e8f06a952d23b62816deb3b62b45375033ede2d8065a8e7b38f5aee0a5c66eb2f21f33fa6795d4b086e6f6ac941ba0c883ccf6e54e52164384045e0b0d74a9361f224303c841ec907be250725ab06cf79dd8bff8f46c08963a409b9b71b5c634c987c5e163f73fc32553be1231c72444c5e2a91189824034a784948f\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[3]; packet 1-2\",\n\t\t\thexData:       \"cb0000000108676ef9ec3514fd5f004046001ae0c831dde6ac72f1337c9ca111f5b32afdf102d75c017d3bccb6fa89902b750b00c51bb226afa517754b72e962ff007c1c8c8749a21be1d8d94f7bf73437c010cd60e0bd4489d0a84868f32ecd4bd0d4c95a8a08d60d8303ef02323bdbcd96a33940824d25b9594bd8ae5716b9d043ab27ba03a2593c4d149b923711dd98e45456db19c8ea71e982562ae787c1b6cbe3ca1b03df2df62aa8e3127c5f68bdf80ed90588e7ec1f41f5a6281b87a12348cb17a04e9eaa461fef2e0e3ae70ebdc7bffa15c6b61ab270173e46dec0fd081f935a5fe6338d3b9cd38fcb52cb159edb66d2927238294313990da25c22f40d40e3cd72e76bbd066de731cf8fb6b4b7bc7639efb788c0b108dbf8280845a2cc62fbaf5fb8e1ecbe5ba7791aab94786c1c71c9058d0153b34a3f5bc8903e0d120f353defbe973cd33568bd03609dcdab8af1e8563897f5dd0251c6e6514bf40bd447d376fed21b2c54ebf74680df241bdc2ea5579bc0736cf3257c20d275746e8e6853aa89dcda8c2dbe523438ab92ca1ed1ab4f109e4ea84de57dfb6c544d695a5b710fe2d432f2b58644f8aeb965752d3a1d1a3057c2229192f89b254f5d292c22f1060642729df3667ef39e27691c82da9be847a59a17ba7345d23a37e31ec135633cc5ea84c752f56d4ec75878a2920b93e9b4e091e0114552712e1e50ade42e26ac0266b84043a493e1ce2e80cd57422de16a88deceaa55385dc2a977ffc9063e7c427200b6d8511ef9004f89412587bd6d0057898f5ae284db78b0ec861fed36dfb7c7a9679ad0480eefe71985ba6f731bd0e816a901e0c017dd0cb7fc8a4606dec2091a51aab16d6f9bbdecf3fea177671e68250a84fe19de8df78d711e22b81372bc22ae21ac7208ed41201f6e26cd6748e9d6e2f4884f5acba736b2432536718891638d43991bd97c232829e26be6e6bb303d44849b245ef758eb2813bc87cf21a30f132360111e3015de5d1e4f0c5a98aff159c29f6debed7c2f18f455dfc7f33995a90b7625688507ecef1e7db48e7030ea6c4fa835bbc1dfbea6c0a6c704d658d4866a42b9860b1c8b5b64cb669e102c81e369b5f07b8fa08816a566a99f4d2910f6e8d751d52f1e2889f0ec9acfcb4627e0da5c35452be05c7766eddf3c42ceb6a312044075a4231b4203718c886498a313f3ba12e44e368b04ec3ea6e72d6fed9b6b334cbc0ba89f0aa9a129b1bad5b0ad8690291a344967f58e52415859852c6ca3ea24bc93ec1041fd1dc8a6a181326d3026098db0cddec90b3cd6df1e7638a3703f70c9a3baff8f005b90f362459a275a8b39daa78ff24613434594f96b8023a41a17d815e5c0319a39e07d32841339f14f404030b4a22551b86ba94832a1c49053d63140b503f2f64354ce10abe6c08f6cdaf6d8dc361c3c9d1a8077ad34dccc699b6fe07c16f8f7743d04003d672f82e643b3f1d5e263495504e11e6b2e676c11b3d0033d5f837e6bfd01602584ff181e3cb86f081015a9311eed546b42a8280680aa538353949f89674c554b43241e36536430ae9e0190729ce902e8f06a952d23b62816deb3b62b45375033ede2d8065a8e7b38f5aee0a5c66eb2f21f33fa6795d4b086e6f6ac941ba0c883ccf6e54e52164384045e0b0d74a9361f224303c841ec907be250725ab06cf79dd8bff8f46c08963a409b9b71b5c634c987c5e163f73fc32553be1231c72444c5e2a91189824034a784948fc90000000108676ef9ec3514fd5f004046001ae0c831dde6ac72f1337c9ca111f5b32afdf102d75c017d3bccb6fa89902b750b00c51bb226afa517754b72e962ff007c1c8c8749a21be1d8d94f7bf73437c010cd60e0bd448983eee52163a177650f57b2cd8404bc619b9b59e796f9808bcd549ae6ae30d448c90f2783978bf9314a8038f45c0da5983163bd26f38f559f59447e8cf004f93b6b5c8af7b09603db021d4bdfa641bd83926eae1709a7a427add14df90cb258c6d4663d4d29709da89c90613d2ff9334637d53ca89407804eb863f78e110b866af2734c980705d9f969730a41132e788fc9e426d0f68ed24157aaff0383438d2715262e9b8b03cff850ba88127a05a8b68ac9a5ae5b098bb9ba5eaadd71ae846b3c0f68db728361eb8c8ed899c77725afbdfabf93812c49cbf4ee64047a96ea71258dbe5be3f988029d005fa2d9fc6e1e53fbeb6888074521b972e2ac71b4f22b754fc743e0de21af1e2ab416b2481e03227a1c7d7ea6cac5bc37ee3597d3bf11bf13a688dfa3d9aeff1eb1a7fdfcf8b6c722a4853f7c2b2d31e0b2b691f4273d4793fbb7a00f27a25577bfcba95e60699c9d2a926e71d64f535b633f2fd03320b28fe86c6619c54b34e6caf8f5a71b8a144c9236bf07edaacb486ff8ac63173af099efe7c9d006a5bb756449fb32b1fbff2e315fd5e96b586bb922a9795e29ffe6ead037c556e1bf30e24afb344cf873201007096b6f687f157588e236b71ade4d9245d8f065f2e23b36fad798d0f5504ddf25b828698d0cbdc28478b20d692d2ab605797a67232b0795927d886de798f00b4e7c69517d62b748e62e01d53dd1e77ac9a1605c0408713ff309ad53ff8f2bef17f9074f01134374068bf1f5dc07125180b5ea6902ec2d55c7d6d5f7ed4ef8732f9d34b4627678611fc9579e4321cea012c4e457dee6a11c41bdd1eb965056e885757af389079a558434eb3d59ae56a232302759431172ecc88de1c5400265f0f47e21396e3c38e0ba022c3e55ee4b85527cf49dece94445adc740cd26c18004a1cb984cc1732a138844da1ab003f89c589b6f3cc10c99a1b0d87be763f83e1b12c6fa6938ebc55d2ba33c25ca816dde207f7186f0c70b56b33feb538eb31175fdcfb036e365087f1b630628affdbbdee20d1976cb009f32db5f35aadb8117aa02ff2da9bdeaffbcc8bf3412efefeb00365e5f1ea577afd6e1c3585c67ffe1fa120382aa54028dcae9bbd624432a6256687d05483f2611f1ddd14b40f66fdf547e7eba904a79bd27733c9a8fbfb01154dda3457c4eacff8116941777ec570ff040e217d648ea5076588a6417462481eba68ebc59af04ba49b92f70b68a007977fde48b94b0af35475ea19cbec92df6449b065880bf03452cb3b3582f3d1a010e585be6506f3e067226471a94ce46c515f20502b3866553c10f037d9be89ad5858d6b2d2d94c70159247f66958d0e841d1c5b4254809d52475fdf96d087c3c6647b86006147a9ebb3f52ea6f4b89d886725b9e9243efd95e434bd8dd785143c57c06863b68df8f832987eb0c730c8b96634c1f888da2ef420cb0ebacf81f4b25c65962ae40c09ac4b0b2d440e3bdaa7309d87a1fa6af1c2e13e7a63c253fae027ceb2067cef8421b62d205f5d37c7204eaf594b1b43f9d9b67509a6709df48769ab9e1078f9e59d7656ec2132b5ebccf297e757a052835fffe94ae073131ac49c4f4374a1904cd4bf3041b236b73ea19eaa583db577fe35\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[3]; packet 1-3\",\n\t\t\thexData:       \"cb0000000108676ef9ec3514fd5f004046001ae0c831dde6ac72f1337c9ca111f5b32afdf102d75c017d3bccb6fa89902b750b00c51bb226afa517754b72e962ff007c1c8c8749a21be1d8d94f7bf73437c010cd60e0bd4489d0a84868f32ecd4bd0d4c95a8a08d60d8303ef02323bdbcd96a33940824d25b9594bd8ae5716b9d043ab27ba03a2593c4d149b923711dd98e45456db19c8ea71e982562ae787c1b6cbe3ca1b03df2df62aa8e3127c5f68bdf80ed90588e7ec1f41f5a6281b87a12348cb17a04e9eaa461fef2e0e3ae70ebdc7bffa15c6b61ab270173e46dec0fd081f935a5fe6338d3b9cd38fcb52cb159edb66d2927238294313990da25c22f40d40e3cd72e76bbd066de731cf8fb6b4b7bc7639efb788c0b108dbf8280845a2cc62fbaf5fb8e1ecbe5ba7791aab94786c1c71c9058d0153b34a3f5bc8903e0d120f353defbe973cd33568bd03609dcdab8af1e8563897f5dd0251c6e6514bf40bd447d376fed21b2c54ebf74680df241bdc2ea5579bc0736cf3257c20d275746e8e6853aa89dcda8c2dbe523438ab92ca1ed1ab4f109e4ea84de57dfb6c544d695a5b710fe2d432f2b58644f8aeb965752d3a1d1a3057c2229192f89b254f5d292c22f1060642729df3667ef39e27691c82da9be847a59a17ba7345d23a37e31ec135633cc5ea84c752f56d4ec75878a2920b93e9b4e091e0114552712e1e50ade42e26ac0266b84043a493e1ce2e80cd57422de16a88deceaa55385dc2a977ffc9063e7c427200b6d8511ef9004f89412587bd6d0057898f5ae284db78b0ec861fed36dfb7c7a9679ad0480eefe71985ba6f731bd0e816a901e0c017dd0cb7fc8a4606dec2091a51aab16d6f9bbdecf3fea177671e68250a84fe19de8df78d711e22b81372bc22ae21ac7208ed41201f6e26cd6748e9d6e2f4884f5acba736b2432536718891638d43991bd97c232829e26be6e6bb303d44849b245ef758eb2813bc87cf21a30f132360111e3015de5d1e4f0c5a98aff159c29f6debed7c2f18f455dfc7f33995a90b7625688507ecef1e7db48e7030ea6c4fa835bbc1dfbea6c0a6c704d658d4866a42b9860b1c8b5b64cb669e102c81e369b5f07b8fa08816a566a99f4d2910f6e8d751d52f1e2889f0ec9acfcb4627e0da5c35452be05c7766eddf3c42ceb6a312044075a4231b4203718c886498a313f3ba12e44e368b04ec3ea6e72d6fed9b6b334cbc0ba89f0aa9a129b1bad5b0ad8690291a344967f58e52415859852c6ca3ea24bc93ec1041fd1dc8a6a181326d3026098db0cddec90b3cd6df1e7638a3703f70c9a3baff8f005b90f362459a275a8b39daa78ff24613434594f96b8023a41a17d815e5c0319a39e07d32841339f14f404030b4a22551b86ba94832a1c49053d63140b503f2f64354ce10abe6c08f6cdaf6d8dc361c3c9d1a8077ad34dccc699b6fe07c16f8f7743d04003d672f82e643b3f1d5e263495504e11e6b2e676c11b3d0033d5f837e6bfd01602584ff181e3cb86f081015a9311eed546b42a8280680aa538353949f89674c554b43241e36536430ae9e0190729ce902e8f06a952d23b62816deb3b62b45375033ede2d8065a8e7b38f5aee0a5c66eb2f21f33fa6795d4b086e6f6ac941ba0c883ccf6e54e52164384045e0b0d74a9361f224303c841ec907be250725ab06cf79dd8bff8f46c08963a409b9b71b5c634c987c5e163f73fc32553be1231c72444c5e2a91189824034a784948fc90000000108676ef9ec3514fd5f004046001ae0c831dde6ac72f1337c9ca111f5b32afdf102d75c017d3bccb6fa89902b750b00c51bb226afa517754b72e962ff007c1c8c8749a21be1d8d94f7bf73437c010cd60e0bd448983eee52163a177650f57b2cd8404bc619b9b59e796f9808bcd549ae6ae30d448c90f2783978bf9314a8038f45c0da5983163bd26f38f559f59447e8cf004f93b6b5c8af7b09603db021d4bdfa641bd83926eae1709a7a427add14df90cb258c6d4663d4d29709da89c90613d2ff9334637d53ca89407804eb863f78e110b866af2734c980705d9f969730a41132e788fc9e426d0f68ed24157aaff0383438d2715262e9b8b03cff850ba88127a05a8b68ac9a5ae5b098bb9ba5eaadd71ae846b3c0f68db728361eb8c8ed899c77725afbdfabf93812c49cbf4ee64047a96ea71258dbe5be3f988029d005fa2d9fc6e1e53fbeb6888074521b972e2ac71b4f22b754fc743e0de21af1e2ab416b2481e03227a1c7d7ea6cac5bc37ee3597d3bf11bf13a688dfa3d9aeff1eb1a7fdfcf8b6c722a4853f7c2b2d31e0b2b691f4273d4793fbb7a00f27a25577bfcba95e60699c9d2a926e71d64f535b633f2fd03320b28fe86c6619c54b34e6caf8f5a71b8a144c9236bf07edaacb486ff8ac63173af099efe7c9d006a5bb756449fb32b1fbff2e315fd5e96b586bb922a9795e29ffe6ead037c556e1bf30e24afb344cf873201007096b6f687f157588e236b71ade4d9245d8f065f2e23b36fad798d0f5504ddf25b828698d0cbdc28478b20d692d2ab605797a67232b0795927d886de798f00b4e7c69517d62b748e62e01d53dd1e77ac9a1605c0408713ff309ad53ff8f2bef17f9074f01134374068bf1f5dc07125180b5ea6902ec2d55c7d6d5f7ed4ef8732f9d34b4627678611fc9579e4321cea012c4e457dee6a11c41bdd1eb965056e885757af389079a558434eb3d59ae56a232302759431172ecc88de1c5400265f0f47e21396e3c38e0ba022c3e55ee4b85527cf49dece94445adc740cd26c18004a1cb984cc1732a138844da1ab003f89c589b6f3cc10c99a1b0d87be763f83e1b12c6fa6938ebc55d2ba33c25ca816dde207f7186f0c70b56b33feb538eb31175fdcfb036e365087f1b630628affdbbdee20d1976cb009f32db5f35aadb8117aa02ff2da9bdeaffbcc8bf3412efefeb00365e5f1ea577afd6e1c3585c67ffe1fa120382aa54028dcae9bbd624432a6256687d05483f2611f1ddd14b40f66fdf547e7eba904a79bd27733c9a8fbfb01154dda3457c4eacff8116941777ec570ff040e217d648ea5076588a6417462481eba68ebc59af04ba49b92f70b68a007977fde48b94b0af35475ea19cbec92df6449b065880bf03452cb3b3582f3d1a010e585be6506f3e067226471a94ce46c515f20502b3866553c10f037d9be89ad5858d6b2d2d94c70159247f66958d0e841d1c5b4254809d52475fdf96d087c3c6647b86006147a9ebb3f52ea6f4b89d886725b9e9243efd95e434bd8dd785143c57c06863b68df8f832987eb0c730c8b96634c1f888da2ef420cb0ebacf81f4b25c65962ae40c09ac4b0b2d440e3bdaa7309d87a1fa6af1c2e13e7a63c253fae027ceb2067cef8421b62d205f5d37c7204eaf594b1b43f9d9b67509a6709df48769ab9e1078f9e59d7656ec2132b5ebccf297e757a052835fffe94ae073131ac49c4f4374a1904cd4bf3041b236b73ea19eaa583db577fe35ca0000000108676ef9ec3514fd5f004046001ae0c831dde6ac72f1337c9ca111f5b32afdf102d75c017d3bccb6fa89902b750b00c51bb226afa517754b72e962ff007c1c8c8749a21be1d8d94f7bf73437c010cd60e0bd4489ea77dbb530c7ba127c66c3d7bbc00c336fd4e09e1775c646dffaa8696f7b8b00bf91261fc5164d57a4b9652b7cff4e301d32224b4e48cbfca535b2070ac46181615358d87e244ba6e369f6719bd5a551ac05dc78c222fd0969d0d943cbfaa3570ec25ab2768e9679d1cd1a3528659d010c409a0719526c44e4d9915dc5b0618ebc9e35f06b31bfd8e01fad99dabe32f6bfa00b3a5db5a01920d6685c34efb958729ffc5acfe46b3605715149b65b2f638007885a0866bbdde6765992b9acce2f527de906443f8643845489f1224fd3bbbb3fa78ca4848fe0167ec7cff8a05a17eb7c7a05a80c3106647e5d9aae350f33d10f3a60ab1c705858323a8f610d98cc68ef3cea66eedbb788b9a3da873bfd44ed632aa952ed7bb2004f4502260cef0596ec6e82e7683bdd2cb1f63b01b3f928ffa86b89cbeee922f1fd192fea0bdd17cf62d14f06f9e27bf5cafec90ab26f103e1dcb96ae4335e444b1fbad294cc395c5dc3a1c0c1fb4078d362eb229c42bc42ff53115c51f137d75596b3e6d3d28974720d6935430054c6b630bade51ad508d31fdfd572bd37f70e3dc06021d2b0ccf91a7975aa501e152d62980f02ce0ee94b547a2fbede47cf1f5c0a541ccc8992dd006f77437ce6a6b1f4f91833914a1cc51acf9336a620c4a22073966cde3ecac3224941dec004e741e05c11b43796dc531ce33e7c9a4fa68fa689880842e37a3a04fb75f3fcee86813388df74d443d1c35d7adea290effa98309b22ceca9bc252ccb4c443733db691adf0af559a5b7565043f84e91c5ed9f79ebf49f0bd60b68a7b8730032574e8e21548204c75321a374bbbf822efb1281ddf32feeced4bfe22bcf7c1a309954c1e356175a8a1a1a074a22f4561acd872d813c88ea9f0f22ac8d7b7b2088bc8565e1c56dfbc84f57aa38c2600ee20e8736076a91ee73f3137e8da3fe3871587b8bdb0a08af40babbe5493f036b45eea837dc15f761d9475d27a512a2d9dfc1ccdb81e2b581f91a5d7fe67cf6955427315a4e9c158806e651e4acff40051cd8a44b0108876c82f7b4d69033bfd8216234de545bf8fb58e489bc74d366db5e48711ba7f317dcdd1708ed5de97468a6026e15bc68ab11efc90f5465b4466bf384a8cc95f9c7fff91d776cccceeae5badebc31c3516c93a7b4682212e5a4902a9fd0327234749d83c141db2eee9688a76f4361f8b6213c88ebde69ebb84488c9ab8f42737da123eaf39373ac687df65f817939296f5477f92ad3fda0effbdd5d0594eb59d80265eef6cfcaf81b386c9d03c205c1b6714bf31be15e8f871b4791aec10884938285d6b8c18a0dfe750b753de88a2d2d855b9d1a0068ac4d2ce3a259bfdd30414380bf8b287abf2a28de442552f1d70a0aeb0867d9c7ed4e9717565ebc6aca21d85d2845faacfd8fadb1a76d9a2cd619413e631666009085bc7dad7492654ec20431e37ddd55588d2cd4d256021547cac768dfe3f7dcc9a18f0c72a743de799e98398b9bb2f216aea727d240b2f52ee269f4df4b8d7bdb439f074e3ef179ae2ae44daba64864fe427574b659a5e79defaf43e45e1357e1ff48e28ba6384c559cd036c9229151f917865b5575cda11e1ee0690bfbdb628b9a17e9c37190102\",\n\t\t\tdomain:        \"signaler-pa.clients6.google.com\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[4]; packet 1\",\n\t\t\thexData:       \"cc0000000108a3e7f3133d37e2970040460094b49b4808cfaa190ce163e91b9d2c0105f36a2c93f670114f7b60598f03d6c596ceb19f410e9660903f590e3f25cf619e5c171001990b1d1b97f789595d3039e666345cc944894c6153ddd936992f160ae349757507f79fd0485766987d986518d9f19270a0021c52bff14e594c074f3c5664cf3de3b761cd36c16acf68565aaaeebf196da581533f19a464b22404b13b46ae3e4819bd4a7a85db6ddf379bb84f8dffcbb412c9ce405d8b4c98d303cb13df2e80a88ca0f09e2e2489c8d0b6d5ba9262b85869f8f989e9b82c4a270592894fda96bd27ce03e0cb4d4a4e130d9655e6da02f4348c949bc9b2aa609fdb4b9a0a3e45be25b18fbde569bb996d6419e98f2d9b7a0ca63f52f054b50771dc7c580596d86b4a94642be9a9b78a01ad2deae4607d8e0e25641aa8ed46b20fe027f4b9f77d1736aa0fec4f837cf5d878b3dcefdf3c6e82eb943dd022e98d623403950e6ea3addc0f93f92a422ed686b7beee437a4040f4a440dfd071d8c09f1344c28545b4488765a455e33e13d17434b9642dedadcb6a13ec35d51c3e7a03ae9a76cca6b1cba8312b7d8bae703e0a378300a17b7483d07893ddd941dd3e545a66faa0fabb4dc967c807665ebf4562fede176719d1a126f228acc0902e7235972a6db4eedd6547c38705629ee2574c5d2dd6c76c5c82e741f33291506e66a8df65ef6d1e7e6628fe4a4f5e141d482fc5f9d26609e64da8061eef5c0fca421d5334b199ca8270612074a1f9fbaad8b98ff7b81f8871f4ada6976f254e47c51e03d4c628beb3471ba375642ae0b41d65dec1419cd31f20ec779f5666717c1e7b4240fdcfa46a774234961083e1915e938ae0d41a66868b91949d856065c4e6813e0cbd9680a916b5eb78655dea9ad0f9c0ad0f5c244a72fcb8b589321519e34f0e6e25e6bb43abfa84a7241bc02555fa9060b9ef55f1e3a9dc3a575e16b23a36aabbd3ddeaf8f2516224179a4039a891e7f29631c2a08745bb184c66ffe98bc960e6c08a14524ae34444433591cdf7adc14419310b74594305f67c3087a2c21733e6e0be748e7af6fb6717946c313fbc0935ad3559e2d6323979cdc3bd48753b5a438605e15832efb8a0c4144060f41ed27a82dd067f2caaea3830abc97d9e080b3fd762aecbd58e8b2b17dae553dacdf3ee44198d2f19c0522b6a1b17923a210cf24902c5590afe808fd22e54e586399665d588a7febd0b402a4e6283679e1f95a2d4d7d3945e2bb8f44225ad8aa07cd07d3323ce94f39ae4c9466c05ceeb0a30981cea022d1bcab8a4b0c8e42e08211ee727728c74d7945f2350a149eb9cb7eb3a280954b64e612b53b19016a4c07427945345ffb86982c113ed797172ded4428d6b95b9ce64b48e98ab96421a179983c4a74b986f3f52d9a2d7fac8ea0955835d241bf4817a42950e2b298e51de20c026df81fdb0d28c68841bf62dfcfb4684def62c13ceddce9a25b446043056006ec8582aea14eee602eb2963f575dedfd2313d7d561c6ceac0d08c94645a222b25b7493542fee52c316f06f583612ab2ec3d420a01a61fe80b099386c2fe647292769d4571239592fe7e27f4324456ef894643f72ac450628cdcc9f376607b85f369a092c64d7d5a0559193e29cbc48e9ed77fa3fa05776d6169fbdbafa507db1e1d33a4550003a3a1a794b266e886f483eba76a8629d17d9596574068ffce61a52b209c21c77f5e7337e5541755c9f1c6b4\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[4]; packet 1-2\",\n\t\t\thexData:       \"cc0000000108a3e7f3133d37e2970040460094b49b4808cfaa190ce163e91b9d2c0105f36a2c93f670114f7b60598f03d6c596ceb19f410e9660903f590e3f25cf619e5c171001990b1d1b97f789595d3039e666345cc944894c6153ddd936992f160ae349757507f79fd0485766987d986518d9f19270a0021c52bff14e594c074f3c5664cf3de3b761cd36c16acf68565aaaeebf196da581533f19a464b22404b13b46ae3e4819bd4a7a85db6ddf379bb84f8dffcbb412c9ce405d8b4c98d303cb13df2e80a88ca0f09e2e2489c8d0b6d5ba9262b85869f8f989e9b82c4a270592894fda96bd27ce03e0cb4d4a4e130d9655e6da02f4348c949bc9b2aa609fdb4b9a0a3e45be25b18fbde569bb996d6419e98f2d9b7a0ca63f52f054b50771dc7c580596d86b4a94642be9a9b78a01ad2deae4607d8e0e25641aa8ed46b20fe027f4b9f77d1736aa0fec4f837cf5d878b3dcefdf3c6e82eb943dd022e98d623403950e6ea3addc0f93f92a422ed686b7beee437a4040f4a440dfd071d8c09f1344c28545b4488765a455e33e13d17434b9642dedadcb6a13ec35d51c3e7a03ae9a76cca6b1cba8312b7d8bae703e0a378300a17b7483d07893ddd941dd3e545a66faa0fabb4dc967c807665ebf4562fede176719d1a126f228acc0902e7235972a6db4eedd6547c38705629ee2574c5d2dd6c76c5c82e741f33291506e66a8df65ef6d1e7e6628fe4a4f5e141d482fc5f9d26609e64da8061eef5c0fca421d5334b199ca8270612074a1f9fbaad8b98ff7b81f8871f4ada6976f254e47c51e03d4c628beb3471ba375642ae0b41d65dec1419cd31f20ec779f5666717c1e7b4240fdcfa46a774234961083e1915e938ae0d41a66868b91949d856065c4e6813e0cbd9680a916b5eb78655dea9ad0f9c0ad0f5c244a72fcb8b589321519e34f0e6e25e6bb43abfa84a7241bc02555fa9060b9ef55f1e3a9dc3a575e16b23a36aabbd3ddeaf8f2516224179a4039a891e7f29631c2a08745bb184c66ffe98bc960e6c08a14524ae34444433591cdf7adc14419310b74594305f67c3087a2c21733e6e0be748e7af6fb6717946c313fbc0935ad3559e2d6323979cdc3bd48753b5a438605e15832efb8a0c4144060f41ed27a82dd067f2caaea3830abc97d9e080b3fd762aecbd58e8b2b17dae553dacdf3ee44198d2f19c0522b6a1b17923a210cf24902c5590afe808fd22e54e586399665d588a7febd0b402a4e6283679e1f95a2d4d7d3945e2bb8f44225ad8aa07cd07d3323ce94f39ae4c9466c05ceeb0a30981cea022d1bcab8a4b0c8e42e08211ee727728c74d7945f2350a149eb9cb7eb3a280954b64e612b53b19016a4c07427945345ffb86982c113ed797172ded4428d6b95b9ce64b48e98ab96421a179983c4a74b986f3f52d9a2d7fac8ea0955835d241bf4817a42950e2b298e51de20c026df81fdb0d28c68841bf62dfcfb4684def62c13ceddce9a25b446043056006ec8582aea14eee602eb2963f575dedfd2313d7d561c6ceac0d08c94645a222b25b7493542fee52c316f06f583612ab2ec3d420a01a61fe80b099386c2fe647292769d4571239592fe7e27f4324456ef894643f72ac450628cdcc9f376607b85f369a092c64d7d5a0559193e29cbc48e9ed77fa3fa05776d6169fbdbafa507db1e1d33a4550003a3a1a794b266e886f483eba76a8629d17d9596574068ffce61a52b209c21c77f5e7337e5541755c9f1c6b4cd0000000108a3e7f3133d37e2970040460094b49b4808cfaa190ce163e91b9d2c0105f36a2c93f670114f7b60598f03d6c596ceb19f410e9660903f590e3f25cf619e5c171001990b1d1b97f789595d3039e666345cc944892d4ba45357f2ca515d03b90820bb91c531a4be27266fda6022856da650cfb9c34139e8a3180e93cb73a6864471f849bdfa26c03e30c0e4d00309207cd46fb48887f60d7c51b208c247d1b311b35da70dd682cb1f7ae6a64215e5fefe25249daf308083837a3898e6052ebcf6cef3cb8e987ee1eb5ea797642d76391ae363b8eb2409d7486dd4a67c9e9b755376ca61009cb853835850e4fc1844f8e9eebca73e89317003482f70c4795ce9e2724c6d62172e010233e7bf203dde6eea9976f29896df562e8640a4ed88b5b3dff50296d0db43885f162c588d72de357c2ee049d9532642576de64d4e13cce77208e0aa9cf9838166f3375a968a5a6a01cf066ea0ca27fe4471cf0bf7eb36227867928076985588d05692d3f81d9a1158d150b2701399ee0a32693aaac43c27b76c657343b2a307e7018c2e9fe6317ec09f9afb762075430140b15016ae44acffc7467f4b1cec619942e916047c2db27f89742e53856d8c7c098beaba710340674a3f8455ab38fa2a4156fa3a45dffca1e20ec86ae792988dcb52bbf2ac97ea878e80511d3e4e70ece4b2816401ad450b9d13a1fecd7a5a363dd120285a972d52c06b632362cb8f897f799fb8342850b6670eb5083347347bd48b559f118839aa627598379963ecf18c2a900399ed936ab77ebdf95bdc5eaa75a903005e38dd99362b3d99f07ee2aea1a0ada77ec5ba76a7da2a80b672f4709bd32fad36787e37467e75fe594a24b402a6fa7e858c2abe9cffd9e885cc7091c035e4354779fc113bc084b5f6fcbd7bc618e9cc15205538cf781c96b658565cd8e39d95001d085d52f87a2970eb8f72149f4061d629ca0a928442b586aef9105326e13c015ce2b987c442b574180550302c48c2cf763b45492e25adee42d23bb2608e284caea4b3a28b77a20768dee6c0002b16e5d714eca22ca0c58195e03951b9564079ffa61c81afb2c5783ea2b8c0605d3994cfaed3c33af2279469c771269174fc5879b67617f571eb376161241ca5a89332074635413661b7fc5f925d86afb56b296dedce33d2b5011fc3b85cfb769c4a1cf5d6217ba3db367ead2159a310cd398b31df83f48f722a1df6c4b6604b2e288aa57cbc9afcf42764ccbc718a3ca42895b8e8287d632d2dd47d933a7472fd7be596c4241220917e636a44a139ec16600d74104fa6055a77c34bdbe14fb1ee56b4084d1d2dc1d56f8d636a8393385fcb4916670eaf8553b2126b12c8f187f58f00ba9bdbe8f06662688b9b8c7327b2d2c2f1443c8b87930d0948c3db62c8becb5b38cc7e484be184400f8c6293568abf1714e2832ad2c0aeb88dde64686fa7b4cd8c452b7365e70221e62dd971db057d4f8eed86e6802bbe8f56f75a8fe65d8216c81265e514042dca73f20a50373fb32e9bd62b741021337a3200b5f0a1b1329e99c57c75a60850f6c2f82cbeb9001edb54d985b7d5cd5957b31f79ee77dd8e1ce5e70d50806273885886b93a12c3dc0f211383d180a475d65bb54b0c5f761f456bfc7d045acd2c7ac648f3bf27bdb52218be48cdef7aa1ddc93e3ce11067ef4819796a4e2a30459c879841789b358b9430368b0910d6e6eaa14894f36b12fe9dd2bd1a20ddb6b12ab8fcec7d0629c9a7\",\n\t\t\tdomain:        \"play.google.com\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[5]; packet 1\",\n\t\t\thexData:       \"c200000001085b15f32cf8fb5a3f00404600f909e38ed514455146c4ab8e53dd225a775dab2a06eaf73c2ec6b36c95c40873910eaa7e424e1b1fcb15892cf9e37a0ad2a1b67e9e8c6ec0c3a99e3d8775afe1e0aac824704489c14d28b48268df096f2db0c040c0ffdfb1817c4e1dd32005e87a74104515069ccd1b12f6fa3f657891bca8f0d27f4bb42b23c8310897ac09241f511888ac2e431e3ba8d9114b3f8bb1470324c8a0815dd1589686d058d03fa2669ad7367dc8877abce4700ae999112eb7cba755b20b7db66918021a36a66c60ecaaeb3e0859e3f50d14c1f8c3f56966043f437bfc16098deeb02e2236cc42d2f2802f4082bec30afc347a75f78c5e7337c52502e8e8d945bb4d792ef69419e57ee4e8f3465de4d0a49955787dff0756f1bcd98268919c112ae5e87ec333d590988e111724627143bf5a0aa69c77ee322b1240a65718e0033c4b70c6a5dc2d3248aef71598d73effa0eb397b79279ce846d9c2556fca28595eb3b196f40f052f0127711abbbc334571b8de67f7d39bd9437f9196bfe0650c4972462473776eccae42418b16edd5f45414e1a5e13300ae6705a49ef68e1748e876ce04fe611c973f94fcbe18b0c1a0ae506ce6eac268021e9744899c33ffe44dabdf1ea5413c20ab1013326255ae6df2d6861a7e914001e231ce4065e0d89fb439afb928d660cea26f99eafe65c9f89c5639f3ba8ffdcdf7a777d7859ca948f123a5c4f1491e22803754373ab0f1b605ac09ca6018c6acca7f52aad786ce96d9ae28d09a77dd88d77f23e2e33475973a23dea914fb049662800cfbed416b61835bd3bc22dace817b3b271c816ccf9603de2209067def5b8747112c49659cf6c5281402bed38a4176c0331e0841592c503d342188ac97266866a102864f76b0ff2adf781e0af84ae725fb6db418545dbb70adde5d4ea6d87f8c9b64b579d4f969830056dc0007cdad648035ccdf2c24264905422dfc1a85ac7f519f475351e046a27268312d4ab6a66ea55be01226fd5dfce06f804cafe85ad997946db3d029ef28ebdd36103c8fc05b522c1d4debe034523595cef576c771f0848a221d76c63dd044ea61a3adcbe5d4f0ebcd0bb631f4db1d88a609a1c2a6cc3de29ccd8a40e8a770d806abdae300cc178a32b4ba979652d0b8849dff252571f0b09935744c5b33628a190ae2eb43543ed8dee8539fd464abfcd3cf826aa18c4e84cd11975c5e3bfd0827f7cd211a2084c8626ed4e32bb9877f4801dabe695132b835e335563cb2f4c3e9377cac57f7766a10620f1c57c9f485d66918613daf8b257035ec91481d0076899c45abdbec38b63745428dee481c1cba81b0ab6e7efd6b0c431e018b6503cb13d4df18dbbff195bad1063d59ca5066e0733d3f499109111d22304066e7656e755518ceb6d862095ae54e532fad82f6c21c0c4d776dfecc516b00fa59e117e79481d3fd386c9b0c4d6fa4ec295a5b5b67207c3db20a206e0e31dad2c8dafb38e35dde331730bea33af32893653763e82565689009265db76b3b142d60f302a9545d82900aa6a017643c5c60583aefae43066ea3908e299612b078d06f102280dce4429461a42d80acdb6279c7aa190f9a8f61b485ffa430cbef199e1732da3d9b96cfac7ecc3b4959b86260eba763abb74c249180f67997967e716c95788bb6c04f182f40b795a929370c7fc72f1785f94cd36e3ddaddc15c7adb226cc131abc1863352caceb541d3924094db9c8a1c21c21640\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[5]; packet 1-2\",\n\t\t\thexData:       \"c200000001085b15f32cf8fb5a3f00404600f909e38ed514455146c4ab8e53dd225a775dab2a06eaf73c2ec6b36c95c40873910eaa7e424e1b1fcb15892cf9e37a0ad2a1b67e9e8c6ec0c3a99e3d8775afe1e0aac824704489c14d28b48268df096f2db0c040c0ffdfb1817c4e1dd32005e87a74104515069ccd1b12f6fa3f657891bca8f0d27f4bb42b23c8310897ac09241f511888ac2e431e3ba8d9114b3f8bb1470324c8a0815dd1589686d058d03fa2669ad7367dc8877abce4700ae999112eb7cba755b20b7db66918021a36a66c60ecaaeb3e0859e3f50d14c1f8c3f56966043f437bfc16098deeb02e2236cc42d2f2802f4082bec30afc347a75f78c5e7337c52502e8e8d945bb4d792ef69419e57ee4e8f3465de4d0a49955787dff0756f1bcd98268919c112ae5e87ec333d590988e111724627143bf5a0aa69c77ee322b1240a65718e0033c4b70c6a5dc2d3248aef71598d73effa0eb397b79279ce846d9c2556fca28595eb3b196f40f052f0127711abbbc334571b8de67f7d39bd9437f9196bfe0650c4972462473776eccae42418b16edd5f45414e1a5e13300ae6705a49ef68e1748e876ce04fe611c973f94fcbe18b0c1a0ae506ce6eac268021e9744899c33ffe44dabdf1ea5413c20ab1013326255ae6df2d6861a7e914001e231ce4065e0d89fb439afb928d660cea26f99eafe65c9f89c5639f3ba8ffdcdf7a777d7859ca948f123a5c4f1491e22803754373ab0f1b605ac09ca6018c6acca7f52aad786ce96d9ae28d09a77dd88d77f23e2e33475973a23dea914fb049662800cfbed416b61835bd3bc22dace817b3b271c816ccf9603de2209067def5b8747112c49659cf6c5281402bed38a4176c0331e0841592c503d342188ac97266866a102864f76b0ff2adf781e0af84ae725fb6db418545dbb70adde5d4ea6d87f8c9b64b579d4f969830056dc0007cdad648035ccdf2c24264905422dfc1a85ac7f519f475351e046a27268312d4ab6a66ea55be01226fd5dfce06f804cafe85ad997946db3d029ef28ebdd36103c8fc05b522c1d4debe034523595cef576c771f0848a221d76c63dd044ea61a3adcbe5d4f0ebcd0bb631f4db1d88a609a1c2a6cc3de29ccd8a40e8a770d806abdae300cc178a32b4ba979652d0b8849dff252571f0b09935744c5b33628a190ae2eb43543ed8dee8539fd464abfcd3cf826aa18c4e84cd11975c5e3bfd0827f7cd211a2084c8626ed4e32bb9877f4801dabe695132b835e335563cb2f4c3e9377cac57f7766a10620f1c57c9f485d66918613daf8b257035ec91481d0076899c45abdbec38b63745428dee481c1cba81b0ab6e7efd6b0c431e018b6503cb13d4df18dbbff195bad1063d59ca5066e0733d3f499109111d22304066e7656e755518ceb6d862095ae54e532fad82f6c21c0c4d776dfecc516b00fa59e117e79481d3fd386c9b0c4d6fa4ec295a5b5b67207c3db20a206e0e31dad2c8dafb38e35dde331730bea33af32893653763e82565689009265db76b3b142d60f302a9545d82900aa6a017643c5c60583aefae43066ea3908e299612b078d06f102280dce4429461a42d80acdb6279c7aa190f9a8f61b485ffa430cbef199e1732da3d9b96cfac7ecc3b4959b86260eba763abb74c249180f67997967e716c95788bb6c04f182f40b795a929370c7fc72f1785f94cd36e3ddaddc15c7adb226cc131abc1863352caceb541d3924094db9c8a1c21c21640c900000001085b15f32cf8fb5a3f00404600f909e38ed514455146c4ab8e53dd225a775dab2a06eaf73c2ec6b36c95c40873910eaa7e424e1b1fcb15892cf9e37a0ad2a1b67e9e8c6ec0c3a99e3d8775afe1e0aac8247044898c283466f3b200164ad9b30e17b425e07f6722df94b9a77dd555fbf25e5b0bae4fef254daf03f156b78afd967614c78208deaadef3552040c055487804c047604c5d6846e67d33e5fb5f743a81f688220d6f4c87091a860885af95d2db27e9c5dd2361f8196f5c1ade8fb37e159980547c38c6a6ddd0e055fbbd52bd7615615ffca15a0c144899d25f21156c53cb3922d2ccb83073e26074025a3c39f64a67dc02044ce0d630d9120041b2233bd26282bd2d7d1a81d486b64cab6dba7fb4375e200f53523f714a066b96769f9b1dc7c14353fc1faa51c0aeb99507ff3ae90ad6f4bfbc9b9ea00a87f8bf8e213a84a9efe2ce624e629261d93c83642df97fe146bdef478cc92bba387c9b524ac83cde55ad8f4a4d8fb3c09c8245a50ac16ebb67d651110a10ad1f7dc74ed32b9d644bc4b229c56942072aae5c311059165ef6839e7cfa0717c7032b667b8618527722fdc10a4c0ea900e9b414521b89ca83f253ea414a410a8b0b13da25c4b618f2ccd79e5d2a7579b4c431107d56ab8df16125bc25673181a6bd5abb09941515806fda32659e5281457d8c093314da0087169781b306f348d3994d84bdef936bb11355c41ce02c359174dc2a366509c130c96ddf5f156e0eb7912ac56611cf4f59ff3a8785034e81738a53ebc7fb60aaed709d78980d39822aae7e9a9d985aee6c11252a5e984ff1d167b9d4dc5d02ca8ba1167422dfc0f68b3b5902f3fd032204a5020b14a288ecd845816575fca7ef13c85765385e9964a9f0f6e2e5c4e600b190b275cd91ee8a38ecf73d35bad7371c15fdb73059afb3178786e76750845232ef787767c6985ea9b9ed9ff73430b7afb8e0b66aa210ab1943b606021bb8f50c55534e1014003d947533c1c0bd0c16dfaabf4914497583b818e643a2d8bc32d33a07133b4eecf8bcbd802dfaae894ebd473338e074af1b3672c6f03c55e6c3885848a4379cdb5873d9ff3015f9ddf8d954b3cb4eb9f56f2e8ccb519dcba72c5832146011068d3074520370fc8008b62f3fdd65978865df1a85e58fb62315dc617a3367e6c9564fbf74f5d5015932d435f3aaaaed37bc7d14d974c0e15d899c684f17db3b4790bdeba076624f4f45a0cc1c6c078a527695110842e837ded310f8c6ddf69a18e455f09130d4b4136ca6d02eee0f103b9923adefe8cb36b8fd554a27fa7300c4a6173835ca2c4d38cc11e3849ebbf73c475b7d0713caed6e70f55b34ccffe03978f231d5f92bc1e2da7ce589e2cc2cd76183394469fa537cb927db14a383dc589cf10819eb90dbdb7981cd1eeb3a284c9ce55ed859fbfbe73ca22328073b534bc81d319b5fdb97e66d532b5ffc19516b4c70ecb68f963b053a82915f3f74c8809f082bbc89d97dff9e8c82a65ed4be8e2975b82f0b7c73f34797c61db4ea8ee273116564288563a71747cf31568317363dffdff1d9e159b2f9bcd3fe5be96a9c50ac885493cc16234c58cdf471381664c1e3b54d147ea5c779c9c9b06d5c493231d9c03b50c6cba315a5ee766a6e8578105306e0911270d347e8ade2b354037f507e4993708191d32b51a79f023f4fccabb7d2ac262004745cc528b8a6dc1d8849e9d4a0152ab326b1eab8a505eef65076aca156f7b9\",\n\t\t\tdomain:        \"optimizationguide-pa.googleapis.com\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[6]; packet 1\",\n\t\t\thexData:       \"c500000001087e13dee82c592724000044d0a17c2a188dadf8c82a018cabf25d25211d9987189b2900ad36a8fa366990353230bc8d41ec5543e91e119a0fd35f72d320d670074d02f412a5418c9a3e25489db73b1f5e5ddb8fc8d6c51fd6a12dcade71e1fc8e89d2663e206185247847d218d695793a8a1054afd18d42a4feaa9bb5fae7651eab0bc5e9aa91539c311cbfd17f46d8894ac45eade657bd456ee87b4475f5e84a2c07571b082ecfdafd1a660075692ae22048d163067a60e06cf879eab20a464c6e44b242da94cc6b92e064ee6a52cb34c115056925d4615e51157da4e88f019ae144040827cf2cd2806b3f4018cde5f42e041ef55eab35fe65ff79dba1ddad5aba6221e93d4555510176463888666b1d1f53a2f3c71e8872b05717002717edd3a9c5c651be47a663ee877962623ee92310b2b1dbcd75ec2f31d9e2f0c87affe3ee083aaa0868c03c9b4e78660d8afa4e936f81dfcb2fc33dbc1ed3828195c8de3130a2757641652de23d270c8a25976546c46460d9635f499a650475a4288d1c62241f65ddd346e2bde3f4fb5fec76646f51d829b55e16a0975494c11101abb504f5398a761d59355a4843e14bfeced024239ca06717d27e932df5e050d7c54c9b3cc937f6b0731f0b1dc312b14cf4388bbc0c601abf8ca16ed7d9b597dd414156d75b486ac256f8989a072fe680961ac7446201aca359337ef0e58ffa2aa12bb3c9bd1a9f6237b5c37880cd450d8a95db7c1463c53ac4bca174f278be1a99fb75ded9fe282e0e44a03b51ad943cf8970e4ca7f8567d9a3883d07bc0ff6c11639ebc7614fa88496488cb2a49a158d0f008a6a03caf97d77c3d03a98c5a611b04f865d134e258f4094bd220e00bde789c3b3158e622d509073179c0725c7a14dde1cd76b4c6b61fc7ba87f05742f081a5c42dbe83445132b8ad1539ee36e221a9dc700ccab55e34688b082a1a8edc48335760f3d5fb7e92b548e7a09d11f15b97bda08ebb5ea355e274587720d7c1189e9ffbb00dba3c13da94d646e7742e3641d59aee50a5bd400cd992c5614325d8f1ff3529637c3f60adc1682fa6b5e26f3d52de73236680abde87ead74368e05c600a2fd291a592be00fba64eea78c9e1f5e55e61f691b3eb0ef17b7bd11f06427c89c4c930d18c0b28221a6c918322cae56397c7e2978bf253e7f2d987f4cbe66c44a96b45cddb9d5f6dae47bbc9e1f9dcbe6280e50c5dfc91efb469f408b28fed49c583800009dc8bfb4bc42174175df987a3be833582abd9aa09ba0425973de2ea9a4149a81ae1863e0c9f1b1075c26bf965dcbec2bea47ff6042495ed715b65fdd3266800994463c95960dfb6ceadfa07d58910d329fa7ef7a8f14da4a6d3b09faa5b17cbac8481ea46cbfcfb54f660929e268bcf2f86cd88a1b065dcc27f18110db9efb6fcf1eec62874ed3657b1d43419f39e785c510d239c021b7e97d258d789c90d39b434f1667495bd4f5dc5e0eb97df376d801cced0da3a85aab6ca12893d8622314b5d530f28ead33075891d0ee553d5bedcffb20fce9933ab5e117df816c96398f6a60c9e6f5b9182fd7d58869de01635b2c178ae7738beb81e318934ecd752393129fda6833718d6984d8e1a8d7bf52e9d93ad0902c0fbe3e66ae8305e43363d8996626646a684bebfb1809ac9823be750e84308ef573243b884d09ef294094ef256cfc13cb0fedb1e095ff71687c09a767bff308e562e1a6ce9964014a7afc8db2481d8d07486\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[6]; packet 1-2\",\n\t\t\thexData:       \"c500000001087e13dee82c592724000044d0a17c2a188dadf8c82a018cabf25d25211d9987189b2900ad36a8fa366990353230bc8d41ec5543e91e119a0fd35f72d320d670074d02f412a5418c9a3e25489db73b1f5e5ddb8fc8d6c51fd6a12dcade71e1fc8e89d2663e206185247847d218d695793a8a1054afd18d42a4feaa9bb5fae7651eab0bc5e9aa91539c311cbfd17f46d8894ac45eade657bd456ee87b4475f5e84a2c07571b082ecfdafd1a660075692ae22048d163067a60e06cf879eab20a464c6e44b242da94cc6b92e064ee6a52cb34c115056925d4615e51157da4e88f019ae144040827cf2cd2806b3f4018cde5f42e041ef55eab35fe65ff79dba1ddad5aba6221e93d4555510176463888666b1d1f53a2f3c71e8872b05717002717edd3a9c5c651be47a663ee877962623ee92310b2b1dbcd75ec2f31d9e2f0c87affe3ee083aaa0868c03c9b4e78660d8afa4e936f81dfcb2fc33dbc1ed3828195c8de3130a2757641652de23d270c8a25976546c46460d9635f499a650475a4288d1c62241f65ddd346e2bde3f4fb5fec76646f51d829b55e16a0975494c11101abb504f5398a761d59355a4843e14bfeced024239ca06717d27e932df5e050d7c54c9b3cc937f6b0731f0b1dc312b14cf4388bbc0c601abf8ca16ed7d9b597dd414156d75b486ac256f8989a072fe680961ac7446201aca359337ef0e58ffa2aa12bb3c9bd1a9f6237b5c37880cd450d8a95db7c1463c53ac4bca174f278be1a99fb75ded9fe282e0e44a03b51ad943cf8970e4ca7f8567d9a3883d07bc0ff6c11639ebc7614fa88496488cb2a49a158d0f008a6a03caf97d77c3d03a98c5a611b04f865d134e258f4094bd220e00bde789c3b3158e622d509073179c0725c7a14dde1cd76b4c6b61fc7ba87f05742f081a5c42dbe83445132b8ad1539ee36e221a9dc700ccab55e34688b082a1a8edc48335760f3d5fb7e92b548e7a09d11f15b97bda08ebb5ea355e274587720d7c1189e9ffbb00dba3c13da94d646e7742e3641d59aee50a5bd400cd992c5614325d8f1ff3529637c3f60adc1682fa6b5e26f3d52de73236680abde87ead74368e05c600a2fd291a592be00fba64eea78c9e1f5e55e61f691b3eb0ef17b7bd11f06427c89c4c930d18c0b28221a6c918322cae56397c7e2978bf253e7f2d987f4cbe66c44a96b45cddb9d5f6dae47bbc9e1f9dcbe6280e50c5dfc91efb469f408b28fed49c583800009dc8bfb4bc42174175df987a3be833582abd9aa09ba0425973de2ea9a4149a81ae1863e0c9f1b1075c26bf965dcbec2bea47ff6042495ed715b65fdd3266800994463c95960dfb6ceadfa07d58910d329fa7ef7a8f14da4a6d3b09faa5b17cbac8481ea46cbfcfb54f660929e268bcf2f86cd88a1b065dcc27f18110db9efb6fcf1eec62874ed3657b1d43419f39e785c510d239c021b7e97d258d789c90d39b434f1667495bd4f5dc5e0eb97df376d801cced0da3a85aab6ca12893d8622314b5d530f28ead33075891d0ee553d5bedcffb20fce9933ab5e117df816c96398f6a60c9e6f5b9182fd7d58869de01635b2c178ae7738beb81e318934ecd752393129fda6833718d6984d8e1a8d7bf52e9d93ad0902c0fbe3e66ae8305e43363d8996626646a684bebfb1809ac9823be750e84308ef573243b884d09ef294094ef256cfc13cb0fedb1e095ff71687c09a767bff308e562e1a6ce9964014a7afc8db2481d8d07486cd00000001087e13dee82c592724000044d0b2c403d66eaa310a954540668e9edc4b17a321446ac931672ca3d9097b2854efdfa7a8f610be76592b56ef9154b9ab42f4dafc575a9b9572433fa2bba180194a32a72a92a42560ae840508317cf34015b1d7d88a633588ce4333cd12bec1f9d53fe905130eb136852d4f405ef66254a0807640fe415e6d667b9f5e2148826d5a6c36b3c44b822cfb7a1e76954610a522e1bc9703e155f8f1e0c705e411d09c5dec1183c61608174767408558da03290f5536682373a09c762deb829dfe3ee061ac9f509a2b3d20dbb77f262e9ba8a5ff50f895165742c90c4ff48eb0438d5ff8491700f97fbfced20e8e95ab9b67078ece6664527eb8a4e78944c07c6bc5c48776e141418c3b5a0e58d24114b7d65a83619525f5a10be53a55f6e3e65080cf42109aa2ec166fbb9079444ea6c809b5062227fed7cc81609a6d7ea471bc82cd0759a354aa896c7a8242c3d8c845aa52225bbaf7546a0de6510189cd2852f7b70a29687eee6a3a99a3a288f3c3672a72dba2843fcee320e18ea906adf1629cc7f8220b6be890a8d37f4093022717d8c6d76080d07798ba74e9cda1a4c26189c367a6d12da14621b93fbfd2d2365465350b5864e4981955750c6d4038b74644827cd60c8cad0d6a18869f99d61b214becedd8f71a476c2a1a0ea8fade7b15de6ee522b6b90d0cc4e6d40eb85d9b5097e2969e85eae6710285016ae47fbc858d63e13d882721aaef3cbe0a6e4c4910e8b3e465fa66a738d8979a444b4a4804baf5b4f9a5fc8438f4991c32d280c5d273d0a1e0d9eea30d003162cd313780a5b000f70fb7797e6111b354c3deac241cb816328b77d71584852966392cab9b1a3d64ead878a2cfac085452397ba17b5cddf96415c31846a80fa9a5a21fd5f9963324ad75505d4b5c70903ec3b5f91c3460d88a7d1c6b111a5206d11accac8a2115e1ce8e834b01f48e041dcd71585c6fcdd3a2e83ec2ff1a2b85e75134ec966afec023d375a2a8bcd54ef0c42d50e20c6cd9b9fdab63785e62c5a4ceb8451c560b647a6cd87698e56e0be4e2990337f45f1cb4c73f0dbf98da1158d75df6eb60ab7a61d836c7b7f3e5c809b850a5cc5369ddd4e455da5e88179e932311873d177febf6226a378c72324ea710e10ef74f6462e7dba25b7df336cb2947df749ad0b8455f3c5c9ba5c0c8eb1e665fe50451c928ce87cc81a0ae2102e7a4fc297392818db885943112fae3c4547ea48c89ef9cd44c2edba4856dbc72b956e4fc6a875bdac57b1cd2378ddb9322e5a1d1844977ff2a6e94d8a00f4ef0a7ef7949f0840c6cc781252830c70d37df9846a69eb95bc733ec420b7b3724572521496da27bba1fcb73c28eed1eefb094283ab01284ebd82004e0be9977f23fbf135b8162ac41a2bf9e1b941b05cb52c80279775070cf2f851bb0168235c97de47880d2d51f1d5ba8327af33f16f49d44326b0d08d20ca7880ff88a14d3201452d7fd452b24fc3b69b89c5149795bc4d0bf51b6ace2c9146048e5ca0259b4955a069a16d5a73e72248cec44b2ca542dcd326aca3ba53bd48368719f44d53eddbace11ff28c11c7fd90c38966752532d3f81325d1682839b2da3d69acc85275c71ef3b10c4d983cfb0cb464f554d9360b0d6ec8fd25b85824350866207eef9e2c66e43f5d08e86aa6186b36d9ece72f56e06ac8e51a1b53fab4cc496e69307e9810a9b5cf960f306ec54131dd8e917a5861ba92f6885e41993\",\n\t\t\tdomain:        \"lh3.google.com\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[7]; packet 1\",\n\t\t\thexData:       \"c9000000010852e6d0c4f5f177b700404600eae9a1449fd711efdca846f59b6c9975a2189c1430f740e0e0eb4d50be086b798a47e037ee6afe9785b45df6302cfb87d39b9c03d0712f11793adab33e74904249722c4a1544896cd650da62160bdb601194f82a98c06df2546b79b5bab9503eafdbfbcfd1128204b52c9c5dde4d661cb84f2e015b7de9e10109874176362b7f06d4b49d850f2dcc8485aacb82fed8017fe454a1c31cfb82d392d6894081fa3ab1e5f2b71df79bf5a52a68a90d4752cf441220acbb274e3473f65c1a6e4cea3295da23e4a07818d5ba80b0668638c6ecb0b3ee12ecb8bed4ca32e27f4eee7376010b3905b8f7055728b8b1eda2e2707338b86f9a6115a23b29a010769d9a0e19d2bd06b81a507c4775d7215030862a026f168664255912c321669a5eff84ded4fec82af394cee909110758e5ad4de945236001bc0627d8e88ead3c3a6790d7e50887ced96f8380a80b11477147abc24dc4963c1907a07fec13e3cd8d5bab83cabd7cf8bb66af4911dfcdaf0f13aade34865b0740bebe4b4a482f1e3105bb9c3e5fece975187fa4eae5cb8fc868376b8b8329f89e407618aa5265f8ce73437e9f2714d752dad78025a38eaca1ebd6617a9a8a0bdefa8b3d3daad006978ba85d17ce3269da06be92eec61e4c5c99712517f01588b0b7deb4d7a75cadd5643daebc731f4a7bfaf17e8f002721b054a5d6d6ca7a3430c9480daff6adfd0a5480968b4fe0ee616d2e1f2f01268dcda2ee523fa593a0c83cbfc051dd7d503d48b152eb53894f79d4f6d38f05af35b287d16df579575b755f36e87b6df082108fda812195d5f60d2ceb59a54f09bb270d660c1d923348c7fdad97dc081e749a393af83bbcdd3c290efa19bce1a0f68dab0061df9dbee778dffb7754db10cbcc354a4b66c614e29d216a3a45a38594d337f775cb88c940924734ad52f8856606147b14ae2cf2990e1c401d79d27e4d6723afa4047454580698b9108b952b78b6bfd31db3b376f0879b2a0d8949b8443ffb9f7eb84b8024c620680481944312e86d183735effadab2d9f144a72d170fb035ed230f1451c94cb3f39bc28929e7480b22bbf6c906070eda03884cdd7ada9b10b7af27315c3bde8b4a273d46d1f764669aca152120da3e0a4fcf1be84b4f3cdfefe235a16598022cc74ad8f32e78aa06eb74ef61cccfc82ed35bcb70f008368ccdc17a6f64a316fcc9f006f307fa7a1a50f28c343c4c93a39df73a0d0a6dfc6f8ab10e966f738bee331e5a29d91ed993fd2638f0ec9d0ce539552b0a312fb85ed5e9f392fbc76a6164298b9de2c47dcb21a895957e92bc1270dfef3f00f44cc42c5f5005132dd030f9aec804045731c6a3eed3776beebe9451488932a1172b979f371aa370308037e57513a8fc9dd03d63fc2e5f7dcd683de26e116ea11a1d3b5e61fb5bbddc98e4ccd20be9ee71c02cacc95cbb17dd404558f586d4f0334bd12fc0a584d29eef3b4c2ce3f87babc462b6d24ca10aa8f1eb1abbd29d11ce3f1c92426c4950e53ba6c914cb4bf0bb1b44b25452cafbf246b76ce17f829bef3178174fbac4f932e6ac18e579fbbf8790611187c6f01de70fa82a21e979c90eed3c7f7b7e416491a000b5f2216e54858fa61893391b115573b2b960a0f7dc1e2a703a6f38485589c9133b4509fb54b4a602cc7d3341298e8e5da88d5e06aad28738650c08d8c71239735375e5bca7ea91dd78d748d65af598192317fd69e03daeecc99b8b\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[7]; packet 1-2\",\n\t\t\thexData:       \"c9000000010852e6d0c4f5f177b700404600eae9a1449fd711efdca846f59b6c9975a2189c1430f740e0e0eb4d50be086b798a47e037ee6afe9785b45df6302cfb87d39b9c03d0712f11793adab33e74904249722c4a1544896cd650da62160bdb601194f82a98c06df2546b79b5bab9503eafdbfbcfd1128204b52c9c5dde4d661cb84f2e015b7de9e10109874176362b7f06d4b49d850f2dcc8485aacb82fed8017fe454a1c31cfb82d392d6894081fa3ab1e5f2b71df79bf5a52a68a90d4752cf441220acbb274e3473f65c1a6e4cea3295da23e4a07818d5ba80b0668638c6ecb0b3ee12ecb8bed4ca32e27f4eee7376010b3905b8f7055728b8b1eda2e2707338b86f9a6115a23b29a010769d9a0e19d2bd06b81a507c4775d7215030862a026f168664255912c321669a5eff84ded4fec82af394cee909110758e5ad4de945236001bc0627d8e88ead3c3a6790d7e50887ced96f8380a80b11477147abc24dc4963c1907a07fec13e3cd8d5bab83cabd7cf8bb66af4911dfcdaf0f13aade34865b0740bebe4b4a482f1e3105bb9c3e5fece975187fa4eae5cb8fc868376b8b8329f89e407618aa5265f8ce73437e9f2714d752dad78025a38eaca1ebd6617a9a8a0bdefa8b3d3daad006978ba85d17ce3269da06be92eec61e4c5c99712517f01588b0b7deb4d7a75cadd5643daebc731f4a7bfaf17e8f002721b054a5d6d6ca7a3430c9480daff6adfd0a5480968b4fe0ee616d2e1f2f01268dcda2ee523fa593a0c83cbfc051dd7d503d48b152eb53894f79d4f6d38f05af35b287d16df579575b755f36e87b6df082108fda812195d5f60d2ceb59a54f09bb270d660c1d923348c7fdad97dc081e749a393af83bbcdd3c290efa19bce1a0f68dab0061df9dbee778dffb7754db10cbcc354a4b66c614e29d216a3a45a38594d337f775cb88c940924734ad52f8856606147b14ae2cf2990e1c401d79d27e4d6723afa4047454580698b9108b952b78b6bfd31db3b376f0879b2a0d8949b8443ffb9f7eb84b8024c620680481944312e86d183735effadab2d9f144a72d170fb035ed230f1451c94cb3f39bc28929e7480b22bbf6c906070eda03884cdd7ada9b10b7af27315c3bde8b4a273d46d1f764669aca152120da3e0a4fcf1be84b4f3cdfefe235a16598022cc74ad8f32e78aa06eb74ef61cccfc82ed35bcb70f008368ccdc17a6f64a316fcc9f006f307fa7a1a50f28c343c4c93a39df73a0d0a6dfc6f8ab10e966f738bee331e5a29d91ed993fd2638f0ec9d0ce539552b0a312fb85ed5e9f392fbc76a6164298b9de2c47dcb21a895957e92bc1270dfef3f00f44cc42c5f5005132dd030f9aec804045731c6a3eed3776beebe9451488932a1172b979f371aa370308037e57513a8fc9dd03d63fc2e5f7dcd683de26e116ea11a1d3b5e61fb5bbddc98e4ccd20be9ee71c02cacc95cbb17dd404558f586d4f0334bd12fc0a584d29eef3b4c2ce3f87babc462b6d24ca10aa8f1eb1abbd29d11ce3f1c92426c4950e53ba6c914cb4bf0bb1b44b25452cafbf246b76ce17f829bef3178174fbac4f932e6ac18e579fbbf8790611187c6f01de70fa82a21e979c90eed3c7f7b7e416491a000b5f2216e54858fa61893391b115573b2b960a0f7dc1e2a703a6f38485589c9133b4509fb54b4a602cc7d3341298e8e5da88d5e06aad28738650c08d8c71239735375e5bca7ea91dd78d748d65af598192317fd69e03daeecc99b8bc4000000010852e6d0c4f5f177b700404600eae9a1449fd711efdca846f59b6c9975a2189c1430f740e0e0eb4d50be086b798a47e037ee6afe9785b45df6302cfb87d39b9c03d0712f11793adab33e74904249722c4a1544898bcc839c7364f9518287bbf01c06e9fd67f74096cab78bc885ad264ca9151a48420ea11d5b9e3bc899cc0d663509c926bee5ef2a389a9945f5919677472b3245a2a68ab91654ba5f75026ae738a9e10b6b7439503961bedbfa2494099a9bba3b9595f70cacd8950abd5d3b8a85ac61e6482847e0ac71cbd63df462f4978afc7084ec5c9e65f3b57ad22f802d699c94f260212a61db6e6958ed60356bf991d3af9582cd1724a90f08e869ebd7f29fc3fb9e1198819a967096de1bdeea692fade6229b41c5efe6cdae313014db328e99bae1f323584a308f575b923a11185634b24c8cc1d608303c8ca5c1ae3d54b8b7ecb689d5e0e22323c5e47d8f9093080bcf1553f7fa238e156658ef50281f633f184e47992645c82ab9985b9b13f97f0bbd9db94285c131fff5870ea38691ade2e017ee6417a118a9b31f5b85ba2c76163f8668d90d448976d9d37238605d36b0b7e7abfb0e9c2866bb11b128bb70f003aeb77f439c6148d28719a4f336f4d622140faff82595233cff94906695e402b9115ba7b99f7d832f55d8de481af808ed9d48a493c3301d2b633cdcdc7a64acefaa9408b99a52768edeb9824cdb49257c6d3ea3f23763f70b74fc46252a97f7b3e173a93e81cca50fb12e8b0ea1083f9262e1607156296b5ff85e1531335441c90b442aa5dc616ed7b520bc040502280a0bdb011d6e9dac154587f033b3e9434cef567b724bf5203c315ef5e283028ec72ff33736499b8d326cd643e3a37d53e70b9a2384ac6037f488075eef8b2e507774d3d450ea4b1b65c1587eb2a60c6aad0ae20745a2c50f8acd8bc1e25740b4e7ab4b03a59731ccc487831b46ca0211264f4fd4a498e145aca0d7339663d29a7f32a14fc2b62a32f6354abf2d7de5ed9d7e0a1d6dbbfe14af25ca8c927dc8eeb2618f308eac81405552f1bafcaaede51f560fe5eb6aa78b8650ae97040b46469503c85994ebcf7ffa0222905657111325f861d380935c2a5b9ad26094e85b92327f79f66b4a2f8cd674344f931f0e056ba58a084a1026bc422b80ec11b17de1ca965e8ac9ede1464588303986ba8fabb395b55de5580131ae3bf61822e4e2817dacf765e034542e435c4e9ebc58f21cfa7901dfbcc2b2be98cc55fa6d9e0030e17a32abf84d551a74f7391dd204847c25ee6382f6374b8ecc5b29b598b9ba562e0a6f25ebb932570ae8ab7ef7d06e444fdf79845e88b3132ffb6e1f330e3424272da082486aba357bd254ef0738bb7f5c9db73d2a9ba0c9afeb34e09ff0e20bd44ba1a46ad3081db2f750d00b647756dec1bb41032e1aaf56f58d7046102aef6ae40517f9cbc148692401ad06ea4ff6ed3e5c8a0cff8f9466a3530a99cfb9b5a857a967675df0cfbe3b798fdc2d929fa4c86e3b3e3c45b75fa5db6c15953f25bcd025d7efc3172b2206a200128f6d8caca97154b2608511b35b0cba9a550d8f791552faed64036cfb8498dc60492207ab81c3f3edeafd9d3acf5bca2f2735117a273c70345d3b7e289b9948edda3d5ebb8adde7de2451fe2d942d92ab383dc9a9adb6fb9e8cbc0b73d852f176e0265a6107e6a59746e2f2e7203fd445e5fe278d02cd5dac1b7988e205c37bc5f35dc27572743810453b9b27e55c\",\n\t\t\tdomain:        \"\",\n\t\t\twantErr:       true,\n\t\t\tneedsMoreData: true,\n\t\t},\n\t\t{\n\t\t\tname:          \"QUIC Chromebook Handshake[7]; packet 1-3\",\n\t\t\thexData:       \"c9000000010852e6d0c4f5f177b700404600eae9a1449fd711efdca846f59b6c9975a2189c1430f740e0e0eb4d50be086b798a47e037ee6afe9785b45df6302cfb87d39b9c03d0712f11793adab33e74904249722c4a1544896cd650da62160bdb601194f82a98c06df2546b79b5bab9503eafdbfbcfd1128204b52c9c5dde4d661cb84f2e015b7de9e10109874176362b7f06d4b49d850f2dcc8485aacb82fed8017fe454a1c31cfb82d392d6894081fa3ab1e5f2b71df79bf5a52a68a90d4752cf441220acbb274e3473f65c1a6e4cea3295da23e4a07818d5ba80b0668638c6ecb0b3ee12ecb8bed4ca32e27f4eee7376010b3905b8f7055728b8b1eda2e2707338b86f9a6115a23b29a010769d9a0e19d2bd06b81a507c4775d7215030862a026f168664255912c321669a5eff84ded4fec82af394cee909110758e5ad4de945236001bc0627d8e88ead3c3a6790d7e50887ced96f8380a80b11477147abc24dc4963c1907a07fec13e3cd8d5bab83cabd7cf8bb66af4911dfcdaf0f13aade34865b0740bebe4b4a482f1e3105bb9c3e5fece975187fa4eae5cb8fc868376b8b8329f89e407618aa5265f8ce73437e9f2714d752dad78025a38eaca1ebd6617a9a8a0bdefa8b3d3daad006978ba85d17ce3269da06be92eec61e4c5c99712517f01588b0b7deb4d7a75cadd5643daebc731f4a7bfaf17e8f002721b054a5d6d6ca7a3430c9480daff6adfd0a5480968b4fe0ee616d2e1f2f01268dcda2ee523fa593a0c83cbfc051dd7d503d48b152eb53894f79d4f6d38f05af35b287d16df579575b755f36e87b6df082108fda812195d5f60d2ceb59a54f09bb270d660c1d923348c7fdad97dc081e749a393af83bbcdd3c290efa19bce1a0f68dab0061df9dbee778dffb7754db10cbcc354a4b66c614e29d216a3a45a38594d337f775cb88c940924734ad52f8856606147b14ae2cf2990e1c401d79d27e4d6723afa4047454580698b9108b952b78b6bfd31db3b376f0879b2a0d8949b8443ffb9f7eb84b8024c620680481944312e86d183735effadab2d9f144a72d170fb035ed230f1451c94cb3f39bc28929e7480b22bbf6c906070eda03884cdd7ada9b10b7af27315c3bde8b4a273d46d1f764669aca152120da3e0a4fcf1be84b4f3cdfefe235a16598022cc74ad8f32e78aa06eb74ef61cccfc82ed35bcb70f008368ccdc17a6f64a316fcc9f006f307fa7a1a50f28c343c4c93a39df73a0d0a6dfc6f8ab10e966f738bee331e5a29d91ed993fd2638f0ec9d0ce539552b0a312fb85ed5e9f392fbc76a6164298b9de2c47dcb21a895957e92bc1270dfef3f00f44cc42c5f5005132dd030f9aec804045731c6a3eed3776beebe9451488932a1172b979f371aa370308037e57513a8fc9dd03d63fc2e5f7dcd683de26e116ea11a1d3b5e61fb5bbddc98e4ccd20be9ee71c02cacc95cbb17dd404558f586d4f0334bd12fc0a584d29eef3b4c2ce3f87babc462b6d24ca10aa8f1eb1abbd29d11ce3f1c92426c4950e53ba6c914cb4bf0bb1b44b25452cafbf246b76ce17f829bef3178174fbac4f932e6ac18e579fbbf8790611187c6f01de70fa82a21e979c90eed3c7f7b7e416491a000b5f2216e54858fa61893391b115573b2b960a0f7dc1e2a703a6f38485589c9133b4509fb54b4a602cc7d3341298e8e5da88d5e06aad28738650c08d8c71239735375e5bca7ea91dd78d748d65af598192317fd69e03daeecc99b8bc4000000010852e6d0c4f5f177b700404600eae9a1449fd711efdca846f59b6c9975a2189c1430f740e0e0eb4d50be086b798a47e037ee6afe9785b45df6302cfb87d39b9c03d0712f11793adab33e74904249722c4a1544898bcc839c7364f9518287bbf01c06e9fd67f74096cab78bc885ad264ca9151a48420ea11d5b9e3bc899cc0d663509c926bee5ef2a389a9945f5919677472b3245a2a68ab91654ba5f75026ae738a9e10b6b7439503961bedbfa2494099a9bba3b9595f70cacd8950abd5d3b8a85ac61e6482847e0ac71cbd63df462f4978afc7084ec5c9e65f3b57ad22f802d699c94f260212a61db6e6958ed60356bf991d3af9582cd1724a90f08e869ebd7f29fc3fb9e1198819a967096de1bdeea692fade6229b41c5efe6cdae313014db328e99bae1f323584a308f575b923a11185634b24c8cc1d608303c8ca5c1ae3d54b8b7ecb689d5e0e22323c5e47d8f9093080bcf1553f7fa238e156658ef50281f633f184e47992645c82ab9985b9b13f97f0bbd9db94285c131fff5870ea38691ade2e017ee6417a118a9b31f5b85ba2c76163f8668d90d448976d9d37238605d36b0b7e7abfb0e9c2866bb11b128bb70f003aeb77f439c6148d28719a4f336f4d622140faff82595233cff94906695e402b9115ba7b99f7d832f55d8de481af808ed9d48a493c3301d2b633cdcdc7a64acefaa9408b99a52768edeb9824cdb49257c6d3ea3f23763f70b74fc46252a97f7b3e173a93e81cca50fb12e8b0ea1083f9262e1607156296b5ff85e1531335441c90b442aa5dc616ed7b520bc040502280a0bdb011d6e9dac154587f033b3e9434cef567b724bf5203c315ef5e283028ec72ff33736499b8d326cd643e3a37d53e70b9a2384ac6037f488075eef8b2e507774d3d450ea4b1b65c1587eb2a60c6aad0ae20745a2c50f8acd8bc1e25740b4e7ab4b03a59731ccc487831b46ca0211264f4fd4a498e145aca0d7339663d29a7f32a14fc2b62a32f6354abf2d7de5ed9d7e0a1d6dbbfe14af25ca8c927dc8eeb2618f308eac81405552f1bafcaaede51f560fe5eb6aa78b8650ae97040b46469503c85994ebcf7ffa0222905657111325f861d380935c2a5b9ad26094e85b92327f79f66b4a2f8cd674344f931f0e056ba58a084a1026bc422b80ec11b17de1ca965e8ac9ede1464588303986ba8fabb395b55de5580131ae3bf61822e4e2817dacf765e034542e435c4e9ebc58f21cfa7901dfbcc2b2be98cc55fa6d9e0030e17a32abf84d551a74f7391dd204847c25ee6382f6374b8ecc5b29b598b9ba562e0a6f25ebb932570ae8ab7ef7d06e444fdf79845e88b3132ffb6e1f330e3424272da082486aba357bd254ef0738bb7f5c9db73d2a9ba0c9afeb34e09ff0e20bd44ba1a46ad3081db2f750d00b647756dec1bb41032e1aaf56f58d7046102aef6ae40517f9cbc148692401ad06ea4ff6ed3e5c8a0cff8f9466a3530a99cfb9b5a857a967675df0cfbe3b798fdc2d929fa4c86e3b3e3c45b75fa5db6c15953f25bcd025d7efc3172b2206a200128f6d8caca97154b2608511b35b0cba9a550d8f791552faed64036cfb8498dc60492207ab81c3f3edeafd9d3acf5bca2f2735117a273c70345d3b7e289b9948edda3d5ebb8adde7de2451fe2d942d92ab383dc9a9adb6fb9e8cbc0b73d852f176e0265a6107e6a59746e2f2e7203fd445e5fe278d02cd5dac1b7988e205c37bc5f35dc27572743810453b9b27e55cc5000000010852e6d0c4f5f177b700404600eae9a1449fd711efdca846f59b6c9975a2189c1430f740e0e0eb4d50be086b798a47e037ee6afe9785b45df6302cfb87d39b9c03d0712f11793adab33e74904249722c4a1544894fb2a6f735bea394066ea4ab5d3ef6f419c4bb099bcea8fd7e36d8ec14fae027d0c84ba8c38a5ea1e2e9ff24ec334dee8085d1fa9d88df2c5ce3dddd981f7b2a68011f2d4034f8e4c6f43e645fc71e19927aec56045f0ef72d9da1942dbe3e42248c2f695525c8d8fcf6dbc970c2eb5d607e07dce5c8c66d4de07de6b2c35bd3bfa12cd4e4fcd4cdda3e0b2ff7575d406db96502f1ec4d9b5748215fe2a4018c7dbdb5ead1ddfc06da5233ce359e4f3924f2af1b80c7af9d13437e0107f7e240e485458a3a656e31a543bc5a80f6a598dcbbd87ff9cb4ce6842abadb72d62ae03e6d12b7f43ac1805e408d738148fa3a5c34deae7378d7d7309a7e09f5bac848f4c031693fbe3382a2de66a9d007420512e24b8a78a9489b30794c7cc51dd751c1cdeb2870b7c4a9b9606547f843c1a16d9be986b2f3e3d2f73f89c8e15da9de3dfdf7a667ced977332c5c62fd83d3c9a5e9718643e716db8f1b6fb58904ca17c24c9a4a191ec42be4c405fb00e443429582ff712dfdbadf1bb7e2d2abb0cc14f39c13a3b7013c62fd99488f043a6aec3ed7998b943ee24905fc915e3144c54393fa67ff34fdce2e48bba044f13ee1cd9c4f59a1a41f7fb7bdd8daee73461234f7cce5d54b078c3ad2b0aa37850ed4bb24f4d310d4ce75ede546ed6e73c0ee495ff8ce4b7256e8f43949539bf9df6e8d0fbf066fb506020c5a72e5e8b686641b78b365474c65fe9d8dd41133e27326fe82744b45b6ad1170433f3746647a68b824e94a213cda4c02f78465acbccdccb5bad1c70806d5a5c98c94338f88bf980b05b72cb82a4fd5b2a8586a5e5c5f2760115df595091809cfd12829f09622b53ca1d3809060aa7ab5d1f3640b3c2792a55c58fc3e80ac5d7f39ab5774a80fa1fc70461d396fa70dad1f90598244ce4197cb3ea42dce4afd61ca8ef93c8bc254d347872db21edcc3857bcb8dbe627508aa4856bd7d46e512db071905b3db100f425ba9f7181f0cce005cee2a95ffc190ddc1939e7049e58791b0e186433b0409f5a49e4e3262690a5160f8267c9099afdc58182236833fe7f825dfca34b08801345c1592bbab4964b34d7efa6c9d92e0106ede9a10fbf2a1be32f61f914211c3caa8b4c14edec5f9c139ee14789fe7d6634ede9bf9789caa60f5bf30b092e65ff95d3b32cbdc3e5842e3b16b935d31a3a0963bb0fe60f41efb6590f24eaf5e84006b28b3c755203113237e43fa70a37a009f71da49ea3f8097914d6128ee2b18adac49b5111fd3d18db9fd61ef8a2202fac5cfce646ccbea7eaaa81df0f1b7243465de15a3900143f479852f0e40bfad434b96eea3941f527b0d31c3d8f43188b911140766b5d7146feb93bf4da1ec47023dcd8f89863e487ba25c3105a4e43c4ea90f479eb0f774f3aa044b817f7e69b5dd1b3954e7dcdb2a6c4d191d5b9178262449413310f3876dd93145716781cb077025deb37d23c35e6fdf867d5353d10303b9e60efa50e9ecd013cd3f5270fc0e117a19ffb63038c594190018bd9c1c18a799f548c08a3e6f768de0de344cff160689fed73aa7fc4edc26f77413145775745c25fc2c9da5b62e24eab9b21895cfcda6e6457ae9fdfa6c54b49b0d160dad0aa7f8cbd3820a3098\",\n\t\t\tdomain:        \"ogads-pa.clients6.google.com\",\n\t\t\twantErr:       false,\n\t\t\tneedsMoreData: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tpkt, err := hex.DecodeString(tt.hexData)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to decode hex string: %v\", err)\n\t\t\t}\n\t\t\tquicHdr, err := quic.SniffQUIC(pkt)\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"SniffQUIC() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (errors.Is(err, protocol.ErrProtoNeedMoreData)) != tt.needsMoreData {\n\t\t\t\tt.Errorf(\"SniffQUIC() error = %v, expectsNoClue %v\", err, tt.needsMoreData)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err == nil && quicHdr.Domain() != tt.domain {\n\t\t\t\tt.Errorf(\"SniffQUIC() domain = %v, want %v\", quicHdr.Domain(), tt.domain)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSniffFakeQUICPacketWithInvalidPacketNumberLength(t *testing.T) {\n\tpkt, err := hex.DecodeString(\"cb00000001081c8c6d5aeb53d54400000090709b8600000000000000000000000000000000\")\n\tcommon.Must(err)\n\t_, err = quic.SniffQUIC(pkt)\n\tif err == nil {\n\t\tt.Error(\"failed\")\n\t}\n}\n\nfunc TestSniffFakeQUICPacketWithTooShortData(t *testing.T) {\n\tpkt, err := hex.DecodeString(\"cb00000001081c8c6d5aeb53d54400000090709b86\")\n\tcommon.Must(err)\n\t_, err = quic.SniffQUIC(pkt)\n\tif err == nil {\n\t\tt.Error(\"failed\")\n\t}\n}\n"
  },
  {
    "path": "common/protocol/server_picker.go",
    "content": "package protocol\n\nimport (\n\t\"sync\"\n)\n\ntype ServerList struct {\n\tsync.RWMutex\n\tservers []*ServerSpec\n}\n\nfunc NewServerList() *ServerList {\n\treturn &ServerList{}\n}\n\nfunc (sl *ServerList) AddServer(server *ServerSpec) {\n\tsl.Lock()\n\tdefer sl.Unlock()\n\n\tsl.servers = append(sl.servers, server)\n}\n\nfunc (sl *ServerList) Size() uint32 {\n\tsl.RLock()\n\tdefer sl.RUnlock()\n\n\treturn uint32(len(sl.servers))\n}\n\nfunc (sl *ServerList) GetServer(idx uint32) *ServerSpec {\n\tsl.Lock()\n\tdefer sl.Unlock()\n\n\tfor {\n\t\tif idx >= uint32(len(sl.servers)) {\n\t\t\treturn nil\n\t\t}\n\n\t\tserver := sl.servers[idx]\n\t\tif !server.IsValid() {\n\t\t\tsl.removeServer(idx)\n\t\t\tcontinue\n\t\t}\n\n\t\treturn server\n\t}\n}\n\nfunc (sl *ServerList) removeServer(idx uint32) {\n\tn := len(sl.servers)\n\tsl.servers[idx] = sl.servers[n-1]\n\tsl.servers = sl.servers[:n-1]\n}\n\ntype ServerPicker interface {\n\tPickServer() *ServerSpec\n}\n\ntype RoundRobinServerPicker struct {\n\tsync.Mutex\n\tserverlist *ServerList\n\tnextIndex  uint32\n}\n\nfunc NewRoundRobinServerPicker(serverlist *ServerList) *RoundRobinServerPicker {\n\treturn &RoundRobinServerPicker{\n\t\tserverlist: serverlist,\n\t\tnextIndex:  0,\n\t}\n}\n\nfunc (p *RoundRobinServerPicker) PickServer() *ServerSpec {\n\tp.Lock()\n\tdefer p.Unlock()\n\n\tnext := p.nextIndex\n\tserver := p.serverlist.GetServer(next)\n\tif server == nil {\n\t\tnext = 0\n\t\tserver = p.serverlist.GetServer(0)\n\t}\n\tnext++\n\tif next >= p.serverlist.Size() {\n\t\tnext = 0\n\t}\n\tp.nextIndex = next\n\n\treturn server\n}\n"
  },
  {
    "path": "common/protocol/server_picker_test.go",
    "content": "package protocol_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nfunc TestServerList(t *testing.T) {\n\tlist := NewServerList()\n\tlist.AddServer(NewServerSpec(net.TCPDestination(net.LocalHostIP, net.Port(1)), AlwaysValid()))\n\tif list.Size() != 1 {\n\t\tt.Error(\"list size: \", list.Size())\n\t}\n\tlist.AddServer(NewServerSpec(net.TCPDestination(net.LocalHostIP, net.Port(2)), BeforeTime(time.Now().Add(time.Second))))\n\tif list.Size() != 2 {\n\t\tt.Error(\"list.size: \", list.Size())\n\t}\n\n\tserver := list.GetServer(1)\n\tif server.Destination().Port != 2 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n\ttime.Sleep(2 * time.Second)\n\tserver = list.GetServer(1)\n\tif server != nil {\n\t\tt.Error(\"server: \", server)\n\t}\n\n\tserver = list.GetServer(0)\n\tif server.Destination().Port != 1 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n}\n\nfunc TestServerPicker(t *testing.T) {\n\tlist := NewServerList()\n\tlist.AddServer(NewServerSpec(net.TCPDestination(net.LocalHostIP, net.Port(1)), AlwaysValid()))\n\tlist.AddServer(NewServerSpec(net.TCPDestination(net.LocalHostIP, net.Port(2)), BeforeTime(time.Now().Add(time.Second))))\n\tlist.AddServer(NewServerSpec(net.TCPDestination(net.LocalHostIP, net.Port(3)), BeforeTime(time.Now().Add(time.Second))))\n\n\tpicker := NewRoundRobinServerPicker(list)\n\tserver := picker.PickServer()\n\tif server.Destination().Port != 1 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n\tserver = picker.PickServer()\n\tif server.Destination().Port != 2 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n\tserver = picker.PickServer()\n\tif server.Destination().Port != 3 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n\tserver = picker.PickServer()\n\tif server.Destination().Port != 1 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n\n\ttime.Sleep(2 * time.Second)\n\tserver = picker.PickServer()\n\tif server.Destination().Port != 1 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n\tserver = picker.PickServer()\n\tif server.Destination().Port != 1 {\n\t\tt.Error(\"server: \", server.Destination())\n\t}\n}\n"
  },
  {
    "path": "common/protocol/server_spec.go",
    "content": "package protocol\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype ValidationStrategy interface {\n\tIsValid() bool\n\tInvalidate()\n}\n\ntype alwaysValidStrategy struct{}\n\nfunc AlwaysValid() ValidationStrategy {\n\treturn alwaysValidStrategy{}\n}\n\nfunc (alwaysValidStrategy) IsValid() bool {\n\treturn true\n}\n\nfunc (alwaysValidStrategy) Invalidate() {}\n\ntype timeoutValidStrategy struct {\n\tuntil time.Time\n}\n\nfunc BeforeTime(t time.Time) ValidationStrategy {\n\treturn &timeoutValidStrategy{\n\t\tuntil: t,\n\t}\n}\n\nfunc (s *timeoutValidStrategy) IsValid() bool {\n\treturn s.until.After(time.Now())\n}\n\nfunc (s *timeoutValidStrategy) Invalidate() {\n\ts.until = time.Time{}\n}\n\ntype ServerSpec struct {\n\tsync.RWMutex\n\tdest  net.Destination\n\tusers []*MemoryUser\n\tvalid ValidationStrategy\n}\n\nfunc NewServerSpec(dest net.Destination, valid ValidationStrategy, users ...*MemoryUser) *ServerSpec {\n\treturn &ServerSpec{\n\t\tdest:  dest,\n\t\tusers: users,\n\t\tvalid: valid,\n\t}\n}\n\nfunc NewServerSpecFromPB(spec *ServerEndpoint) (*ServerSpec, error) {\n\tdest := net.TCPDestination(spec.Address.AsAddress(), net.Port(spec.Port))\n\tmUsers := make([]*MemoryUser, len(spec.User))\n\tfor idx, u := range spec.User {\n\t\tmUser, err := u.ToMemoryUser()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmUsers[idx] = mUser\n\t}\n\treturn NewServerSpec(dest, AlwaysValid(), mUsers...), nil\n}\n\nfunc (s *ServerSpec) Destination() net.Destination {\n\treturn s.dest\n}\n\nfunc (s *ServerSpec) HasUser(user *MemoryUser) bool {\n\ts.RLock()\n\tdefer s.RUnlock()\n\n\tfor _, u := range s.users {\n\t\tif u.Account.Equals(user.Account) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (s *ServerSpec) AddUser(user *MemoryUser) {\n\tif s.HasUser(user) {\n\t\treturn\n\t}\n\n\ts.Lock()\n\tdefer s.Unlock()\n\n\ts.users = append(s.users, user)\n}\n\nfunc (s *ServerSpec) PickUser() *MemoryUser {\n\ts.RLock()\n\tdefer s.RUnlock()\n\n\tuserCount := len(s.users)\n\tswitch userCount {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\treturn s.users[0]\n\tdefault:\n\t\treturn s.users[dice.Roll(userCount)]\n\t}\n}\n\nfunc (s *ServerSpec) IsValid() bool {\n\treturn s.valid.IsValid()\n}\n\nfunc (s *ServerSpec) Invalidate() {\n\ts.valid.Invalidate()\n}\n"
  },
  {
    "path": "common/protocol/server_spec.pb.go",
    "content": "package protocol\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ServerEndpoint struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress       *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tUser          []*User                `protobuf:\"bytes,3,rep,name=user,proto3\" json:\"user,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ServerEndpoint) Reset() {\n\t*x = ServerEndpoint{}\n\tmi := &file_common_protocol_server_spec_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerEndpoint) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerEndpoint) ProtoMessage() {}\n\nfunc (x *ServerEndpoint) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_protocol_server_spec_proto_msgTypes[0]\n\tif 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 ServerEndpoint.ProtoReflect.Descriptor instead.\nfunc (*ServerEndpoint) Descriptor() ([]byte, []int) {\n\treturn file_common_protocol_server_spec_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ServerEndpoint) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ServerEndpoint) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *ServerEndpoint) GetUser() []*User {\n\tif x != nil {\n\t\treturn x.User\n\t}\n\treturn nil\n}\n\nvar File_common_protocol_server_spec_proto protoreflect.FileDescriptor\n\nconst file_common_protocol_server_spec_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!common/protocol/server_spec.proto\\x12\\x1av2ray.core.common.protocol\\x1a\\x18common/net/address.proto\\x1a\\x1acommon/protocol/user.proto\\\"\\x97\\x01\\n\" +\n\t\"\\x0eServerEndpoint\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x124\\n\" +\n\t\"\\x04user\\x18\\x03 \\x03(\\v2 .v2ray.core.common.protocol.UserR\\x04userBo\\n\" +\n\t\"\\x1ecom.v2ray.core.common.protocolP\\x01Z.github.com/v2fly/v2ray-core/v5/common/protocol\\xaa\\x02\\x1aV2Ray.Core.Common.Protocolb\\x06proto3\"\n\nvar (\n\tfile_common_protocol_server_spec_proto_rawDescOnce sync.Once\n\tfile_common_protocol_server_spec_proto_rawDescData []byte\n)\n\nfunc file_common_protocol_server_spec_proto_rawDescGZIP() []byte {\n\tfile_common_protocol_server_spec_proto_rawDescOnce.Do(func() {\n\t\tfile_common_protocol_server_spec_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_protocol_server_spec_proto_rawDesc), len(file_common_protocol_server_spec_proto_rawDesc)))\n\t})\n\treturn file_common_protocol_server_spec_proto_rawDescData\n}\n\nvar file_common_protocol_server_spec_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_protocol_server_spec_proto_goTypes = []any{\n\t(*ServerEndpoint)(nil), // 0: v2ray.core.common.protocol.ServerEndpoint\n\t(*net.IPOrDomain)(nil), // 1: v2ray.core.common.net.IPOrDomain\n\t(*User)(nil),           // 2: v2ray.core.common.protocol.User\n}\nvar file_common_protocol_server_spec_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.common.protocol.ServerEndpoint.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t2, // 1: v2ray.core.common.protocol.ServerEndpoint.user:type_name -> v2ray.core.common.protocol.User\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_common_protocol_server_spec_proto_init() }\nfunc file_common_protocol_server_spec_proto_init() {\n\tif File_common_protocol_server_spec_proto != nil {\n\t\treturn\n\t}\n\tfile_common_protocol_user_proto_init()\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: unsafe.Slice(unsafe.StringData(file_common_protocol_server_spec_proto_rawDesc), len(file_common_protocol_server_spec_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_protocol_server_spec_proto_goTypes,\n\t\tDependencyIndexes: file_common_protocol_server_spec_proto_depIdxs,\n\t\tMessageInfos:      file_common_protocol_server_spec_proto_msgTypes,\n\t}.Build()\n\tFile_common_protocol_server_spec_proto = out.File\n\tfile_common_protocol_server_spec_proto_goTypes = nil\n\tfile_common_protocol_server_spec_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/protocol/server_spec.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.protocol;\noption csharp_namespace = \"V2Ray.Core.Common.Protocol\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/protocol\";\noption java_package = \"com.v2ray.core.common.protocol\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/protocol/user.proto\";\n\nmessage ServerEndpoint {\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  repeated v2ray.core.common.protocol.User user = 3;\n}\n"
  },
  {
    "path": "common/protocol/server_spec_test.go",
    "content": "package protocol_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n)\n\nfunc TestAlwaysValidStrategy(t *testing.T) {\n\tstrategy := AlwaysValid()\n\tif !strategy.IsValid() {\n\t\tt.Error(\"strategy not valid\")\n\t}\n\tstrategy.Invalidate()\n\tif !strategy.IsValid() {\n\t\tt.Error(\"strategy not valid\")\n\t}\n}\n\nfunc TestTimeoutValidStrategy(t *testing.T) {\n\tstrategy := BeforeTime(time.Now().Add(2 * time.Second))\n\tif !strategy.IsValid() {\n\t\tt.Error(\"strategy not valid\")\n\t}\n\ttime.Sleep(3 * time.Second)\n\tif strategy.IsValid() {\n\t\tt.Error(\"strategy is valid\")\n\t}\n\n\tstrategy = BeforeTime(time.Now().Add(2 * time.Second))\n\tstrategy.Invalidate()\n\tif strategy.IsValid() {\n\t\tt.Error(\"strategy is valid\")\n\t}\n}\n\nfunc TestUserInServerSpec(t *testing.T) {\n\tuuid1 := uuid.New()\n\tuuid2 := uuid.New()\n\n\ttoAccount := func(a *vmess.Account) Account {\n\t\taccount, err := a.AsAccount()\n\t\tcommon.Must(err)\n\t\treturn account\n\t}\n\n\tspec := NewServerSpec(net.Destination{}, AlwaysValid(), &MemoryUser{\n\t\tEmail:   \"test1@v2fly.org\",\n\t\tAccount: toAccount(&vmess.Account{Id: uuid1.String()}),\n\t})\n\tif spec.HasUser(&MemoryUser{\n\t\tEmail:   \"test1@v2fly.org\",\n\t\tAccount: toAccount(&vmess.Account{Id: uuid2.String()}),\n\t}) {\n\t\tt.Error(\"has user: \", uuid2)\n\t}\n\n\tspec.AddUser(&MemoryUser{Email: \"test2@v2fly.org\"})\n\tif !spec.HasUser(&MemoryUser{\n\t\tEmail:   \"test1@v2fly.org\",\n\t\tAccount: toAccount(&vmess.Account{Id: uuid1.String()}),\n\t}) {\n\t\tt.Error(\"not having user: \", uuid1)\n\t}\n}\n\nfunc TestPickUser(t *testing.T) {\n\tspec := NewServerSpec(net.Destination{}, AlwaysValid(), &MemoryUser{Email: \"test1@v2fly.org\"}, &MemoryUser{Email: \"test2@v2fly.org\"}, &MemoryUser{Email: \"test3@v2fly.org\"})\n\tuser := spec.PickUser()\n\tif !strings.HasSuffix(user.Email, \"@v2fly.org\") {\n\t\tt.Error(\"user: \", user.Email)\n\t}\n}\n"
  },
  {
    "path": "common/protocol/time.go",
    "content": "package protocol\n\nimport (\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\ntype Timestamp int64\n\ntype TimestampGenerator func() Timestamp\n\nfunc NowTime() Timestamp {\n\treturn Timestamp(time.Now().Unix())\n}\n\nfunc NewTimestampGenerator(base Timestamp, delta int) TimestampGenerator {\n\treturn func() Timestamp {\n\t\trangeInDelta := dice.Roll(delta*2) - delta\n\t\treturn base + Timestamp(rangeInDelta)\n\t}\n}\n"
  },
  {
    "path": "common/protocol/time_test.go",
    "content": "package protocol_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nfunc TestGenerateRandomInt64InRange(t *testing.T) {\n\tbase := time.Now().Unix()\n\tdelta := 100\n\tgenerator := NewTimestampGenerator(Timestamp(base), delta)\n\n\tfor i := 0; i < 100; i++ {\n\t\tval := int64(generator())\n\t\tif val > base+int64(delta) || val < base-int64(delta) {\n\t\t\tt.Error(val, \" not between \", base-int64(delta), \" and \", base+int64(delta))\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/protocol/tls/cert/.gitignore",
    "content": "*.pem"
  },
  {
    "path": "common/protocol/tls/cert/cert.go",
    "content": "package cert\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"encoding/asn1\"\n\t\"encoding/pem\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype Certificate struct {\n\t// Certificate in ASN.1 DER format\n\tCertificate []byte\n\t// Private key in ASN.1 DER format\n\tPrivateKey []byte\n}\n\nfunc ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) {\n\tcertBlock, _ := pem.Decode(certPEM)\n\tif certBlock == nil {\n\t\treturn nil, newError(\"failed to decode certificate\")\n\t}\n\tkeyBlock, _ := pem.Decode(keyPEM)\n\tif keyBlock == nil {\n\t\treturn nil, newError(\"failed to decode key\")\n\t}\n\treturn &Certificate{\n\t\tCertificate: certBlock.Bytes,\n\t\tPrivateKey:  keyBlock.Bytes,\n\t}, nil\n}\n\nfunc (c *Certificate) ToPEM() ([]byte, []byte) {\n\treturn pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: c.Certificate}),\n\t\tpem.EncodeToMemory(&pem.Block{Type: \"RSA PRIVATE KEY\", Bytes: c.PrivateKey})\n}\n\ntype Option func(*x509.Certificate)\n\nfunc Authority(isCA bool) Option {\n\treturn func(cert *x509.Certificate) {\n\t\tcert.IsCA = isCA\n\t}\n}\n\nfunc NotBefore(t time.Time) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.NotBefore = t\n\t}\n}\n\nfunc NotAfter(t time.Time) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.NotAfter = t\n\t}\n}\n\nfunc DNSNames(names ...string) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.DNSNames = names\n\t}\n}\n\nfunc CommonName(name string) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.Subject.CommonName = name\n\t}\n}\n\nfunc IPAddresses(ip ...net.IP) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.IPAddresses = ip\n\t}\n}\n\nfunc KeyUsage(usage x509.KeyUsage) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.KeyUsage = usage\n\t}\n}\n\nfunc Organization(org string) Option {\n\treturn func(c *x509.Certificate) {\n\t\tc.Subject.Organization = []string{org}\n\t}\n}\n\nfunc MustGenerate(parent *Certificate, opts ...Option) *Certificate {\n\tcert, err := Generate(parent, opts...)\n\tcommon.Must(err)\n\treturn cert\n}\n\nfunc publicKey(priv interface{}) interface{} {\n\tswitch k := priv.(type) {\n\tcase *rsa.PrivateKey:\n\t\treturn &k.PublicKey\n\tcase *ecdsa.PrivateKey:\n\t\treturn &k.PublicKey\n\tcase ed25519.PrivateKey:\n\t\treturn k.Public().(ed25519.PublicKey)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc Generate(parent *Certificate, opts ...Option) (*Certificate, error) {\n\tvar (\n\t\tpKey      interface{}\n\t\tparentKey interface{}\n\t\terr       error\n\t)\n\t// higher signing performance than RSA2048\n\tselfKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to generate self private key\").Base(err)\n\t}\n\tparentKey = selfKey\n\tif parent != nil {\n\t\tif _, e := asn1.Unmarshal(parent.PrivateKey, &ecPrivateKey{}); e == nil {\n\t\t\tpKey, err = x509.ParseECPrivateKey(parent.PrivateKey)\n\t\t} else if _, e := asn1.Unmarshal(parent.PrivateKey, &pkcs8{}); e == nil {\n\t\t\tpKey, err = x509.ParsePKCS8PrivateKey(parent.PrivateKey)\n\t\t} else if _, e := asn1.Unmarshal(parent.PrivateKey, &pkcs1PrivateKey{}); e == nil {\n\t\t\tpKey, err = x509.ParsePKCS1PrivateKey(parent.PrivateKey)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse parent private key\").Base(err)\n\t\t}\n\t\tparentKey = pKey\n\t}\n\n\tserialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)\n\tserialNumber, err := rand.Int(rand.Reader, serialNumberLimit)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to generate serial number\").Base(err)\n\t}\n\n\ttemplate := &x509.Certificate{\n\t\tSerialNumber:          serialNumber,\n\t\tNotBefore:             time.Now().Add(time.Hour * -1),\n\t\tNotAfter:              time.Now().Add(time.Hour),\n\t\tKeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,\n\t\tExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},\n\t\tBasicConstraintsValid: true,\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(template)\n\t}\n\n\tparentCert := template\n\tif parent != nil {\n\t\tpCert, err := x509.ParseCertificate(parent.Certificate)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse parent certificate\").Base(err)\n\t\t}\n\t\tparentCert = pCert\n\t}\n\n\tderBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, publicKey(selfKey), parentKey)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create certificate\").Base(err)\n\t}\n\n\tprivateKey, err := x509.MarshalPKCS8PrivateKey(selfKey)\n\tif err != nil {\n\t\treturn nil, newError(\"Unable to marshal private key\").Base(err)\n\t}\n\n\treturn &Certificate{\n\t\tCertificate: derBytes,\n\t\tPrivateKey:  privateKey,\n\t}, nil\n}\n"
  },
  {
    "path": "common/protocol/tls/cert/cert_test.go",
    "content": "package cert\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\nfunc TestGenerate(t *testing.T) {\n\terr := generate(nil, true, true, \"ca\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc generate(domainNames []string, isCA bool, jsonOutput bool, fileOutput string) error {\n\tcommonName := \"V2Ray Root CA\"\n\torganization := \"V2Ray Inc\"\n\n\texpire := time.Hour * 3\n\n\tvar opts []Option\n\tif isCA {\n\t\topts = append(opts, Authority(isCA))\n\t\topts = append(opts, KeyUsage(x509.KeyUsageCertSign|x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature))\n\t}\n\n\topts = append(opts, NotAfter(time.Now().Add(expire)))\n\topts = append(opts, CommonName(commonName))\n\tif len(domainNames) > 0 {\n\t\topts = append(opts, DNSNames(domainNames...))\n\t}\n\topts = append(opts, Organization(organization))\n\n\tcert, err := Generate(nil, opts...)\n\tif err != nil {\n\t\treturn newError(\"failed to generate TLS certificate\").Base(err)\n\t}\n\n\tif jsonOutput {\n\t\tprintJSON(cert)\n\t}\n\n\tif len(fileOutput) > 0 {\n\t\tif err := printFile(cert, fileOutput); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype jsonCert struct {\n\tCertificate []string `json:\"certificate\"`\n\tKey         []string `json:\"key\"`\n}\n\nfunc printJSON(certificate *Certificate) {\n\tcertPEM, keyPEM := certificate.ToPEM()\n\tjCert := &jsonCert{\n\t\tCertificate: strings.Split(strings.TrimSpace(string(certPEM)), \"\\n\"),\n\t\tKey:         strings.Split(strings.TrimSpace(string(keyPEM)), \"\\n\"),\n\t}\n\tcontent, err := json.MarshalIndent(jCert, \"\", \"  \")\n\tcommon.Must(err)\n\tos.Stdout.Write(content)\n\tos.Stdout.WriteString(\"\\n\")\n}\n\nfunc printFile(certificate *Certificate, name string) error {\n\tcertPEM, keyPEM := certificate.ToPEM()\n\treturn task.Run(context.Background(), func() error {\n\t\treturn writeFile(certPEM, name+\"_cert.pem\")\n\t}, func() error {\n\t\treturn writeFile(keyPEM, name+\"_key.pem\")\n\t})\n}\n\nfunc writeFile(content []byte, name string) error {\n\tf, err := os.Create(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\treturn common.Error2(f.Write(content))\n}\n"
  },
  {
    "path": "common/protocol/tls/cert/errors.generated.go",
    "content": "package cert\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/protocol/tls/cert/privateKey.go",
    "content": "package cert\n\nimport (\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"math/big\"\n)\n\ntype ecPrivateKey struct {\n\tVersion       int\n\tPrivateKey    []byte\n\tNamedCurveOID asn1.ObjectIdentifier `asn1:\"optional,explicit,tag:0\"`\n\tPublicKey     asn1.BitString        `asn1:\"optional,explicit,tag:1\"`\n}\n\ntype pkcs8 struct {\n\tVersion    int\n\tAlgo       pkix.AlgorithmIdentifier\n\tPrivateKey []byte\n\t// optional attributes omitted.\n}\n\ntype pkcs1AdditionalRSAPrime struct {\n\tPrime *big.Int\n\n\t// We ignore these values because rsa will calculate them.\n\tExp   *big.Int\n\tCoeff *big.Int\n}\n\ntype pkcs1PrivateKey struct {\n\tVersion int\n\tN       *big.Int\n\tE       int\n\tD       *big.Int\n\tP       *big.Int\n\tQ       *big.Int\n\t// We ignore these values, if present, because rsa will calculate them.\n\tDp   *big.Int `asn1:\"optional\"`\n\tDq   *big.Int `asn1:\"optional\"`\n\tQinv *big.Int `asn1:\"optional\"`\n\n\tAdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:\"optional,omitempty\"`\n}\n"
  },
  {
    "path": "common/protocol/tls/sniff.go",
    "content": "package tls\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype SniffHeader struct {\n\tdomain string\n}\n\nfunc (h *SniffHeader) Protocol() string {\n\treturn \"tls\"\n}\n\nfunc (h *SniffHeader) Domain() string {\n\treturn h.domain\n}\n\nvar (\n\terrNotTLS         = errors.New(\"not TLS header\")\n\terrNotClientHello = errors.New(\"not client hello\")\n)\n\nfunc IsValidTLSVersion(major, minor byte) bool {\n\treturn major == 3\n}\n\n// ReadClientHello returns server name (if any) from TLS client hello message.\n// https://github.com/golang/go/blob/master/src/crypto/tls/handshake_messages.go#L300\nfunc ReadClientHello(data []byte, h *SniffHeader) error {\n\tif len(data) < 42 {\n\t\treturn common.ErrNoClue\n\t}\n\tsessionIDLen := int(data[38])\n\tif sessionIDLen > 32 || len(data) < 39+sessionIDLen {\n\t\treturn common.ErrNoClue\n\t}\n\tdata = data[39+sessionIDLen:]\n\tif len(data) < 2 {\n\t\treturn common.ErrNoClue\n\t}\n\t// cipherSuiteLen is the number of bytes of cipher suite numbers. Since\n\t// they are uint16s, the number must be even.\n\tcipherSuiteLen := int(data[0])<<8 | int(data[1])\n\tif cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {\n\t\treturn errNotClientHello\n\t}\n\tdata = data[2+cipherSuiteLen:]\n\tif len(data) < 1 {\n\t\treturn common.ErrNoClue\n\t}\n\tcompressionMethodsLen := int(data[0])\n\tif len(data) < 1+compressionMethodsLen {\n\t\treturn common.ErrNoClue\n\t}\n\tdata = data[1+compressionMethodsLen:]\n\n\tif len(data) == 0 {\n\t\treturn errNotClientHello\n\t}\n\tif len(data) < 2 {\n\t\treturn errNotClientHello\n\t}\n\n\textensionsLength := int(data[0])<<8 | int(data[1])\n\tdata = data[2:]\n\tif extensionsLength != len(data) {\n\t\treturn errNotClientHello\n\t}\n\n\tfor len(data) != 0 {\n\t\tif len(data) < 4 {\n\t\t\treturn errNotClientHello\n\t\t}\n\t\textension := uint16(data[0])<<8 | uint16(data[1])\n\t\tlength := int(data[2])<<8 | int(data[3])\n\t\tdata = data[4:]\n\t\tif len(data) < length {\n\t\t\treturn errNotClientHello\n\t\t}\n\n\t\tif extension == 0x00 { /* extensionServerName */\n\t\t\td := data[:length]\n\t\t\tif len(d) < 2 {\n\t\t\t\treturn errNotClientHello\n\t\t\t}\n\t\t\tnamesLen := int(d[0])<<8 | int(d[1])\n\t\t\td = d[2:]\n\t\t\tif len(d) != namesLen {\n\t\t\t\treturn errNotClientHello\n\t\t\t}\n\t\t\tfor len(d) > 0 {\n\t\t\t\tif len(d) < 3 {\n\t\t\t\t\treturn errNotClientHello\n\t\t\t\t}\n\t\t\t\tnameType := d[0]\n\t\t\t\tnameLen := int(d[1])<<8 | int(d[2])\n\t\t\t\td = d[3:]\n\t\t\t\tif len(d) < nameLen {\n\t\t\t\t\treturn errNotClientHello\n\t\t\t\t}\n\t\t\t\tif nameType == 0 {\n\t\t\t\t\tserverName := string(d[:nameLen])\n\t\t\t\t\t// An SNI value may not include a\n\t\t\t\t\t// trailing dot. See\n\t\t\t\t\t// https://tools.ietf.org/html/rfc6066#section-3.\n\t\t\t\t\tif strings.HasSuffix(serverName, \".\") {\n\t\t\t\t\t\treturn errNotClientHello\n\t\t\t\t\t}\n\t\t\t\t\th.domain = serverName\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\td = d[nameLen:]\n\t\t\t}\n\t\t}\n\t\tdata = data[length:]\n\t}\n\n\treturn errNotTLS\n}\n\nfunc SniffTLS(b []byte) (*SniffHeader, error) {\n\tif len(b) < 5 {\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\tif b[0] != 0x16 /* TLS Handshake */ {\n\t\treturn nil, errNotTLS\n\t}\n\tif !IsValidTLSVersion(b[1], b[2]) {\n\t\treturn nil, errNotTLS\n\t}\n\theaderLen := int(binary.BigEndian.Uint16(b[3:5]))\n\tif 5+headerLen > len(b) {\n\t\treturn nil, common.ErrNoClue\n\t}\n\n\th := &SniffHeader{}\n\terr := ReadClientHello(b[5:5+headerLen], h)\n\tif err == nil {\n\t\treturn h, nil\n\t}\n\treturn nil, err\n}\n"
  },
  {
    "path": "common/protocol/tls/sniff_test.go",
    "content": "package tls_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/protocol/tls\"\n)\n\nfunc TestTLSHeaders(t *testing.T) {\n\tcases := []struct {\n\t\tinput  []byte\n\t\tdomain string\n\t\terr    bool\n\t}{\n\t\t{\n\t\t\tinput: []byte{\n\t\t\t\t0x16, 0x03, 0x01, 0x00, 0xc8, 0x01, 0x00, 0x00,\n\t\t\t\t0xc4, 0x03, 0x03, 0x1a, 0xac, 0xb2, 0xa8, 0xfe,\n\t\t\t\t0xb4, 0x96, 0x04, 0x5b, 0xca, 0xf7, 0xc1, 0xf4,\n\t\t\t\t0x2e, 0x53, 0x24, 0x6e, 0x34, 0x0c, 0x58, 0x36,\n\t\t\t\t0x71, 0x97, 0x59, 0xe9, 0x41, 0x66, 0xe2, 0x43,\n\t\t\t\t0xa0, 0x13, 0xb6, 0x00, 0x00, 0x20, 0x1a, 0x1a,\n\t\t\t\t0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,\n\t\t\t\t0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13,\n\t\t\t\t0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d,\n\t\t\t\t0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,\n\t\t\t\t0x00, 0x7b, 0xba, 0xba, 0x00, 0x00, 0xff, 0x01,\n\t\t\t\t0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,\n\t\t\t\t0x14, 0x00, 0x00, 0x11, 0x63, 0x2e, 0x73, 0x2d,\n\t\t\t\t0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,\n\t\t\t\t0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x17, 0x00,\n\t\t\t\t0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,\n\t\t\t\t0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,\n\t\t\t\t0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,\n\t\t\t\t0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x05, 0x00,\n\t\t\t\t0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,\n\t\t\t\t0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c,\n\t\t\t\t0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70,\n\t\t\t\t0x2f, 0x31, 0x2e, 0x31, 0x00, 0x0b, 0x00, 0x02,\n\t\t\t\t0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08,\n\t\t\t\t0xaa, 0xaa, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,\n\t\t\t\t0xaa, 0xaa, 0x00, 0x01, 0x00,\n\t\t\t},\n\t\t\tdomain: \"c.s-microsoft.com\",\n\t\t\terr:    false,\n\t\t},\n\t\t{\n\t\t\tinput: []byte{\n\t\t\t\t0x16, 0x03, 0x01, 0x00, 0xee, 0x01, 0x00, 0x00,\n\t\t\t\t0xea, 0x03, 0x03, 0xe7, 0x91, 0x9e, 0x93, 0xca,\n\t\t\t\t0x78, 0x1b, 0x3c, 0xe0, 0x65, 0x25, 0x58, 0xb5,\n\t\t\t\t0x93, 0xe1, 0x0f, 0x85, 0xec, 0x9a, 0x66, 0x8e,\n\t\t\t\t0x61, 0x82, 0x88, 0xc8, 0xfc, 0xae, 0x1e, 0xca,\n\t\t\t\t0xd7, 0xa5, 0x63, 0x20, 0xbd, 0x1c, 0x00, 0x00,\n\t\t\t\t0x8b, 0xee, 0x09, 0xe3, 0x47, 0x6a, 0x0e, 0x74,\n\t\t\t\t0xb0, 0xbc, 0xa3, 0x02, 0xa7, 0x35, 0xe8, 0x85,\n\t\t\t\t0x70, 0x7c, 0x7a, 0xf0, 0x00, 0xdf, 0x4a, 0xea,\n\t\t\t\t0x87, 0x01, 0x14, 0x91, 0x00, 0x20, 0xea, 0xea,\n\t\t\t\t0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,\n\t\t\t\t0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13,\n\t\t\t\t0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d,\n\t\t\t\t0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,\n\t\t\t\t0x00, 0x81, 0x9a, 0x9a, 0x00, 0x00, 0xff, 0x01,\n\t\t\t\t0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,\n\t\t\t\t0x16, 0x00, 0x00, 0x13, 0x77, 0x77, 0x77, 0x30,\n\t\t\t\t0x37, 0x2e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x74,\n\t\t\t\t0x61, 0x6c, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x00,\n\t\t\t\t0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,\n\t\t\t\t0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,\n\t\t\t\t0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05,\n\t\t\t\t0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00,\n\t\t\t\t0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e,\n\t\t\t\t0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74,\n\t\t\t\t0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x75, 0x50,\n\t\t\t\t0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,\n\t\t\t\t0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x9a, 0x9a,\n\t\t\t\t0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x8a, 0x8a,\n\t\t\t\t0x00, 0x01, 0x00,\n\t\t\t},\n\t\t\tdomain: \"www07.clicktale.net\",\n\t\t\terr:    false,\n\t\t},\n\t\t{\n\t\t\tinput: []byte{\n\t\t\t\t0x16, 0x03, 0x01, 0x00, 0xe6, 0x01, 0x00, 0x00, 0xe2, 0x03, 0x03, 0x81, 0x47, 0xc1,\n\t\t\t\t0x66, 0xd5, 0x1b, 0xfa, 0x4b, 0xb5, 0xe0, 0x2a, 0xe1, 0xa7, 0x87, 0x13, 0x1d, 0x11, 0xaa, 0xc6,\n\t\t\t\t0xce, 0xfc, 0x7f, 0xab, 0x94, 0xc8, 0x62, 0xad, 0xc8, 0xab, 0x0c, 0xdd, 0xcb, 0x20, 0x6f, 0x9d,\n\t\t\t\t0x07, 0xf1, 0x95, 0x3e, 0x99, 0xd8, 0xf3, 0x6d, 0x97, 0xee, 0x19, 0x0b, 0x06, 0x1b, 0xf4, 0x84,\n\t\t\t\t0x0b, 0xb6, 0x8f, 0xcc, 0xde, 0xe2, 0xd0, 0x2d, 0x6b, 0x0c, 0x1f, 0x52, 0x53, 0x13, 0x00, 0x08,\n\t\t\t\t0x13, 0x02, 0x13, 0x03, 0x13, 0x01, 0x00, 0xff, 0x01, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x0c,\n\t\t\t\t0x00, 0x0a, 0x00, 0x00, 0x07, 0x64, 0x6f, 0x67, 0x66, 0x69, 0x73, 0x68, 0x00, 0x0b, 0x00, 0x04,\n\t\t\t\t0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x1e,\n\t\t\t\t0x00, 0x19, 0x00, 0x18, 0x00, 0x23, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00,\n\t\t\t\t0x00, 0x0d, 0x00, 0x1e, 0x00, 0x1c, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x07, 0x08, 0x08,\n\t\t\t\t0x08, 0x09, 0x08, 0x0a, 0x08, 0x0b, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01,\n\t\t\t\t0x06, 0x01, 0x00, 0x2b, 0x00, 0x07, 0x06, 0x7f, 0x1c, 0x7f, 0x1b, 0x7f, 0x1a, 0x00, 0x2d, 0x00,\n\t\t\t\t0x02, 0x01, 0x01, 0x00, 0x33, 0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x2f, 0x35, 0x0c,\n\t\t\t\t0xb6, 0x90, 0x0a, 0xb7, 0xd5, 0xc4, 0x1b, 0x2f, 0x60, 0xaa, 0x56, 0x7b, 0x3f, 0x71, 0xc8, 0x01,\n\t\t\t\t0x7e, 0x86, 0xd3, 0xb7, 0x0c, 0x29, 0x1a, 0x9e, 0x5b, 0x38, 0x3f, 0x01, 0x72,\n\t\t\t},\n\t\t\tdomain: \"dogfish\",\n\t\t\terr:    false,\n\t\t},\n\t\t{\n\t\t\tinput: []byte{\n\t\t\t\t0x16, 0x03, 0x01, 0x01, 0x03, 0x01, 0x00, 0x00,\n\t\t\t\t0xff, 0x03, 0x03, 0x3d, 0x89, 0x52, 0x9e, 0xee,\n\t\t\t\t0xbe, 0x17, 0x63, 0x75, 0xef, 0x29, 0xbd, 0x14,\n\t\t\t\t0x6a, 0x49, 0xe0, 0x2c, 0x37, 0x57, 0x71, 0x62,\n\t\t\t\t0x82, 0x44, 0x94, 0x8f, 0x6e, 0x94, 0x08, 0x45,\n\t\t\t\t0x7f, 0xdb, 0xc1, 0x00, 0x00, 0x3e, 0xc0, 0x2c,\n\t\t\t\t0xc0, 0x30, 0x00, 0x9f, 0xcc, 0xa9, 0xcc, 0xa8,\n\t\t\t\t0xcc, 0xaa, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,\n\t\t\t\t0xc0, 0x24, 0xc0, 0x28, 0x00, 0x6b, 0xc0, 0x23,\n\t\t\t\t0xc0, 0x27, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x14,\n\t\t\t\t0x00, 0x39, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33,\n\t\t\t\t0x00, 0x9d, 0x00, 0x9c, 0x13, 0x02, 0x13, 0x03,\n\t\t\t\t0x13, 0x01, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x35,\n\t\t\t\t0x00, 0x2f, 0x00, 0xff, 0x01, 0x00, 0x00, 0x98,\n\t\t\t\t0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00,\n\t\t\t\t0x0b, 0x31, 0x30, 0x2e, 0x34, 0x32, 0x2e, 0x30,\n\t\t\t\t0x2e, 0x32, 0x34, 0x33, 0x00, 0x0b, 0x00, 0x04,\n\t\t\t\t0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x0a,\n\t\t\t\t0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x19,\n\t\t\t\t0x00, 0x18, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d,\n\t\t\t\t0x00, 0x20, 0x00, 0x1e, 0x04, 0x03, 0x05, 0x03,\n\t\t\t\t0x06, 0x03, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06,\n\t\t\t\t0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03,\n\t\t\t\t0x02, 0x01, 0x02, 0x02, 0x04, 0x02, 0x05, 0x02,\n\t\t\t\t0x06, 0x02, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17,\n\t\t\t\t0x00, 0x00, 0x00, 0x2b, 0x00, 0x09, 0x08, 0x7f,\n\t\t\t\t0x14, 0x03, 0x03, 0x03, 0x02, 0x03, 0x01, 0x00,\n\t\t\t\t0x2d, 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x28,\n\t\t\t\t0x00, 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20,\n\t\t\t\t0x13, 0x7c, 0x6e, 0x97, 0xc4, 0xfd, 0x09, 0x2e,\n\t\t\t\t0x70, 0x2f, 0x73, 0x5a, 0x9b, 0x57, 0x4d, 0x5f,\n\t\t\t\t0x2b, 0x73, 0x2c, 0xa5, 0x4a, 0x98, 0x40, 0x3d,\n\t\t\t\t0x75, 0x6e, 0xb4, 0x76, 0xf9, 0x48, 0x8f, 0x36,\n\t\t\t},\n\t\t\tdomain: \"10.42.0.243\",\n\t\t\terr:    false,\n\t\t},\n\t}\n\n\tfor _, test := range cases {\n\t\theader, err := SniffTLS(test.input)\n\t\tif test.err {\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"Exepct error but nil in test %v\", test)\n\t\t\t}\n\t\t} else {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"Expect no error but actually %s in test %v\", err.Error(), test)\n\t\t\t}\n\t\t\tif header.Domain() != test.domain {\n\t\t\t\tt.Error(\"expect domain \", test.domain, \" but got \", header.Domain())\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/protocol/udp/packet.go",
    "content": "package udp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n// Packet is a UDP packet together with its source and destination address.\ntype Packet struct {\n\tPayload *buf.Buffer\n\tSource  net.Destination\n\tTarget  net.Destination\n}\n"
  },
  {
    "path": "common/protocol/udp/udp.go",
    "content": "package udp\n"
  },
  {
    "path": "common/protocol/user.go",
    "content": "package protocol\n\nimport \"github.com/v2fly/v2ray-core/v5/common/serial\"\n\nfunc (u *User) GetTypedAccount() (Account, error) {\n\tif u.GetAccount() == nil {\n\t\treturn nil, newError(\"Account missing\").AtWarning()\n\t}\n\n\trawAccount, err := serial.GetInstanceOf(u.Account)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif asAccount, ok := rawAccount.(AsAccount); ok {\n\t\treturn asAccount.AsAccount()\n\t}\n\tif account, ok := rawAccount.(Account); ok {\n\t\treturn account, nil\n\t}\n\treturn nil, newError(\"Unknown account type: \", serial.V2Type(u.Account))\n}\n\nfunc (u *User) ToMemoryUser() (*MemoryUser, error) {\n\taccount, err := u.GetTypedAccount()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MemoryUser{\n\t\tAccount: account,\n\t\tEmail:   u.Email,\n\t\tLevel:   u.Level,\n\t}, nil\n}\n\n// MemoryUser is a parsed form of User, to reduce number of parsing of Account proto.\ntype MemoryUser struct {\n\t// Account is the parsed account of the protocol.\n\tAccount Account\n\tEmail   string\n\tLevel   uint32\n}\n"
  },
  {
    "path": "common/protocol/user.pb.go",
    "content": "package protocol\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\tunsafe \"unsafe\"\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// User is a generic user for all procotols.\ntype User struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\tLevel uint32                 `protobuf:\"varint,1,opt,name=level,proto3\" json:\"level,omitempty\"`\n\tEmail string                 `protobuf:\"bytes,2,opt,name=email,proto3\" json:\"email,omitempty\"`\n\t// Protocol specific account information. Must be the account proto in one of\n\t// the proxies.\n\tAccount       *anypb.Any `protobuf:\"bytes,3,opt,name=account,proto3\" json:\"account,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *User) Reset() {\n\t*x = User{}\n\tmi := &file_common_protocol_user_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *User) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*User) ProtoMessage() {}\n\nfunc (x *User) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_protocol_user_proto_msgTypes[0]\n\tif 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 User.ProtoReflect.Descriptor instead.\nfunc (*User) Descriptor() ([]byte, []int) {\n\treturn file_common_protocol_user_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *User) GetLevel() uint32 {\n\tif x != nil {\n\t\treturn x.Level\n\t}\n\treturn 0\n}\n\nfunc (x *User) GetEmail() string {\n\tif x != nil {\n\t\treturn x.Email\n\t}\n\treturn \"\"\n}\n\nfunc (x *User) GetAccount() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Account\n\t}\n\treturn nil\n}\n\nvar File_common_protocol_user_proto protoreflect.FileDescriptor\n\nconst file_common_protocol_user_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1acommon/protocol/user.proto\\x12\\x1av2ray.core.common.protocol\\x1a\\x19google/protobuf/any.proto\\\"b\\n\" +\n\t\"\\x04User\\x12\\x14\\n\" +\n\t\"\\x05level\\x18\\x01 \\x01(\\rR\\x05level\\x12\\x14\\n\" +\n\t\"\\x05email\\x18\\x02 \\x01(\\tR\\x05email\\x12.\\n\" +\n\t\"\\aaccount\\x18\\x03 \\x01(\\v2\\x14.google.protobuf.AnyR\\aaccountBo\\n\" +\n\t\"\\x1ecom.v2ray.core.common.protocolP\\x01Z.github.com/v2fly/v2ray-core/v5/common/protocol\\xaa\\x02\\x1aV2Ray.Core.Common.Protocolb\\x06proto3\"\n\nvar (\n\tfile_common_protocol_user_proto_rawDescOnce sync.Once\n\tfile_common_protocol_user_proto_rawDescData []byte\n)\n\nfunc file_common_protocol_user_proto_rawDescGZIP() []byte {\n\tfile_common_protocol_user_proto_rawDescOnce.Do(func() {\n\t\tfile_common_protocol_user_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_protocol_user_proto_rawDesc), len(file_common_protocol_user_proto_rawDesc)))\n\t})\n\treturn file_common_protocol_user_proto_rawDescData\n}\n\nvar file_common_protocol_user_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_protocol_user_proto_goTypes = []any{\n\t(*User)(nil),      // 0: v2ray.core.common.protocol.User\n\t(*anypb.Any)(nil), // 1: google.protobuf.Any\n}\nvar file_common_protocol_user_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.common.protocol.User.account:type_name -> google.protobuf.Any\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_common_protocol_user_proto_init() }\nfunc file_common_protocol_user_proto_init() {\n\tif File_common_protocol_user_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: unsafe.Slice(unsafe.StringData(file_common_protocol_user_proto_rawDesc), len(file_common_protocol_user_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_protocol_user_proto_goTypes,\n\t\tDependencyIndexes: file_common_protocol_user_proto_depIdxs,\n\t\tMessageInfos:      file_common_protocol_user_proto_msgTypes,\n\t}.Build()\n\tFile_common_protocol_user_proto = out.File\n\tfile_common_protocol_user_proto_goTypes = nil\n\tfile_common_protocol_user_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/protocol/user.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.protocol;\noption csharp_namespace = \"V2Ray.Core.Common.Protocol\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/protocol\";\noption java_package = \"com.v2ray.core.common.protocol\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\n\n// User is a generic user for all procotols.\nmessage User {\n  uint32 level = 1;\n  string email = 2;\n\n  // Protocol specific account information. Must be the account proto in one of\n  // the proxies.\n  google.protobuf.Any account = 3;\n}\n"
  },
  {
    "path": "common/protoext/errors.generated.go",
    "content": "package protoext\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/protoext/extensions.go",
    "content": "package protoext\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/types/descriptorpb\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc GetMessageOptions(msgDesc protoreflect.MessageDescriptor) (*MessageOpt, error) {\n\tmsgOpt := msgDesc.Options().(*descriptorpb.MessageOptions)\n\tmsgOptRet, err := proto.GetExtension(msgOpt, E_MessageOpt)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to parse extension from message\").Base(err)\n\t}\n\treturn msgOptRet.(*MessageOpt), nil\n}\n\nfunc GetFieldOptions(fieldDesc protoreflect.FieldDescriptor) (*FieldOpt, error) {\n\tfieldOpt := fieldDesc.Options().(*descriptorpb.FieldOptions)\n\tmsgOptRet, err := proto.GetExtension(fieldOpt, E_FieldOpt)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to parse extension from message\").Base(err)\n\t}\n\treturn msgOptRet.(*FieldOpt), nil\n}\n"
  },
  {
    "path": "common/protoext/extensions.pb.go",
    "content": "package protoext\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tdescriptorpb \"google.golang.org/protobuf/types/descriptorpb\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 MessageOpt struct {\n\tstate                 protoimpl.MessageState `protogen:\"open.v1\"`\n\tType                  []string               `protobuf:\"bytes,1,rep,name=type,proto3\" json:\"type,omitempty\"`\n\tShortName             []string               `protobuf:\"bytes,2,rep,name=short_name,json=shortName,proto3\" json:\"short_name,omitempty\"`\n\tTransportOriginalName string                 `protobuf:\"bytes,86001,opt,name=transport_original_name,json=transportOriginalName,proto3\" json:\"transport_original_name,omitempty\"`\n\t// allow_restricted_mode_load allow this config to be loaded in restricted mode\n\t// this is typically used when a an attacker can control the content\n\tAllowRestrictedModeLoad bool `protobuf:\"varint,86002,opt,name=allow_restricted_mode_load,json=allowRestrictedModeLoad,proto3\" json:\"allow_restricted_mode_load,omitempty\"`\n\tunknownFields           protoimpl.UnknownFields\n\tsizeCache               protoimpl.SizeCache\n}\n\nfunc (x *MessageOpt) Reset() {\n\t*x = MessageOpt{}\n\tmi := &file_common_protoext_extensions_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *MessageOpt) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*MessageOpt) ProtoMessage() {}\n\nfunc (x *MessageOpt) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_protoext_extensions_proto_msgTypes[0]\n\tif 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 MessageOpt.ProtoReflect.Descriptor instead.\nfunc (*MessageOpt) Descriptor() ([]byte, []int) {\n\treturn file_common_protoext_extensions_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *MessageOpt) GetType() []string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn nil\n}\n\nfunc (x *MessageOpt) GetShortName() []string {\n\tif x != nil {\n\t\treturn x.ShortName\n\t}\n\treturn nil\n}\n\nfunc (x *MessageOpt) GetTransportOriginalName() string {\n\tif x != nil {\n\t\treturn x.TransportOriginalName\n\t}\n\treturn \"\"\n}\n\nfunc (x *MessageOpt) GetAllowRestrictedModeLoad() bool {\n\tif x != nil {\n\t\treturn x.AllowRestrictedModeLoad\n\t}\n\treturn false\n}\n\ntype FieldOpt struct {\n\tstate             protoimpl.MessageState `protogen:\"open.v1\"`\n\tAnyWants          []string               `protobuf:\"bytes,1,rep,name=any_wants,json=anyWants,proto3\" json:\"any_wants,omitempty\"`\n\tAllowedValues     []string               `protobuf:\"bytes,2,rep,name=allowed_values,json=allowedValues,proto3\" json:\"allowed_values,omitempty\"`\n\tAllowedValueTypes []string               `protobuf:\"bytes,3,rep,name=allowed_value_types,json=allowedValueTypes,proto3\" json:\"allowed_value_types,omitempty\"`\n\t// convert_time_read_file_into read a file into another field, and clear this field during input parsing\n\tConvertTimeReadFileInto string `protobuf:\"bytes,4,opt,name=convert_time_read_file_into,json=convertTimeReadFileInto,proto3\" json:\"convert_time_read_file_into,omitempty\"`\n\t// forbidden marks a boolean to be inaccessible to user\n\tForbidden bool `protobuf:\"varint,5,opt,name=forbidden,proto3\" json:\"forbidden,omitempty\"`\n\t// convert_time_resource_loading read a file, and place its resource hash into another field\n\tConvertTimeResourceLoading string `protobuf:\"bytes,6,opt,name=convert_time_resource_loading,json=convertTimeResourceLoading,proto3\" json:\"convert_time_resource_loading,omitempty\"`\n\t// convert_time_parse_ip parse a string ip address, and put its binary representation into another field\n\tConvertTimeParseIp string `protobuf:\"bytes,7,opt,name=convert_time_parse_ip,json=convertTimeParseIp,proto3\" json:\"convert_time_parse_ip,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *FieldOpt) Reset() {\n\t*x = FieldOpt{}\n\tmi := &file_common_protoext_extensions_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *FieldOpt) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FieldOpt) ProtoMessage() {}\n\nfunc (x *FieldOpt) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_protoext_extensions_proto_msgTypes[1]\n\tif 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 FieldOpt.ProtoReflect.Descriptor instead.\nfunc (*FieldOpt) Descriptor() ([]byte, []int) {\n\treturn file_common_protoext_extensions_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *FieldOpt) GetAnyWants() []string {\n\tif x != nil {\n\t\treturn x.AnyWants\n\t}\n\treturn nil\n}\n\nfunc (x *FieldOpt) GetAllowedValues() []string {\n\tif x != nil {\n\t\treturn x.AllowedValues\n\t}\n\treturn nil\n}\n\nfunc (x *FieldOpt) GetAllowedValueTypes() []string {\n\tif x != nil {\n\t\treturn x.AllowedValueTypes\n\t}\n\treturn nil\n}\n\nfunc (x *FieldOpt) GetConvertTimeReadFileInto() string {\n\tif x != nil {\n\t\treturn x.ConvertTimeReadFileInto\n\t}\n\treturn \"\"\n}\n\nfunc (x *FieldOpt) GetForbidden() bool {\n\tif x != nil {\n\t\treturn x.Forbidden\n\t}\n\treturn false\n}\n\nfunc (x *FieldOpt) GetConvertTimeResourceLoading() string {\n\tif x != nil {\n\t\treturn x.ConvertTimeResourceLoading\n\t}\n\treturn \"\"\n}\n\nfunc (x *FieldOpt) GetConvertTimeParseIp() string {\n\tif x != nil {\n\t\treturn x.ConvertTimeParseIp\n\t}\n\treturn \"\"\n}\n\nvar file_common_protoext_extensions_proto_extTypes = []protoimpl.ExtensionInfo{\n\t{\n\t\tExtendedType:  (*descriptorpb.MessageOptions)(nil),\n\t\tExtensionType: (*MessageOpt)(nil),\n\t\tField:         50000,\n\t\tName:          \"v2ray.core.common.protoext.message_opt\",\n\t\tTag:           \"bytes,50000,opt,name=message_opt\",\n\t\tFilename:      \"common/protoext/extensions.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.FieldOptions)(nil),\n\t\tExtensionType: (*FieldOpt)(nil),\n\t\tField:         50000,\n\t\tName:          \"v2ray.core.common.protoext.field_opt\",\n\t\tTag:           \"bytes,50000,opt,name=field_opt\",\n\t\tFilename:      \"common/protoext/extensions.proto\",\n\t},\n}\n\n// Extension fields to descriptorpb.MessageOptions.\nvar (\n\t// optional v2ray.core.common.protoext.MessageOpt message_opt = 50000;\n\tE_MessageOpt = &file_common_protoext_extensions_proto_extTypes[0]\n)\n\n// Extension fields to descriptorpb.FieldOptions.\nvar (\n\t// optional v2ray.core.common.protoext.FieldOpt field_opt = 50000;\n\tE_FieldOpt = &file_common_protoext_extensions_proto_extTypes[1]\n)\n\nvar File_common_protoext_extensions_proto protoreflect.FileDescriptor\n\nconst file_common_protoext_extensions_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\" common/protoext/extensions.proto\\x12\\x1av2ray.core.common.protoext\\x1a google/protobuf/descriptor.proto\\\"\\xb8\\x01\\n\" +\n\t\"\\n\" +\n\t\"MessageOpt\\x12\\x12\\n\" +\n\t\"\\x04type\\x18\\x01 \\x03(\\tR\\x04type\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"short_name\\x18\\x02 \\x03(\\tR\\tshortName\\x128\\n\" +\n\t\"\\x17transport_original_name\\x18\\xf1\\x9f\\x05 \\x01(\\tR\\x15transportOriginalName\\x12=\\n\" +\n\t\"\\x1aallow_restricted_mode_load\\x18\\xf2\\x9f\\x05 \\x01(\\bR\\x17allowRestrictedModeLoad\\\"\\xd0\\x02\\n\" +\n\t\"\\bFieldOpt\\x12\\x1b\\n\" +\n\t\"\\tany_wants\\x18\\x01 \\x03(\\tR\\banyWants\\x12%\\n\" +\n\t\"\\x0eallowed_values\\x18\\x02 \\x03(\\tR\\rallowedValues\\x12.\\n\" +\n\t\"\\x13allowed_value_types\\x18\\x03 \\x03(\\tR\\x11allowedValueTypes\\x12<\\n\" +\n\t\"\\x1bconvert_time_read_file_into\\x18\\x04 \\x01(\\tR\\x17convertTimeReadFileInto\\x12\\x1c\\n\" +\n\t\"\\tforbidden\\x18\\x05 \\x01(\\bR\\tforbidden\\x12A\\n\" +\n\t\"\\x1dconvert_time_resource_loading\\x18\\x06 \\x01(\\tR\\x1aconvertTimeResourceLoading\\x121\\n\" +\n\t\"\\x15convert_time_parse_ip\\x18\\a \\x01(\\tR\\x12convertTimeParseIp:j\\n\" +\n\t\"\\vmessage_opt\\x12\\x1f.google.protobuf.MessageOptions\\x18І\\x03 \\x01(\\v2&.v2ray.core.common.protoext.MessageOptR\\n\" +\n\t\"messageOpt:b\\n\" +\n\t\"\\tfield_opt\\x12\\x1d.google.protobuf.FieldOptions\\x18І\\x03 \\x01(\\v2$.v2ray.core.common.protoext.FieldOptR\\bfieldOptBo\\n\" +\n\t\"\\x1ecom.v2ray.core.common.protoextP\\x01Z.github.com/v2fly/v2ray-core/v5/common/protoext\\xaa\\x02\\x1aV2Ray.Core.Common.ProtoExtb\\x06proto3\"\n\nvar (\n\tfile_common_protoext_extensions_proto_rawDescOnce sync.Once\n\tfile_common_protoext_extensions_proto_rawDescData []byte\n)\n\nfunc file_common_protoext_extensions_proto_rawDescGZIP() []byte {\n\tfile_common_protoext_extensions_proto_rawDescOnce.Do(func() {\n\t\tfile_common_protoext_extensions_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_protoext_extensions_proto_rawDesc), len(file_common_protoext_extensions_proto_rawDesc)))\n\t})\n\treturn file_common_protoext_extensions_proto_rawDescData\n}\n\nvar file_common_protoext_extensions_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_common_protoext_extensions_proto_goTypes = []any{\n\t(*MessageOpt)(nil),                  // 0: v2ray.core.common.protoext.MessageOpt\n\t(*FieldOpt)(nil),                    // 1: v2ray.core.common.protoext.FieldOpt\n\t(*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions\n\t(*descriptorpb.FieldOptions)(nil),   // 3: google.protobuf.FieldOptions\n}\nvar file_common_protoext_extensions_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.common.protoext.message_opt:extendee -> google.protobuf.MessageOptions\n\t3, // 1: v2ray.core.common.protoext.field_opt:extendee -> google.protobuf.FieldOptions\n\t0, // 2: v2ray.core.common.protoext.message_opt:type_name -> v2ray.core.common.protoext.MessageOpt\n\t1, // 3: v2ray.core.common.protoext.field_opt:type_name -> v2ray.core.common.protoext.FieldOpt\n\t4, // [4:4] is the sub-list for method output_type\n\t4, // [4:4] is the sub-list for method input_type\n\t2, // [2:4] is the sub-list for extension type_name\n\t0, // [0:2] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_common_protoext_extensions_proto_init() }\nfunc file_common_protoext_extensions_proto_init() {\n\tif File_common_protoext_extensions_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: unsafe.Slice(unsafe.StringData(file_common_protoext_extensions_proto_rawDesc), len(file_common_protoext_extensions_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 2,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_protoext_extensions_proto_goTypes,\n\t\tDependencyIndexes: file_common_protoext_extensions_proto_depIdxs,\n\t\tMessageInfos:      file_common_protoext_extensions_proto_msgTypes,\n\t\tExtensionInfos:    file_common_protoext_extensions_proto_extTypes,\n\t}.Build()\n\tFile_common_protoext_extensions_proto = out.File\n\tfile_common_protoext_extensions_proto_goTypes = nil\n\tfile_common_protoext_extensions_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/protoext/extensions.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.protoext;\noption csharp_namespace = \"V2Ray.Core.Common.ProtoExt\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/protoext\";\noption java_package = \"com.v2ray.core.common.protoext\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/descriptor.proto\";\n\nextend google.protobuf.MessageOptions {\n  MessageOpt message_opt = 50000;\n}\n\nextend google.protobuf.FieldOptions {\n  FieldOpt field_opt = 50000;\n}\n\nmessage MessageOpt{\n  repeated string type = 1;\n  repeated string short_name = 2;\n\n  string transport_original_name = 86001;\n\n  // allow_restricted_mode_load allow this config to be loaded in restricted mode\n  // this is typically used when a an attacker can control the content\n  bool allow_restricted_mode_load = 86002;\n}\n\nmessage FieldOpt{\n  repeated string any_wants = 1;\n  repeated string allowed_values = 2;\n  repeated string allowed_value_types = 3;\n\n  // convert_time_read_file_into read a file into another field, and clear this field during input parsing\n  string convert_time_read_file_into = 4;\n  // forbidden marks a boolean to be inaccessible to user\n  bool forbidden = 5;\n  // convert_time_resource_loading read a file, and place its resource hash into another field\n  string convert_time_resource_loading = 6;\n  // convert_time_parse_ip parse a string ip address, and put its binary representation into another field\n  string convert_time_parse_ip = 7;\n}"
  },
  {
    "path": "common/protoext/testing/extension_test.go",
    "content": "package testing\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protoext\"\n)\n\nfunc TestMessageOpt(t *testing.T) {\n\tmsg := TestingMessage{}\n\topt, err := protoext.GetMessageOptions(msg.ProtoReflect().Descriptor())\n\tassert.Nil(t, err)\n\tassert.EqualValues(t, []string{\"demo\", \"demo2\"}, opt.Type)\n}\n\nfunc TestFieldOpt(t *testing.T) {\n\tmsg := TestingMessage{\n\t\tTestField: \"Test\",\n\t}\n\tmsgreflect := msg.ProtoReflect()\n\tmsgreflect.Range(func(descriptor protoreflect.FieldDescriptor, value protoreflect.Value) bool {\n\t\topt, err := protoext.GetFieldOptions(descriptor)\n\t\tassert.Nil(t, err)\n\t\tassert.EqualValues(t, []string{\"test\", \"test2\"}, opt.AllowedValues)\n\t\treturn true\n\t})\n}\n"
  },
  {
    "path": "common/protoext/testing/test.pb.go",
    "content": "package testing\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 TestingMessage struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTestField     string                 `protobuf:\"bytes,1,opt,name=test_field,json=testField,proto3\" json:\"test_field,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *TestingMessage) Reset() {\n\t*x = TestingMessage{}\n\tmi := &file_common_protoext_testing_test_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TestingMessage) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TestingMessage) ProtoMessage() {}\n\nfunc (x *TestingMessage) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_protoext_testing_test_proto_msgTypes[0]\n\tif 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 TestingMessage.ProtoReflect.Descriptor instead.\nfunc (*TestingMessage) Descriptor() ([]byte, []int) {\n\treturn file_common_protoext_testing_test_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *TestingMessage) GetTestField() string {\n\tif x != nil {\n\t\treturn x.TestField\n\t}\n\treturn \"\"\n}\n\nvar File_common_protoext_testing_test_proto protoreflect.FileDescriptor\n\nconst file_common_protoext_testing_test_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\\"common/protoext/testing/test.proto\\x12\\\"v2ray.core.common.protoext.testing\\x1a common/protoext/extensions.proto\\\"U\\n\" +\n\t\"\\x0eTestingMessage\\x120\\n\" +\n\t\"\\n\" +\n\t\"test_field\\x18\\x01 \\x01(\\tB\\x11\\x82\\xb5\\x18\\r\\x12\\x04test\\x12\\x05test2R\\ttestField:\\x11\\x82\\xb5\\x18\\r\\n\" +\n\t\"\\x04demo\\n\" +\n\t\"\\x05demo2B\\x84\\x01\\n\" +\n\t\"&com.v2ray.core.common.protoext.testingP\\x01Z3github.com/v2fly/v2ray-core/common/protoext/testing\\xaa\\x02\\\"V2Ray.Core.Common.ProtoExt.Testingb\\x06proto3\"\n\nvar (\n\tfile_common_protoext_testing_test_proto_rawDescOnce sync.Once\n\tfile_common_protoext_testing_test_proto_rawDescData []byte\n)\n\nfunc file_common_protoext_testing_test_proto_rawDescGZIP() []byte {\n\tfile_common_protoext_testing_test_proto_rawDescOnce.Do(func() {\n\t\tfile_common_protoext_testing_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_protoext_testing_test_proto_rawDesc), len(file_common_protoext_testing_test_proto_rawDesc)))\n\t})\n\treturn file_common_protoext_testing_test_proto_rawDescData\n}\n\nvar file_common_protoext_testing_test_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_common_protoext_testing_test_proto_goTypes = []any{\n\t(*TestingMessage)(nil), // 0: v2ray.core.common.protoext.testing.TestingMessage\n}\nvar file_common_protoext_testing_test_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_common_protoext_testing_test_proto_init() }\nfunc file_common_protoext_testing_test_proto_init() {\n\tif File_common_protoext_testing_test_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: unsafe.Slice(unsafe.StringData(file_common_protoext_testing_test_proto_rawDesc), len(file_common_protoext_testing_test_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_protoext_testing_test_proto_goTypes,\n\t\tDependencyIndexes: file_common_protoext_testing_test_proto_depIdxs,\n\t\tMessageInfos:      file_common_protoext_testing_test_proto_msgTypes,\n\t}.Build()\n\tFile_common_protoext_testing_test_proto = out.File\n\tfile_common_protoext_testing_test_proto_goTypes = nil\n\tfile_common_protoext_testing_test_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/protoext/testing/test.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.protoext.testing;\noption csharp_namespace = \"V2Ray.Core.Common.ProtoExt.Testing\";\noption go_package = \"github.com/v2fly/v2ray-core/common/protoext/testing\";\noption java_package = \"com.v2ray.core.common.protoext.testing\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage TestingMessage{\n  option (v2ray.core.common.protoext.message_opt).type = \"demo\";\n  option (v2ray.core.common.protoext.message_opt).type = \"demo2\";\n\n  string test_field = 1\n  [(v2ray.core.common.protoext.field_opt).allowed_values = \"test\",\n    (v2ray.core.common.protoext.field_opt).allowed_values = \"test2\"];\n}"
  },
  {
    "path": "common/protofilter/errors.generated.go",
    "content": "package protofilter\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/protofilter/filter.go",
    "content": "package protofilter\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/filesystemcap\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protoext\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc FilterProtoConfig(ctx context.Context, config proto.Message) error {\n\tmessageProtoReflect := config.ProtoReflect()\n\treturn filterMessage(ctx, messageProtoReflect)\n}\n\nfunc filterMessage(ctx context.Context, message protoreflect.Message) error {\n\tvar err error\n\ttype fileRead struct {\n\t\tfilename string\n\t\tfield    string\n\t}\n\tvar fileReadingQueue []fileRead\n\n\ttype pendingWrite struct {\n\t\tfield protoreflect.FieldDescriptor\n\t\tvalue protoreflect.Value\n\t}\n\n\tvar pendingWriteQueue []pendingWrite\n\n\tmessage.Range(func(descriptor protoreflect.FieldDescriptor, value protoreflect.Value) bool {\n\t\tv2extension, ferr := protoext.GetFieldOptions(descriptor)\n\t\tif ferr == nil {\n\t\t\tif v2extension.Forbidden {\n\t\t\t\tif value.Bool() {\n\t\t\t\t\terr = newError(\"a forbidden value is set \", descriptor.FullName())\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif v2extension.ConvertTimeReadFileInto != \"\" {\n\t\t\t\tfileReadingQueue = append(fileReadingQueue, fileRead{\n\t\t\t\t\tfilename: value.String(),\n\t\t\t\t\tfield:    v2extension.ConvertTimeReadFileInto,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif v2extension.ConvertTimeParseIp != \"\" {\n\t\t\t\tipValue := net.ParseIP(value.String())\n\t\t\t\ttarget := message.Descriptor().Fields().ByTextName(v2extension.ConvertTimeParseIp)\n\t\t\t\tif ipValue.To4() != nil {\n\t\t\t\t\tipValue = ipValue.To4()\n\t\t\t\t}\n\t\t\t\tpendingWriteQueue = append(pendingWriteQueue, pendingWrite{\n\t\t\t\t\tfield: target,\n\t\t\t\t\tvalue: protoreflect.ValueOf([]byte(ipValue)),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tswitch descriptor.Kind() {\n\t\tcase protoreflect.MessageKind:\n\t\t\tif descriptor.IsMap() {\n\t\t\t\terr = filterMap(ctx, value.Map())\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif descriptor.IsList() {\n\t\t\t\terr = filterList(ctx, value.List())\n\t\t\t\tbreak\n\t\t\t}\n\t\t\terr = filterMessage(ctx, value.Message())\n\t\t}\n\t\treturn true\n\t})\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfsenvironment := envctx.EnvironmentFromContext(ctx)\n\tfsifce, fsifceOk := fsenvironment.(filesystemcap.FileSystemCapabilitySet)\n\tfor _, v := range fileReadingQueue {\n\t\tif !fsifceOk {\n\t\t\treturn newError(\"unable to read file as filesystem capability is not given\")\n\t\t}\n\t\tfield := message.Descriptor().Fields().ByTextName(v.field)\n\t\tif v.filename == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(message.Get(field).Bytes()) > 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tfile, err := fsifce.OpenFileForRead()(v.filename)\n\t\tif err != nil {\n\t\t\treturn newError(\"unable to open file\").Base(err)\n\t\t}\n\t\tfileContent, err := io.ReadAll(file)\n\t\tif err != nil {\n\t\t\treturn newError(\"unable to read file\").Base(err)\n\t\t}\n\t\tfile.Close()\n\t\tmessage.Set(field, protoreflect.ValueOf(fileContent))\n\t}\n\n\tfor _, v := range pendingWriteQueue {\n\t\tmessage.Set(v.field, v.value)\n\t}\n\treturn nil\n}\n\nfunc filterMap(ctx context.Context, mapValue protoreflect.Map) error {\n\tvar err error\n\tmapValue.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool {\n\t\terr = filterMessage(ctx, value.Message())\n\t\treturn err == nil\n\t})\n\treturn err\n}\n\nfunc filterList(ctx context.Context, listValue protoreflect.List) error {\n\tvar err error\n\tsize := listValue.Len()\n\tfor i := 0; i < size; i++ {\n\t\terr = filterMessage(ctx, listValue.Get(i).Message())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "common/registry/errors.generated.go",
    "content": "package registry\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/registry/implementation_set.go",
    "content": "package registry\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protoext\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype implementationSet struct {\n\tAliasLookup map[string]*implementation\n}\n\ntype CustomLoader func(data []byte, loader LoadByAlias) (proto.Message, error)\n\ntype implementation struct {\n\tFullName string\n\tAlias    []string\n\tLoader   CustomLoader\n}\n\nfunc (i *implementationSet) RegisterImplementation(name string, opt *protoext.MessageOpt, loader CustomLoader) {\n\talias := opt.GetShortName()\n\n\timpl := &implementation{\n\t\tFullName: name,\n\t\tAlias:    alias,\n\t}\n\n\tfor _, aliasName := range alias {\n\t\ti.AliasLookup[aliasName] = impl\n\t}\n}\n\nfunc (i *implementationSet) findImplementationByAlias(alias string) (string, CustomLoader, error) {\n\timpl, found := i.AliasLookup[alias]\n\tif found {\n\t\treturn impl.FullName, impl.Loader, nil\n\t}\n\treturn \"\", nil, newError(\"cannot find implementation by alias: \", alias)\n}\n\nfunc newImplementationSet() *implementationSet {\n\treturn &implementationSet{AliasLookup: map[string]*implementation{}}\n}\n"
  },
  {
    "path": "common/registry/registry.go",
    "content": "package registry\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n\t\"github.com/golang/protobuf/proto\"\n\tprotov2 \"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protofilter\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype implementationRegistry struct {\n\timplSet map[string]*implementationSet\n}\n\nfunc (i *implementationRegistry) RegisterImplementation(name string, opt *protoext.MessageOpt, loader CustomLoader) {\n\tinterfaceType := opt.GetType()\n\tfor _, v := range interfaceType {\n\t\ti.registerSingleImplementation(v, name, opt, loader)\n\t}\n}\n\nfunc (i *implementationRegistry) registerSingleImplementation(interfaceType, name string, opt *protoext.MessageOpt, loader CustomLoader) {\n\timplSet, found := i.implSet[interfaceType]\n\tif !found {\n\t\timplSet = newImplementationSet()\n\t\ti.implSet[interfaceType] = implSet\n\t}\n\timplSet.RegisterImplementation(name, opt, loader)\n}\n\nfunc (i *implementationRegistry) findImplementationByAlias(interfaceType, alias string) (string, CustomLoader, error) {\n\timplSet, found := i.implSet[interfaceType]\n\tif !found {\n\t\treturn \"\", nil, newError(\"cannot find implemention unknown interface type\")\n\t}\n\treturn implSet.findImplementationByAlias(alias)\n}\n\nfunc (i *implementationRegistry) LoadImplementationByAlias(ctx context.Context, interfaceType, alias string, data []byte) (proto.Message, error) {\n\tvar implementationFullName string\n\n\tif strings.HasPrefix(alias, \"#\") {\n\t\t// skip resolution for full name\n\t\timplementationFullName, _ = strings.CutPrefix(alias, \"#\")\n\t} else {\n\t\tregistryResult, customLoader, err := i.findImplementationByAlias(interfaceType, alias)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to find implementation\").Base(err)\n\t\t}\n\t\tif customLoader != nil {\n\t\t\treturn customLoader(data, i)\n\t\t}\n\t\timplementationFullName = registryResult\n\t}\n\timplementationConfigInstance, err := serial.GetInstance(implementationFullName)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create implementation config instance\").Base(err)\n\t}\n\n\tunmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: false}\n\terr = unmarshaler.Unmarshal(bytes.NewReader(data), implementationConfigInstance.(proto.Message))\n\tif err != nil {\n\t\treturn nil, newError(\"unable to parse json content\").Base(err)\n\t}\n\n\timplementationConfigInstancev2 := proto.MessageV2(implementationConfigInstance)\n\n\tif isRestrictedModeContext(ctx) {\n\t\tif err := enforceRestriction(implementationConfigInstancev2); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif err := protofilter.FilterProtoConfig(ctx, implementationConfigInstancev2); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn implementationConfigInstance.(proto.Message), nil\n}\n\nfunc newImplementationRegistry() *implementationRegistry {\n\treturn &implementationRegistry{implSet: map[string]*implementationSet{}}\n}\n\nvar globalImplementationRegistry = newImplementationRegistry()\n\nvar initialized = &sync.Once{}\n\ntype registerRequest struct {\n\tproto  interface{}\n\tloader CustomLoader\n}\n\nvar registerRequests []registerRequest\n\n// RegisterImplementation register an implementation of a type of interface\n// loader(CustomLoader) is a private API, its interface is subject to breaking changes\nfunc RegisterImplementation(proto interface{}, loader CustomLoader) error {\n\tregisterRequests = append(registerRequests, registerRequest{\n\t\tproto:  proto,\n\t\tloader: loader,\n\t})\n\treturn nil\n}\n\nfunc registerImplementation(proto interface{}, loader CustomLoader) error {\n\tprotoReflect := reflect.New(reflect.TypeOf(proto).Elem())\n\tproto2 := protoReflect.Interface().(protov2.Message)\n\tmsgDesc := proto2.ProtoReflect().Descriptor()\n\tfullName := string(msgDesc.FullName())\n\tmsgOpts, err := protoext.GetMessageOptions(msgDesc)\n\tif err != nil {\n\t\treturn newError(\"unable to find message options\").Base(err)\n\t}\n\tglobalImplementationRegistry.RegisterImplementation(fullName, msgOpts, loader)\n\treturn nil\n}\n\ntype LoadByAlias interface {\n\tLoadImplementationByAlias(ctx context.Context, interfaceType, alias string, data []byte) (proto.Message, error)\n}\n\nfunc LoadImplementationByAlias(ctx context.Context, interfaceType, alias string, data []byte) (proto.Message, error) {\n\tinitialized.Do(func() {\n\t\tfor _, v := range registerRequests {\n\t\t\tregisterImplementation(v.proto, v.loader)\n\t\t}\n\t})\n\treturn globalImplementationRegistry.LoadImplementationByAlias(ctx, interfaceType, alias, data)\n}\n"
  },
  {
    "path": "common/registry/restrict.go",
    "content": "package registry\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protoext\"\n)\n\nconst restrictedLoadModeCtx = \"restrictedLoadModeCtx\"\n\nfunc CreateRestrictedModeContext(ctx context.Context) context.Context {\n\treturn context.WithValue(ctx, restrictedLoadModeCtx, true) //nolint: staticcheck\n}\n\nfunc isRestrictedModeContext(ctx context.Context) bool {\n\tv := ctx.Value(restrictedLoadModeCtx)\n\tif v == nil {\n\t\treturn false\n\t}\n\treturn v.(bool)\n}\n\nfunc enforceRestriction(config proto.Message) error {\n\tconfigDescriptor := config.ProtoReflect().Descriptor()\n\tmsgOpts, err := protoext.GetMessageOptions(configDescriptor)\n\tif err != nil {\n\t\treturn newError(\"unable to find message options\").Base(err)\n\t}\n\tif !msgOpts.AllowRestrictedModeLoad {\n\t\treturn newError(\"component has not opted in for load in restricted mode\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "common/retry/errors.generated.go",
    "content": "package retry\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/retry/retry.go",
    "content": "package retry\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"time\"\n)\n\nvar ErrRetryFailed = newError(\"all retry attempts failed\")\n\n// Strategy is a way to retry on a specific function.\ntype Strategy interface {\n\t// On performs a retry on a specific function, until it doesn't return any error.\n\tOn(func() error) error\n}\n\ntype retryer struct {\n\ttotalAttempt int\n\tnextDelay    func() uint32\n}\n\n// On implements Strategy.On.\nfunc (r *retryer) On(method func() error) error {\n\tattempt := 0\n\taccumulatedError := make([]error, 0, r.totalAttempt)\n\tfor attempt < r.totalAttempt {\n\t\terr := method()\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tnumErrors := len(accumulatedError)\n\t\tif numErrors == 0 || err.Error() != accumulatedError[numErrors-1].Error() {\n\t\t\taccumulatedError = append(accumulatedError, err)\n\t\t}\n\t\tdelay := r.nextDelay()\n\t\ttime.Sleep(time.Duration(delay) * time.Millisecond)\n\t\tattempt++\n\t}\n\treturn newError(accumulatedError).Base(ErrRetryFailed)\n}\n\n// Timed returns a retry strategy with fixed interval.\nfunc Timed(attempts int, delay uint32) Strategy {\n\treturn &retryer{\n\t\ttotalAttempt: attempts,\n\t\tnextDelay: func() uint32 {\n\t\t\treturn delay\n\t\t},\n\t}\n}\n\nfunc ExponentialBackoff(attempts int, delay uint32) Strategy {\n\tnextDelay := uint32(0)\n\treturn &retryer{\n\t\ttotalAttempt: attempts,\n\t\tnextDelay: func() uint32 {\n\t\t\tr := nextDelay\n\t\t\tnextDelay += delay\n\t\t\treturn r\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "common/retry/retry_test.go",
    "content": "package retry_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/retry\"\n)\n\nvar errorTestOnly = errors.New(\"this is a fake error\")\n\nfunc TestNoRetry(t *testing.T) {\n\tstartTime := time.Now().Unix()\n\terr := Timed(10, 100000).On(func() error {\n\t\treturn nil\n\t})\n\tendTime := time.Now().Unix()\n\n\tcommon.Must(err)\n\tif endTime < startTime {\n\t\tt.Error(\"endTime < startTime: \", startTime, \" -> \", endTime)\n\t}\n}\n\nfunc TestRetryOnce(t *testing.T) {\n\tstartTime := time.Now()\n\tcalled := 0\n\terr := Timed(10, 1000).On(func() error {\n\t\tif called == 0 {\n\t\t\tcalled++\n\t\t\treturn errorTestOnly\n\t\t}\n\t\treturn nil\n\t})\n\tduration := time.Since(startTime)\n\n\tcommon.Must(err)\n\tif v := int64(duration / time.Millisecond); v < 900 {\n\t\tt.Error(\"duration: \", v)\n\t}\n}\n\nfunc TestRetryMultiple(t *testing.T) {\n\tstartTime := time.Now()\n\tcalled := 0\n\terr := Timed(10, 1000).On(func() error {\n\t\tif called < 5 {\n\t\t\tcalled++\n\t\t\treturn errorTestOnly\n\t\t}\n\t\treturn nil\n\t})\n\tduration := time.Since(startTime)\n\n\tcommon.Must(err)\n\tif v := int64(duration / time.Millisecond); v < 4900 {\n\t\tt.Error(\"duration: \", v)\n\t}\n}\n\nfunc TestRetryExhausted(t *testing.T) {\n\tstartTime := time.Now()\n\tcalled := 0\n\terr := Timed(2, 1000).On(func() error {\n\t\tcalled++\n\t\treturn errorTestOnly\n\t})\n\tduration := time.Since(startTime)\n\n\tif errors.Cause(err) != ErrRetryFailed {\n\t\tt.Error(\"cause: \", err)\n\t}\n\n\tif v := int64(duration / time.Millisecond); v < 1900 {\n\t\tt.Error(\"duration: \", v)\n\t}\n}\n\nfunc TestExponentialBackoff(t *testing.T) {\n\tstartTime := time.Now()\n\tcalled := 0\n\terr := ExponentialBackoff(10, 100).On(func() error {\n\t\tcalled++\n\t\treturn errorTestOnly\n\t})\n\tduration := time.Since(startTime)\n\n\tif errors.Cause(err) != ErrRetryFailed {\n\t\tt.Error(\"cause: \", err)\n\t}\n\tif v := int64(duration / time.Millisecond); v < 4000 {\n\t\tt.Error(\"duration: \", v)\n\t}\n}\n"
  },
  {
    "path": "common/serial/resolver.go",
    "content": "package serial\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n)\n\ntype AnyResolver interface {\n\tResolve(typeURL string) (proto.Message, error)\n}\n\ntype serialResolver struct{}\n\nfunc (s serialResolver) Resolve(typeURL string) (proto.Message, error) {\n\tinstance, err := GetInstance(typeURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn instance.(proto.Message), nil\n}\n\nfunc GetResolver() AnyResolver {\n\treturn &serialResolver{}\n}\n"
  },
  {
    "path": "common/serial/serial.go",
    "content": "package serial\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n)\n\n// ReadUint16 reads first two bytes from the reader, and then coverts them to an uint16 value.\nfunc ReadUint16(reader io.Reader) (uint16, error) {\n\tvar b [2]byte\n\tif _, err := io.ReadFull(reader, b[:]); err != nil {\n\t\treturn 0, err\n\t}\n\treturn binary.BigEndian.Uint16(b[:]), nil\n}\n\n// WriteUint16 writes an uint16 value into writer.\nfunc WriteUint16(writer io.Writer, value uint16) (int, error) {\n\tvar b [2]byte\n\tbinary.BigEndian.PutUint16(b[:], value)\n\treturn writer.Write(b[:])\n}\n\n// WriteUint64 writes an uint64 value into writer.\nfunc WriteUint64(writer io.Writer, value uint64) (int, error) {\n\tvar b [8]byte\n\tbinary.BigEndian.PutUint64(b[:], value)\n\treturn writer.Write(b[:])\n}\n"
  },
  {
    "path": "common/serial/serial_test.go",
    "content": "package serial_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc TestUint16Serial(t *testing.T) {\n\tb := buf.New()\n\tdefer b.Release()\n\n\tn, err := serial.WriteUint16(b, 10)\n\tcommon.Must(err)\n\tif n != 2 {\n\t\tt.Error(\"expect 2 bytes writtng, but actually \", n)\n\t}\n\tif diff := cmp.Diff(b.Bytes(), []byte{0, 10}); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n\nfunc TestUint64Serial(t *testing.T) {\n\tb := buf.New()\n\tdefer b.Release()\n\n\tn, err := serial.WriteUint64(b, 10)\n\tcommon.Must(err)\n\tif n != 8 {\n\t\tt.Error(\"expect 8 bytes writtng, but actually \", n)\n\t}\n\tif diff := cmp.Diff(b.Bytes(), []byte{0, 0, 0, 0, 0, 0, 0, 10}); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n\nfunc TestReadUint16(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput  []byte\n\t\tOutput uint16\n\t}{\n\t\t{\n\t\t\tInput:  []byte{0, 1},\n\t\t\tOutput: 1,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tv, err := serial.ReadUint16(bytes.NewReader(testCase.Input))\n\t\tcommon.Must(err)\n\t\tif v != testCase.Output {\n\t\t\tt.Error(\"for input \", testCase.Input, \" expect output \", testCase.Output, \" but got \", v)\n\t\t}\n\t}\n}\n\nfunc BenchmarkReadUint16(b *testing.B) {\n\treader := buf.New()\n\tdefer reader.Release()\n\n\tcommon.Must2(reader.Write([]byte{0, 1}))\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, err := serial.ReadUint16(reader)\n\t\tcommon.Must(err)\n\t\treader.Clear()\n\t\treader.Extend(2)\n\t}\n}\n\nfunc BenchmarkWriteUint64(b *testing.B) {\n\twriter := buf.New()\n\tdefer writer.Release()\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, err := serial.WriteUint64(writer, 8)\n\t\tcommon.Must(err)\n\t\twriter.Clear()\n\t}\n}\n"
  },
  {
    "path": "common/serial/string.go",
    "content": "package serial\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// ToString serialize an arbitrary value into string.\nfunc ToString(v interface{}) string {\n\tif v == nil {\n\t\treturn \"\"\n\t}\n\n\tswitch value := v.(type) {\n\tcase string:\n\t\treturn value\n\tcase *string:\n\t\treturn *value\n\tcase fmt.Stringer:\n\t\treturn value.String()\n\tcase error:\n\t\treturn value.Error()\n\tdefault:\n\t\treturn fmt.Sprintf(\"%+v\", value)\n\t}\n}\n\n// Concat concatenates all input into a single string.\nfunc Concat(v ...interface{}) string {\n\tbuilder := strings.Builder{}\n\tfor _, value := range v {\n\t\tbuilder.WriteString(ToString(value))\n\t}\n\treturn builder.String()\n}\n"
  },
  {
    "path": "common/serial/string_test.go",
    "content": "package serial_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc TestToString(t *testing.T) {\n\ts := \"a\"\n\tdata := []struct {\n\t\tValue  interface{}\n\t\tString string\n\t}{\n\t\t{Value: s, String: s},\n\t\t{Value: &s, String: s},\n\t\t{Value: errors.New(\"t\"), String: \"t\"},\n\t\t{Value: []byte{'b', 'c'}, String: \"[98 99]\"},\n\t}\n\n\tfor _, c := range data {\n\t\tif r := cmp.Diff(ToString(c.Value), c.String); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t}\n}\n\nfunc TestConcat(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput  []interface{}\n\t\tOutput string\n\t}{\n\t\t{\n\t\t\tInput: []interface{}{\n\t\t\t\t\"a\", \"b\",\n\t\t\t},\n\t\t\tOutput: \"ab\",\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tactual := Concat(testCase.Input...)\n\t\tif actual != testCase.Output {\n\t\t\tt.Error(\"Unexpected output: \", actual, \" but want: \", testCase.Output)\n\t\t}\n\t}\n}\n\nfunc BenchmarkConcat(b *testing.B) {\n\tinput := []interface{}{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\"}\n\n\tb.ReportAllocs()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = Concat(input...)\n\t}\n}\n"
  },
  {
    "path": "common/serial/typed_message.go",
    "content": "package serial\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n)\n\nconst V2RayTypeURLHeader = \"types.v2fly.org/\"\n\n// ToTypedMessage converts a proto Message into TypedMessage.\nfunc ToTypedMessage(message proto.Message) *anypb.Any {\n\tif message == nil {\n\t\treturn nil\n\t}\n\tsettings, _ := proto.Marshal(message)\n\treturn &anypb.Any{\n\t\tTypeUrl: V2RayTypeURLHeader + GetMessageType(message),\n\t\tValue:   settings,\n\t}\n}\n\n// GetMessageType returns the name of this proto Message.\nfunc GetMessageType(message proto.Message) string {\n\treturn proto.MessageName(message)\n}\n\n// GetInstance creates a new instance of the message with messageType.\nfunc GetInstance(messageType string) (interface{}, error) {\n\tmType := proto.MessageType(messageType)\n\tif mType == nil || mType.Elem() == nil {\n\t\treturn nil, errors.New(\"Serial: Unknown type: \" + messageType)\n\t}\n\treturn reflect.New(mType.Elem()).Interface(), nil\n}\n\nfunc GetInstanceOf(v *anypb.Any) (proto.Message, error) {\n\tinstance, err := GetInstance(V2TypeFromURL(v.TypeUrl))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tprotoMessage := instance.(proto.Message)\n\tif err := proto.Unmarshal(v.Value, protoMessage); err != nil {\n\t\treturn nil, err\n\t}\n\treturn protoMessage, nil\n}\n\nfunc V2Type(v *anypb.Any) string {\n\treturn V2TypeFromURL(v.TypeUrl)\n}\n\nfunc V2TypeFromURL(string2 string) string {\n\treturn strings.TrimPrefix(string2, V2RayTypeURLHeader)\n}\n\nfunc V2TypeHumanReadable(v *anypb.Any) string {\n\treturn v.TypeUrl\n}\n\nfunc V2URLFromV2Type(readableType string) string {\n\treturn readableType\n}\n"
  },
  {
    "path": "common/serial/typed_message_test.go",
    "content": "package serial_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc TestGetInstance(t *testing.T) {\n\tp, err := GetInstance(\"\")\n\tif p != nil {\n\t\tt.Error(\"expected nil instance, but got \", p)\n\t}\n\tif err == nil {\n\t\tt.Error(\"expect non-nil error, but got nil\")\n\t}\n}\n\nfunc TestConvertingNilMessage(t *testing.T) {\n\tx := ToTypedMessage(nil)\n\tif x != nil {\n\t\tt.Error(\"expect nil, but actually not\")\n\t}\n}\n"
  },
  {
    "path": "common/session/context.go",
    "content": "package session\n\nimport (\n\t\"context\"\n)\n\ntype sessionKey int\n\nconst (\n\tidSessionKey sessionKey = iota\n\tinboundSessionKey\n\toutboundSessionKey\n\tcontentSessionKey\n\tmuxPreferedSessionKey\n\tsockoptSessionKey\n\ttrackedConnectionErrorKey\n\thandlerSessionKey // nolint: varcheck\n)\n\n// ContextWithID returns a new context with the given ID.\nfunc ContextWithID(ctx context.Context, id ID) context.Context {\n\treturn context.WithValue(ctx, idSessionKey, id)\n}\n\n// IDFromContext returns ID in this context, or 0 if not contained.\nfunc IDFromContext(ctx context.Context) ID {\n\tif id, ok := ctx.Value(idSessionKey).(ID); ok {\n\t\treturn id\n\t}\n\treturn 0\n}\n\nfunc ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context {\n\treturn context.WithValue(ctx, inboundSessionKey, inbound)\n}\n\nfunc InboundFromContext(ctx context.Context) *Inbound {\n\tif inbound, ok := ctx.Value(inboundSessionKey).(*Inbound); ok {\n\t\treturn inbound\n\t}\n\treturn nil\n}\n\nfunc ContextWithOutbound(ctx context.Context, outbound *Outbound) context.Context {\n\treturn context.WithValue(ctx, outboundSessionKey, outbound)\n}\n\nfunc OutboundFromContext(ctx context.Context) *Outbound {\n\tif outbound, ok := ctx.Value(outboundSessionKey).(*Outbound); ok {\n\t\treturn outbound\n\t}\n\treturn nil\n}\n\nfunc ContextWithContent(ctx context.Context, content *Content) context.Context {\n\treturn context.WithValue(ctx, contentSessionKey, content)\n}\n\nfunc ContentFromContext(ctx context.Context) *Content {\n\tif content, ok := ctx.Value(contentSessionKey).(*Content); ok {\n\t\treturn content\n\t}\n\treturn nil\n}\n\n// ContextWithMuxPrefered returns a new context with the given bool\nfunc ContextWithMuxPrefered(ctx context.Context, forced bool) context.Context {\n\treturn context.WithValue(ctx, muxPreferedSessionKey, forced)\n}\n\n// MuxPreferedFromContext returns value in this context, or false if not contained.\nfunc MuxPreferedFromContext(ctx context.Context) bool {\n\tif val, ok := ctx.Value(muxPreferedSessionKey).(bool); ok {\n\t\treturn val\n\t}\n\treturn false\n}\n\n// ContextWithSockopt returns a new context with Socket configs included\nfunc ContextWithSockopt(ctx context.Context, s *Sockopt) context.Context {\n\treturn context.WithValue(ctx, sockoptSessionKey, s)\n}\n\n// SockoptFromContext returns Socket configs in this context, or nil if not contained.\nfunc SockoptFromContext(ctx context.Context) *Sockopt {\n\tif sockopt, ok := ctx.Value(sockoptSessionKey).(*Sockopt); ok {\n\t\treturn sockopt\n\t}\n\treturn nil\n}\n\nfunc GetTransportLayerProxyTagFromContext(ctx context.Context) string {\n\tif ContentFromContext(ctx) == nil {\n\t\treturn \"\"\n\t}\n\treturn ContentFromContext(ctx).Attribute(\"transportLayerOutgoingTag\")\n}\n\nfunc SetTransportLayerProxyTagToContext(ctx context.Context, tag string) context.Context {\n\tif contentFromContext := ContentFromContext(ctx); contentFromContext == nil {\n\t\tctx = ContextWithContent(ctx, &Content{})\n\t}\n\tContentFromContext(ctx).SetAttribute(\"transportLayerOutgoingTag\", tag)\n\treturn ctx\n}\n\nfunc GetForcedOutboundTagFromContext(ctx context.Context) string {\n\tif ContentFromContext(ctx) == nil {\n\t\treturn \"\"\n\t}\n\treturn ContentFromContext(ctx).Attribute(\"forcedOutboundTag\")\n}\n\nfunc SetForcedOutboundTagToContext(ctx context.Context, tag string) context.Context {\n\tif contentFromContext := ContentFromContext(ctx); contentFromContext == nil {\n\t\tctx = ContextWithContent(ctx, &Content{})\n\t}\n\tContentFromContext(ctx).SetAttribute(\"forcedOutboundTag\", tag)\n\treturn ctx\n}\n\ntype TrackedRequestErrorFeedback interface {\n\tSubmitError(err error)\n}\n\nfunc SubmitOutboundErrorToOriginator(ctx context.Context, err error) {\n\tif errorTracker := ctx.Value(trackedConnectionErrorKey); errorTracker != nil {\n\t\terrorTracker := errorTracker.(TrackedRequestErrorFeedback)\n\t\terrorTracker.SubmitError(err)\n\t}\n}\n\nfunc TrackedConnectionError(ctx context.Context, tracker TrackedRequestErrorFeedback) context.Context {\n\treturn context.WithValue(ctx, trackedConnectionErrorKey, tracker)\n}\n"
  },
  {
    "path": "common/session/session.go",
    "content": "// Package session provides functions for sessions of incoming requests.\npackage session\n\nimport (\n\t\"context\"\n\t\"math/rand\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n// ID of a session.\ntype ID uint32\n\n// NewID generates a new ID. The generated ID is high likely to be unique, but not cryptographically secure.\n// The generated ID will never be 0.\nfunc NewID() ID {\n\tfor {\n\t\tid := ID(rand.Uint32())\n\t\tif id != 0 {\n\t\t\treturn id\n\t\t}\n\t}\n}\n\n// ExportIDToError transfers session.ID into an error object, for logging purpose.\n// This can be used with error.WriteToLog().\nfunc ExportIDToError(ctx context.Context) errors.ExportOption {\n\tid := IDFromContext(ctx)\n\treturn func(h *errors.ExportOptionHolder) {\n\t\th.SessionID = uint32(id)\n\t}\n}\n\n// Inbound is the metadata of an inbound connection.\ntype Inbound struct {\n\t// Source address of the inbound connection.\n\tSource net.Destination\n\t// Gateway address\n\tGateway net.Destination\n\t// Tag of the inbound proxy that handles the connection.\n\tTag string\n\t// User is the user that authencates for the inbound. May be nil if the protocol allows anounymous traffic.\n\tUser *protocol.MemoryUser\n}\n\n// Outbound is the metadata of an outbound connection.\ntype Outbound struct {\n\t// Target address of the outbound connection.\n\tTarget net.Destination\n\t// Gateway address\n\tGateway net.Address\n\t// Domain resolver to use when dialing\n\tResolver func(ctx context.Context, domain string) net.Address\n}\n\n// SniffingRequest controls the behavior of content sniffing.\ntype SniffingRequest struct {\n\tOverrideDestinationForProtocol []string\n\tEnabled                        bool\n\tMetadataOnly                   bool\n}\n\n// Content is the metadata of the connection content.\ntype Content struct {\n\t// Protocol of current content.\n\tProtocol string\n\n\tSniffingRequest SniffingRequest\n\n\tAttributes map[string]string\n\n\tSkipDNSResolve bool\n}\n\n// Sockopt is the settings for socket connection.\ntype Sockopt struct {\n\t// Mark of the socket connection.\n\tMark uint32\n}\n\n// SetAttribute attachs additional string attributes to content.\nfunc (c *Content) SetAttribute(name string, value string) {\n\tif c.Attributes == nil {\n\t\tc.Attributes = make(map[string]string)\n\t}\n\tc.Attributes[name] = value\n}\n\n// Attribute retrieves additional string attributes from content.\nfunc (c *Content) Attribute(name string) string {\n\tif c.Attributes == nil {\n\t\treturn \"\"\n\t}\n\treturn c.Attributes[name]\n}\n"
  },
  {
    "path": "common/signal/done/done.go",
    "content": "package done\n\nimport (\n\t\"sync\"\n)\n\n// Instance is a utility for notifications of something being done.\ntype Instance struct {\n\taccess sync.Mutex\n\tc      chan struct{}\n\tclosed bool\n}\n\n// New returns a new Done.\nfunc New() *Instance {\n\treturn &Instance{\n\t\tc: make(chan struct{}),\n\t}\n}\n\n// Done returns true if Close() is called.\nfunc (d *Instance) Done() bool {\n\tselect {\n\tcase <-d.Wait():\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Wait returns a channel for waiting for done.\nfunc (d *Instance) Wait() <-chan struct{} {\n\treturn d.c\n}\n\n// Close marks this Done 'done'. This method may be called multiple times. All calls after first call will have no effect on its status.\nfunc (d *Instance) Close() error {\n\td.access.Lock()\n\tdefer d.access.Unlock()\n\n\tif d.closed {\n\t\treturn nil\n\t}\n\n\td.closed = true\n\tclose(d.c)\n\n\treturn nil\n}\n"
  },
  {
    "path": "common/signal/notifier.go",
    "content": "package signal\n\n// Notifier is a utility for notifying changes. The change producer may notify changes multiple time, and the consumer may get notified asynchronously.\ntype Notifier struct {\n\tc chan struct{}\n}\n\n// NewNotifier creates a new Notifier.\nfunc NewNotifier() *Notifier {\n\treturn &Notifier{\n\t\tc: make(chan struct{}, 1),\n\t}\n}\n\n// Signal signals a change, usually by producer. This method never blocks.\nfunc (n *Notifier) Signal() {\n\tselect {\n\tcase n.c <- struct{}{}:\n\tdefault:\n\t}\n}\n\n// Wait returns a channel for waiting for changes. The returned channel never gets closed.\nfunc (n *Notifier) Wait() <-chan struct{} {\n\treturn n.c\n}\n"
  },
  {
    "path": "common/signal/notifier_test.go",
    "content": "package signal_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/signal\"\n)\n\nfunc TestNotifierSignal(t *testing.T) {\n\tn := NewNotifier()\n\n\tw := n.Wait()\n\tn.Signal()\n\n\tselect {\n\tcase <-w:\n\tdefault:\n\t\tt.Fail()\n\t}\n}\n"
  },
  {
    "path": "common/signal/pubsub/pubsub.go",
    "content": "package pubsub\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\ntype Subscriber struct {\n\tbuffer chan interface{}\n\tdone   *done.Instance\n}\n\nfunc (s *Subscriber) push(msg interface{}) {\n\tselect {\n\tcase s.buffer <- msg:\n\tdefault:\n\t}\n}\n\nfunc (s *Subscriber) Wait() <-chan interface{} {\n\treturn s.buffer\n}\n\nfunc (s *Subscriber) Close() error {\n\treturn s.done.Close()\n}\n\nfunc (s *Subscriber) IsClosed() bool {\n\treturn s.done.Done()\n}\n\ntype Service struct {\n\tsync.RWMutex\n\tsubs  map[string][]*Subscriber\n\tctask *task.Periodic\n}\n\nfunc NewService() *Service {\n\ts := &Service{\n\t\tsubs: make(map[string][]*Subscriber),\n\t}\n\ts.ctask = &task.Periodic{\n\t\tExecute:  s.Cleanup,\n\t\tInterval: time.Second * 30,\n\t}\n\treturn s\n}\n\n// Cleanup cleans up internal caches of subscribers.\n// Visible for testing only.\nfunc (s *Service) Cleanup() error {\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tif len(s.subs) == 0 {\n\t\treturn errors.New(\"nothing to do\")\n\t}\n\n\tfor name, subs := range s.subs {\n\t\tnewSub := make([]*Subscriber, 0, len(s.subs))\n\t\tfor _, sub := range subs {\n\t\t\tif !sub.IsClosed() {\n\t\t\t\tnewSub = append(newSub, sub)\n\t\t\t}\n\t\t}\n\t\tif len(newSub) == 0 {\n\t\t\tdelete(s.subs, name)\n\t\t} else {\n\t\t\ts.subs[name] = newSub\n\t\t}\n\t}\n\n\tif len(s.subs) == 0 {\n\t\ts.subs = make(map[string][]*Subscriber)\n\t}\n\treturn nil\n}\n\nfunc (s *Service) Subscribe(name string) *Subscriber {\n\tsub := &Subscriber{\n\t\tbuffer: make(chan interface{}, 16),\n\t\tdone:   done.New(),\n\t}\n\ts.Lock()\n\ts.subs[name] = append(s.subs[name], sub)\n\ts.Unlock()\n\tcommon.Must(s.ctask.Start())\n\treturn sub\n}\n\nfunc (s *Service) Publish(name string, message interface{}) {\n\ts.RLock()\n\tdefer s.RUnlock()\n\n\tfor _, sub := range s.subs[name] {\n\t\tif !sub.IsClosed() {\n\t\t\tsub.push(message)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/signal/pubsub/pubsub_test.go",
    "content": "package pubsub_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/signal/pubsub\"\n)\n\nfunc TestPubsub(t *testing.T) {\n\tservice := NewService()\n\n\tsub := service.Subscribe(\"a\")\n\tservice.Publish(\"a\", 1)\n\n\tselect {\n\tcase v := <-sub.Wait():\n\t\tif v != 1 {\n\t\t\tt.Error(\"expected subscribed value 1, but got \", v)\n\t\t}\n\tdefault:\n\t\tt.Fail()\n\t}\n\n\tsub.Close()\n\tservice.Publish(\"a\", 2)\n\n\tselect {\n\tcase <-sub.Wait():\n\t\tt.Fail()\n\tdefault:\n\t}\n\n\tservice.Cleanup()\n}\n"
  },
  {
    "path": "common/signal/semaphore/semaphore.go",
    "content": "package semaphore\n\n// Instance is an implementation of semaphore.\ntype Instance struct {\n\ttoken chan struct{}\n}\n\n// New create a new Semaphore with n permits.\nfunc New(n int) *Instance {\n\ts := &Instance{\n\t\ttoken: make(chan struct{}, n),\n\t}\n\tfor i := 0; i < n; i++ {\n\t\ts.token <- struct{}{}\n\t}\n\treturn s\n}\n\n// Wait returns a channel for acquiring a permit.\nfunc (s *Instance) Wait() <-chan struct{} {\n\treturn s.token\n}\n\n// Signal releases a permit into the semaphore.\nfunc (s *Instance) Signal() {\n\ts.token <- struct{}{}\n}\n"
  },
  {
    "path": "common/signal/timer.go",
    "content": "package signal\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\ntype ActivityUpdater interface {\n\tUpdate()\n}\n\ntype ActivityTimer struct {\n\tsync.RWMutex\n\tupdated   chan struct{}\n\tcheckTask *task.Periodic\n\tonTimeout func()\n}\n\nfunc (t *ActivityTimer) Update() {\n\tselect {\n\tcase t.updated <- struct{}{}:\n\tdefault:\n\t}\n}\n\nfunc (t *ActivityTimer) check() error {\n\tselect {\n\tcase <-t.updated:\n\tdefault:\n\t\tt.finish()\n\t}\n\treturn nil\n}\n\nfunc (t *ActivityTimer) finish() {\n\tt.Lock()\n\tdefer t.Unlock()\n\n\tif t.onTimeout != nil {\n\t\tt.onTimeout()\n\t\tt.onTimeout = nil\n\t}\n\tif t.checkTask != nil {\n\t\tt.checkTask.Close()\n\t\tt.checkTask = nil\n\t}\n}\n\nfunc (t *ActivityTimer) SetTimeout(timeout time.Duration) {\n\tif timeout == 0 {\n\t\tt.finish()\n\t\treturn\n\t}\n\n\tcheckTask := &task.Periodic{\n\t\tInterval: timeout,\n\t\tExecute:  t.check,\n\t}\n\n\tt.Lock()\n\n\tif t.checkTask != nil {\n\t\tt.checkTask.Close()\n\t}\n\tt.checkTask = checkTask\n\tt.Unlock()\n\tt.Update()\n\tcommon.Must(checkTask.Start())\n}\n\nfunc CancelAfterInactivity(ctx context.Context, cancel context.CancelFunc, timeout time.Duration) *ActivityTimer {\n\ttimer := &ActivityTimer{\n\t\tupdated:   make(chan struct{}, 1),\n\t\tonTimeout: cancel,\n\t}\n\ttimer.SetTimeout(timeout)\n\treturn timer\n}\n"
  },
  {
    "path": "common/signal/timer_test.go",
    "content": "package signal_test\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\t\"testing\"\n\t\"time\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/signal\"\n)\n\nfunc TestActivityTimer(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\ttimer := CancelAfterInactivity(ctx, cancel, time.Second*4)\n\ttime.Sleep(time.Second * 6)\n\tif ctx.Err() == nil {\n\t\tt.Error(\"expected some error, but got nil\")\n\t}\n\truntime.KeepAlive(timer)\n}\n\nfunc TestActivityTimerUpdate(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\ttimer := CancelAfterInactivity(ctx, cancel, time.Second*10)\n\ttime.Sleep(time.Second * 3)\n\tif ctx.Err() != nil {\n\t\tt.Error(\"expected nil, but got \", ctx.Err().Error())\n\t}\n\ttimer.SetTimeout(time.Second * 1)\n\ttime.Sleep(time.Second * 2)\n\tif ctx.Err() == nil {\n\t\tt.Error(\"expected some error, but got nil\")\n\t}\n\truntime.KeepAlive(timer)\n}\n\nfunc TestActivityTimerNonBlocking(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\ttimer := CancelAfterInactivity(ctx, cancel, 0)\n\ttime.Sleep(time.Second * 1)\n\tselect {\n\tcase <-ctx.Done():\n\tdefault:\n\t\tt.Error(\"context not done\")\n\t}\n\ttimer.SetTimeout(0)\n\ttimer.SetTimeout(1)\n\ttimer.SetTimeout(2)\n}\n\nfunc TestActivityTimerZeroTimeout(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\ttimer := CancelAfterInactivity(ctx, cancel, 0)\n\tselect {\n\tcase <-ctx.Done():\n\tdefault:\n\t\tt.Error(\"context not done\")\n\t}\n\truntime.KeepAlive(timer)\n}\n"
  },
  {
    "path": "common/strmatcher/benchmark_indexmatcher_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc BenchmarkLinearIndexMatcher(b *testing.B) {\n\tbenchmarkIndexMatcher(b, func() IndexMatcher {\n\t\treturn NewLinearIndexMatcher()\n\t})\n}\n\nfunc BenchmarkMphIndexMatcher(b *testing.B) {\n\tbenchmarkIndexMatcher(b, func() IndexMatcher {\n\t\treturn NewMphIndexMatcher()\n\t})\n}\n\nfunc benchmarkIndexMatcher(b *testing.B, ctor func() IndexMatcher) {\n\tb.Run(\"Match\", func(b *testing.B) {\n\t\tb.Run(\"Domain------------\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{Domain: true})\n\t\t})\n\t\tb.Run(\"Domain+Full-------\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{Domain: true, Full: true})\n\t\t})\n\t\tb.Run(\"Domain+Full+Substr\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{Domain: true, Full: true, Substr: true})\n\t\t})\n\t\tb.Run(\"All-Fail----------\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{Domain: false, Full: false, Substr: false})\n\t\t})\n\t})\n\tb.Run(\"Match/Dotless\", func(b *testing.B) { // Dotless domain matcher automatically inserted in DNS app when \"localhost\" DNS is used.\n\t\tb.Run(\"All-Succ\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{Domain: true, Full: true, Substr: true, Regex: true})\n\t\t})\n\t\tb.Run(\"All-Fail\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{Domain: false, Full: false, Substr: false, Regex: false})\n\t\t})\n\t})\n\tb.Run(\"MatchAny\", func(b *testing.B) {\n\t\tb.Run(\"First-Full--\", func(b *testing.B) {\n\t\t\tbenchmarkMatchAny(b, ctor(), map[Type]bool{Full: true, Domain: true, Substr: true})\n\t\t})\n\t\tb.Run(\"First-Domain\", func(b *testing.B) {\n\t\t\tbenchmarkMatchAny(b, ctor(), map[Type]bool{Full: false, Domain: true, Substr: true})\n\t\t})\n\t\tb.Run(\"First-Substr\", func(b *testing.B) {\n\t\t\tbenchmarkMatchAny(b, ctor(), map[Type]bool{Full: false, Domain: false, Substr: true})\n\t\t})\n\t\tb.Run(\"All-Fail----\", func(b *testing.B) {\n\t\t\tbenchmarkMatchAny(b, ctor(), map[Type]bool{Full: false, Domain: false, Substr: false})\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "common/strmatcher/benchmark_matchers_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc BenchmarkFullMatcher(b *testing.B) {\n\tb.Run(\"SimpleMatcherGroup------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Full, func() MatcherGroup {\n\t\t\treturn new(SimpleMatcherGroup)\n\t\t})\n\t})\n\tb.Run(\"FullMatcherGroup--------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Full, func() MatcherGroup {\n\t\t\treturn NewFullMatcherGroup()\n\t\t})\n\t})\n\tb.Run(\"ACAutomationMatcherGroup\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Full, func() MatcherGroup {\n\t\t\treturn NewACAutomatonMatcherGroup()\n\t\t})\n\t})\n\tb.Run(\"MphMatcherGroup---------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Full, func() MatcherGroup {\n\t\t\treturn NewMphMatcherGroup()\n\t\t})\n\t})\n}\n\nfunc BenchmarkDomainMatcher(b *testing.B) {\n\tb.Run(\"SimpleMatcherGroup------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Domain, func() MatcherGroup {\n\t\t\treturn new(SimpleMatcherGroup)\n\t\t})\n\t})\n\tb.Run(\"DomainMatcherGroup------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Domain, func() MatcherGroup {\n\t\t\treturn NewDomainMatcherGroup()\n\t\t})\n\t})\n\tb.Run(\"ACAutomationMatcherGroup\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Domain, func() MatcherGroup {\n\t\t\treturn NewACAutomatonMatcherGroup()\n\t\t})\n\t})\n\tb.Run(\"MphMatcherGroup---------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Domain, func() MatcherGroup {\n\t\t\treturn NewMphMatcherGroup()\n\t\t})\n\t})\n}\n\nfunc BenchmarkSubstrMatcher(b *testing.B) {\n\tb.Run(\"SimpleMatcherGroup------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Substr, func() MatcherGroup {\n\t\t\treturn new(SimpleMatcherGroup)\n\t\t})\n\t})\n\tb.Run(\"SubstrMatcherGroup------\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Substr, func() MatcherGroup {\n\t\t\treturn new(SubstrMatcherGroup)\n\t\t})\n\t})\n\tb.Run(\"ACAutomationMatcherGroup\", func(b *testing.B) {\n\t\tbenchmarkMatcherType(b, Substr, func() MatcherGroup {\n\t\t\treturn NewACAutomatonMatcherGroup()\n\t\t})\n\t})\n}\n\n// Utility functions for benchmark\n\nfunc benchmarkMatcherType(b *testing.B, t Type, ctor func() MatcherGroup) {\n\tb.Run(\"Match\", func(b *testing.B) {\n\t\tb.Run(\"Succ\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{t: true})\n\t\t})\n\t\tb.Run(\"Fail\", func(b *testing.B) {\n\t\t\tbenchmarkMatch(b, ctor(), map[Type]bool{t: false})\n\t\t})\n\t})\n\tb.Run(\"MatchAny\", func(b *testing.B) {\n\t\tb.Run(\"Succ\", func(b *testing.B) {\n\t\t\tbenchmarkMatchAny(b, ctor(), map[Type]bool{t: true})\n\t\t})\n\t\tb.Run(\"Fail\", func(b *testing.B) {\n\t\t\tbenchmarkMatchAny(b, ctor(), map[Type]bool{t: false})\n\t\t})\n\t})\n}\n\nfunc benchmarkMatch(b *testing.B, g MatcherGroup, enabledTypes map[Type]bool) {\n\tprepareMatchers(g, enabledTypes)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = g.Match(\"0.v2fly.org\")\n\t}\n}\n\nfunc benchmarkMatchAny(b *testing.B, g MatcherGroup, enabledTypes map[Type]bool) {\n\tprepareMatchers(g, enabledTypes)\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_ = g.MatchAny(\"0.v2fly.org\")\n\t}\n}\n\nfunc prepareMatchers(g MatcherGroup, enabledTypes map[Type]bool) {\n\tfor matcherType, hasMatch := range enabledTypes {\n\t\tswitch matcherType {\n\t\tcase Domain:\n\t\t\tif hasMatch {\n\t\t\t\tAddMatcherToGroup(g, DomainMatcher(\"v2fly.org\"), 0)\n\t\t\t}\n\t\t\tfor i := 1; i < 1024; i++ {\n\t\t\t\tAddMatcherToGroup(g, DomainMatcher(strconv.Itoa(i)+\".v2fly.org\"), uint32(i))\n\t\t\t}\n\t\tcase Full:\n\t\t\tif hasMatch {\n\t\t\t\tAddMatcherToGroup(g, FullMatcher(\"0.v2fly.org\"), 0)\n\t\t\t}\n\t\t\tfor i := 1; i < 64; i++ {\n\t\t\t\tAddMatcherToGroup(g, FullMatcher(strconv.Itoa(i)+\".v2fly.org\"), uint32(i))\n\t\t\t}\n\t\tcase Substr:\n\t\t\tif hasMatch {\n\t\t\t\tAddMatcherToGroup(g, SubstrMatcher(\"v2fly.org\"), 0)\n\t\t\t}\n\t\t\tfor i := 1; i < 4; i++ {\n\t\t\t\tAddMatcherToGroup(g, SubstrMatcher(strconv.Itoa(i)+\".v2fly.org\"), uint32(i))\n\t\t\t}\n\t\tcase Regex:\n\t\t\tmatcher, err := Regex.New(\"^[^.]*$\") // Dotless domain matcher automatically inserted in DNS app when \"localhost\" DNS is used.\n\t\t\tcommon.Must(err)\n\t\t\tAddMatcherToGroup(g, matcher, 0)\n\t\t}\n\t}\n\tif g, ok := g.(buildable); ok {\n\t\tcommon.Must(g.Build())\n\t}\n}\n\ntype buildable interface {\n\tBuild() error\n}\n"
  },
  {
    "path": "common/strmatcher/indexmatcher_linear.go",
    "content": "package strmatcher\n\n// LinearIndexMatcher is an implementation of IndexMatcher.\ntype LinearIndexMatcher struct {\n\tcount  uint32\n\tfull   *FullMatcherGroup\n\tdomain *DomainMatcherGroup\n\tsubstr *SubstrMatcherGroup\n\tregex  *SimpleMatcherGroup\n}\n\nfunc NewLinearIndexMatcher() *LinearIndexMatcher {\n\treturn new(LinearIndexMatcher)\n}\n\n// Add implements IndexMatcher.Add.\nfunc (g *LinearIndexMatcher) Add(matcher Matcher) uint32 {\n\tg.count++\n\tindex := g.count\n\n\tswitch matcher := matcher.(type) {\n\tcase FullMatcher:\n\t\tif g.full == nil {\n\t\t\tg.full = NewFullMatcherGroup()\n\t\t}\n\t\tg.full.AddFullMatcher(matcher, index)\n\tcase DomainMatcher:\n\t\tif g.domain == nil {\n\t\t\tg.domain = NewDomainMatcherGroup()\n\t\t}\n\t\tg.domain.AddDomainMatcher(matcher, index)\n\tcase SubstrMatcher:\n\t\tif g.substr == nil {\n\t\t\tg.substr = new(SubstrMatcherGroup)\n\t\t}\n\t\tg.substr.AddSubstrMatcher(matcher, index)\n\tdefault:\n\t\tif g.regex == nil {\n\t\t\tg.regex = new(SimpleMatcherGroup)\n\t\t}\n\t\tg.regex.AddMatcher(matcher, index)\n\t}\n\n\treturn index\n}\n\n// Build implements IndexMatcher.Build.\nfunc (*LinearIndexMatcher) Build() error {\n\treturn nil\n}\n\n// Match implements IndexMatcher.Match.\nfunc (g *LinearIndexMatcher) Match(input string) []uint32 {\n\t// Allocate capacity to prevent matches escaping to heap\n\tresult := make([][]uint32, 0, 5)\n\tif g.full != nil {\n\t\tif matches := g.full.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\tif g.domain != nil {\n\t\tif matches := g.domain.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\tif g.substr != nil {\n\t\tif matches := g.substr.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\tif g.regex != nil {\n\t\tif matches := g.regex.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\treturn CompositeMatches(result)\n}\n\n// MatchAny implements IndexMatcher.MatchAny.\nfunc (g *LinearIndexMatcher) MatchAny(input string) bool {\n\tif g.full != nil && g.full.MatchAny(input) {\n\t\treturn true\n\t}\n\tif g.domain != nil && g.domain.MatchAny(input) {\n\t\treturn true\n\t}\n\tif g.substr != nil && g.substr.MatchAny(input) {\n\t\treturn true\n\t}\n\treturn g.regex != nil && g.regex.MatchAny(input)\n}\n\n// Size implements IndexMatcher.Size.\nfunc (g *LinearIndexMatcher) Size() uint32 {\n\treturn g.count\n}\n"
  },
  {
    "path": "common/strmatcher/indexmatcher_linear_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\n// See https://github.com/v2fly/v2ray-core/issues/92#issuecomment-673238489\nfunc TestLinearIndexMatcher(t *testing.T) {\n\trules := []struct {\n\t\tType   Type\n\t\tDomain string\n\t}{\n\t\t{\n\t\t\tType:   Regex,\n\t\t\tDomain: \"apis\\\\.us$\",\n\t\t},\n\t\t{\n\t\t\tType:   Substr,\n\t\t\tDomain: \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Substr,\n\t\t\tDomain: \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"fonts.googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"example.com\",\n\t\t},\n\t}\n\tcases := []struct {\n\t\tInput  string\n\t\tOutput []uint32\n\t}{\n\t\t{\n\t\t\tInput:  \"www.baidu.com\",\n\t\t\tOutput: []uint32{5, 9, 4},\n\t\t},\n\t\t{\n\t\t\tInput:  \"fonts.googleapis.com\",\n\t\t\tOutput: []uint32{8, 3, 7, 4, 2, 6},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.googleapis.com\",\n\t\t\tOutput: []uint32{3, 7, 4, 2, 6},\n\t\t},\n\t\t{\n\t\t\tInput:  \"testapis.us\",\n\t\t\tOutput: []uint32{2, 6, 1},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.com\",\n\t\t\tOutput: []uint32{10, 4},\n\t\t},\n\t}\n\tmatcherGroup := NewLinearIndexMatcher()\n\tfor _, rule := range rules {\n\t\tmatcher, err := rule.Type.New(rule.Domain)\n\t\tcommon.Must(err)\n\t\tmatcherGroup.Add(matcher)\n\t}\n\tmatcherGroup.Build()\n\tfor _, test := range cases {\n\t\tif m := matcherGroup.Match(test.Input); !reflect.DeepEqual(m, test.Output) {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/indexmatcher_mph.go",
    "content": "package strmatcher\n\n// A MphIndexMatcher is divided into three parts:\n// 1. `full` and `domain` patterns are matched by Rabin-Karp algorithm and minimal perfect hash table;\n// 2. `substr` patterns are matched by ac automaton;\n// 3. `regex` patterns are matched with the regex library.\ntype MphIndexMatcher struct {\n\tcount uint32\n\tmph   *MphMatcherGroup\n\tac    *ACAutomatonMatcherGroup\n\tregex *SimpleMatcherGroup\n}\n\nfunc NewMphIndexMatcher() *MphIndexMatcher {\n\treturn new(MphIndexMatcher)\n}\n\n// Add implements IndexMatcher.Add.\nfunc (g *MphIndexMatcher) Add(matcher Matcher) uint32 {\n\tg.count++\n\tindex := g.count\n\n\tswitch matcher := matcher.(type) {\n\tcase FullMatcher:\n\t\tif g.mph == nil {\n\t\t\tg.mph = NewMphMatcherGroup()\n\t\t}\n\t\tg.mph.AddFullMatcher(matcher, index)\n\tcase DomainMatcher:\n\t\tif g.mph == nil {\n\t\t\tg.mph = NewMphMatcherGroup()\n\t\t}\n\t\tg.mph.AddDomainMatcher(matcher, index)\n\tcase SubstrMatcher:\n\t\tif g.ac == nil {\n\t\t\tg.ac = NewACAutomatonMatcherGroup()\n\t\t}\n\t\tg.ac.AddSubstrMatcher(matcher, index)\n\tcase *RegexMatcher:\n\t\tif g.regex == nil {\n\t\t\tg.regex = &SimpleMatcherGroup{}\n\t\t}\n\t\tg.regex.AddMatcher(matcher, index)\n\t}\n\n\treturn index\n}\n\n// Build implements IndexMatcher.Build.\nfunc (g *MphIndexMatcher) Build() error {\n\tif g.mph != nil {\n\t\tg.mph.Build()\n\t}\n\tif g.ac != nil {\n\t\tg.ac.Build()\n\t}\n\treturn nil\n}\n\n// Match implements IndexMatcher.Match.\nfunc (g *MphIndexMatcher) Match(input string) []uint32 {\n\tresult := make([][]uint32, 0, 5)\n\tif g.mph != nil {\n\t\tif matches := g.mph.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\tif g.ac != nil {\n\t\tif matches := g.ac.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\tif g.regex != nil {\n\t\tif matches := g.regex.Match(input); len(matches) > 0 {\n\t\t\tresult = append(result, matches)\n\t\t}\n\t}\n\treturn CompositeMatches(result)\n}\n\n// MatchAny implements IndexMatcher.MatchAny.\nfunc (g *MphIndexMatcher) MatchAny(input string) bool {\n\tif g.mph != nil && g.mph.MatchAny(input) {\n\t\treturn true\n\t}\n\tif g.ac != nil && g.ac.MatchAny(input) {\n\t\treturn true\n\t}\n\treturn g.regex != nil && g.regex.MatchAny(input)\n}\n\n// Size implements IndexMatcher.Size.\nfunc (g *MphIndexMatcher) Size() uint32 {\n\treturn g.count\n}\n"
  },
  {
    "path": "common/strmatcher/indexmatcher_mph_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestMphIndexMatcher(t *testing.T) {\n\trules := []struct {\n\t\tType   Type\n\t\tDomain string\n\t}{\n\t\t{\n\t\t\tType:   Regex,\n\t\t\tDomain: \"apis\\\\.us$\",\n\t\t},\n\t\t{\n\t\t\tType:   Substr,\n\t\t\tDomain: \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Substr,\n\t\t\tDomain: \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"fonts.googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"example.com\",\n\t\t},\n\t}\n\tcases := []struct {\n\t\tInput  string\n\t\tOutput []uint32\n\t}{\n\t\t{\n\t\t\tInput:  \"www.baidu.com\",\n\t\t\tOutput: []uint32{5, 9, 4},\n\t\t},\n\t\t{\n\t\t\tInput:  \"fonts.googleapis.com\",\n\t\t\tOutput: []uint32{8, 3, 7, 4, 2, 6},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.googleapis.com\",\n\t\t\tOutput: []uint32{3, 7, 4, 2, 6},\n\t\t},\n\t\t{\n\t\t\tInput:  \"testapis.us\",\n\t\t\tOutput: []uint32{2, 6, 1},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.com\",\n\t\t\tOutput: []uint32{10, 4},\n\t\t},\n\t}\n\tmatcherGroup := NewMphIndexMatcher()\n\tfor _, rule := range rules {\n\t\tmatcher, err := rule.Type.New(rule.Domain)\n\t\tcommon.Must(err)\n\t\tmatcherGroup.Add(matcher)\n\t}\n\tmatcherGroup.Build()\n\tfor _, test := range cases {\n\t\tif m := matcherGroup.Match(test.Input); !reflect.DeepEqual(m, test.Output) {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_ac_automation.go",
    "content": "package strmatcher\n\nimport (\n\t\"container/list\"\n)\n\nconst (\n\tacValidCharCount = 39 // aA-zZ (26), 0-9 (10), - (1), . (1), invalid(1)\n\tacMatchTypeCount = 3  // Full, Domain and Substr\n)\n\ntype acEdge byte\n\nconst (\n\tacTrieEdge acEdge = 1\n\tacFailEdge acEdge = 0\n)\n\ntype acNode struct {\n\tnext  [acValidCharCount]uint32 // EdgeIdx -> Next NodeIdx (Next trie node or fail node)\n\tedge  [acValidCharCount]acEdge // EdgeIdx -> Trie Edge / Fail Edge\n\tfail  uint32                   // NodeIdx of *next matched* Substr Pattern on its fail path\n\tmatch uint32                   // MatchIdx of matchers registered on this node, 0 indicates no match\n} // Sizeof acNode: (4+1)*acValidCharCount + <padding> + 4 + 4\n\ntype acValue [acMatchTypeCount][]uint32 // MatcherType -> Registered Matcher Values\n\n// ACAutoMationMatcherGroup is an implementation of MatcherGroup.\n// It uses an AC Automata to provide support for Full, Domain and Substr matcher. Trie node is char based.\n//\n// NOTICE: ACAutomatonMatcherGroup currently uses a restricted charset (LDH Subset),\n// upstream should manually in a way to ensure all patterns and inputs passed to it to be in this charset.\ntype ACAutomatonMatcherGroup struct {\n\tnodes  []acNode  // NodeIdx -> acNode\n\tvalues []acValue // MatchIdx -> acValue\n}\n\nfunc NewACAutomatonMatcherGroup() *ACAutomatonMatcherGroup {\n\tac := new(ACAutomatonMatcherGroup)\n\tac.addNode()       // Create root node (NodeIdx 0)\n\tac.addMatchEntry() // Create sentinel match entry (MatchIdx 0)\n\treturn ac\n}\n\n// AddFullMatcher implements MatcherGroupForFull.AddFullMatcher.\nfunc (ac *ACAutomatonMatcherGroup) AddFullMatcher(matcher FullMatcher, value uint32) {\n\tac.addPattern(0, matcher.Pattern(), matcher.Type(), value)\n}\n\n// AddDomainMatcher implements MatcherGroupForDomain.AddDomainMatcher.\nfunc (ac *ACAutomatonMatcherGroup) AddDomainMatcher(matcher DomainMatcher, value uint32) {\n\tnode := ac.addPattern(0, matcher.Pattern(), matcher.Type(), value) // For full domain match\n\tac.addPattern(node, \".\", matcher.Type(), value)                    // For partial domain match\n}\n\n// AddSubstrMatcher implements MatcherGroupForSubstr.AddSubstrMatcher.\nfunc (ac *ACAutomatonMatcherGroup) AddSubstrMatcher(matcher SubstrMatcher, value uint32) {\n\tac.addPattern(0, matcher.Pattern(), matcher.Type(), value)\n}\n\nfunc (ac *ACAutomatonMatcherGroup) addPattern(nodeIdx uint32, pattern string, matcherType Type, value uint32) uint32 {\n\tnode := &ac.nodes[nodeIdx]\n\tfor i := len(pattern) - 1; i >= 0; i-- {\n\t\tedgeIdx := acCharset[pattern[i]]\n\t\tnextIdx := node.next[edgeIdx]\n\t\tif nextIdx == 0 { // Add new Trie Edge\n\t\t\tnextIdx = ac.addNode()\n\t\t\tac.nodes[nodeIdx].next[edgeIdx] = nextIdx\n\t\t\tac.nodes[nodeIdx].edge[edgeIdx] = acTrieEdge\n\t\t}\n\t\tnodeIdx = nextIdx\n\t\tnode = &ac.nodes[nodeIdx]\n\t}\n\tif node.match == 0 { // Add new match entry\n\t\tnode.match = ac.addMatchEntry()\n\t}\n\tac.values[node.match][matcherType] = append(ac.values[node.match][matcherType], value)\n\treturn nodeIdx\n}\n\nfunc (ac *ACAutomatonMatcherGroup) addNode() uint32 {\n\tac.nodes = append(ac.nodes, acNode{})\n\treturn uint32(len(ac.nodes) - 1)\n}\n\nfunc (ac *ACAutomatonMatcherGroup) addMatchEntry() uint32 {\n\tac.values = append(ac.values, acValue{})\n\treturn uint32(len(ac.values) - 1)\n}\n\nfunc (ac *ACAutomatonMatcherGroup) Build() error {\n\tfail := make([]uint32, len(ac.nodes))\n\tqueue := list.New()\n\tfor edgeIdx := 0; edgeIdx < acValidCharCount; edgeIdx++ {\n\t\tif nextIdx := ac.nodes[0].next[edgeIdx]; nextIdx != 0 {\n\t\t\tqueue.PushBack(nextIdx)\n\t\t}\n\t}\n\tfor {\n\t\tfront := queue.Front()\n\t\tif front == nil {\n\t\t\tbreak\n\t\t}\n\t\tqueue.Remove(front)\n\t\tnodeIdx := front.Value.(uint32)\n\t\tnode := &ac.nodes[nodeIdx]           // Current node\n\t\tfailNode := &ac.nodes[fail[nodeIdx]] // Fail node of currrent node\n\t\tfor edgeIdx := 0; edgeIdx < acValidCharCount; edgeIdx++ {\n\t\t\tnodeIdx := node.next[edgeIdx]     // Next node through trie edge\n\t\t\tfailIdx := failNode.next[edgeIdx] // Next node through fail edge\n\t\t\tif nodeIdx != 0 {\n\t\t\t\tqueue.PushBack(nodeIdx)\n\t\t\t\tfail[nodeIdx] = failIdx\n\t\t\t\tif match := ac.nodes[failIdx].match; match != 0 && len(ac.values[match][Substr]) > 0 { // Fail node is a Substr match node\n\t\t\t\t\tac.nodes[nodeIdx].fail = failIdx\n\t\t\t\t} else { // Use path compression to reduce fail path to only contain match nodes\n\t\t\t\t\tac.nodes[nodeIdx].fail = ac.nodes[failIdx].fail\n\t\t\t\t}\n\t\t\t} else { // Add new fail edge\n\t\t\t\tnode.next[edgeIdx] = failIdx\n\t\t\t\tnode.edge[edgeIdx] = acFailEdge\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Match implements MatcherGroup.Match.\nfunc (ac *ACAutomatonMatcherGroup) Match(input string) []uint32 {\n\tsuffixMatches := make([][]uint32, 0, 5)\n\tsubstrMatches := make([][]uint32, 0, 5)\n\tfullMatch := true    // fullMatch indicates no fail edge traversed so far.\n\tnode := &ac.nodes[0] // start from root node.\n\t// 1. the match string is all through trie edge. FULL MATCH or DOMAIN\n\t// 2. the match string is through a fail edge. NOT FULL MATCH\n\t// 2.1 Through a fail edge, but there exists a valid node. SUBSTR\n\tfor i := len(input) - 1; i >= 0; i-- {\n\t\tedge := acCharset[input[i]]\n\t\tfullMatch = fullMatch && (node.edge[edge] == acTrieEdge)\n\t\tnode = &ac.nodes[node.next[edge]] // Advance to next node\n\t\t// When entering a new node, traverse the fail path to find all possible Substr patterns:\n\t\t//   1. The fail path is compressed to only contains match nodes and root node (for terminate condition).\n\t\t//   2. node.fail != 0 is added here for better performance (as shown by benchmark), possibly it helps branch prediction.\n\t\tif node.fail != 0 {\n\t\t\tfor failIdx, failNode := node.fail, &ac.nodes[node.fail]; failIdx != 0; failIdx, failNode = failNode.fail, &ac.nodes[failIdx] {\n\t\t\t\tsubstrMatches = append(substrMatches, ac.values[failNode.match][Substr])\n\t\t\t}\n\t\t}\n\t\t// When entering a new node, check whether this node is a match.\n\t\t// For Substr matchers:\n\t\t//   1. Matched in any situation, whether a failNode edge is traversed or not.\n\t\t// For Domain matchers:\n\t\t//   1. Should not traverse any fail edge (fullMatch).\n\t\t//   2. Only check on dot separator (input[i] == '.').\n\t\tif node.match != 0 {\n\t\t\tvalues := ac.values[node.match]\n\t\t\tif len(values[Substr]) > 0 {\n\t\t\t\tsubstrMatches = append(substrMatches, values[Substr])\n\t\t\t}\n\t\t\tif fullMatch && input[i] == '.' && len(values[Domain]) > 0 {\n\t\t\t\tsuffixMatches = append(suffixMatches, values[Domain])\n\t\t\t}\n\t\t}\n\t}\n\t// At the end of input, check if the whole string matches a pattern.\n\t// For Domain matchers:\n\t//   1. Exact match on Domain Matcher works like Full Match. e.g. foo.com is a full match for domain:foo.com.\n\t// For Full matchers:\n\t//   1. Only when no fail edge is traversed (fullMatch).\n\t//   2. Takes the highest priority (added at last).\n\tif fullMatch && node.match != 0 {\n\t\tvalues := ac.values[node.match]\n\t\tif len(values[Domain]) > 0 {\n\t\t\tsuffixMatches = append(suffixMatches, values[Domain])\n\t\t}\n\t\tif len(values[Full]) > 0 {\n\t\t\tsuffixMatches = append(suffixMatches, values[Full])\n\t\t}\n\t}\n\tif len(substrMatches) == 0 {\n\t\treturn CompositeMatchesReverse(suffixMatches)\n\t}\n\treturn CompositeMatchesReverse(append(substrMatches, suffixMatches...))\n}\n\n// MatchAny implements MatcherGroup.MatchAny.\nfunc (ac *ACAutomatonMatcherGroup) MatchAny(input string) bool {\n\tfullMatch := true\n\tnode := &ac.nodes[0]\n\tfor i := len(input) - 1; i >= 0; i-- {\n\t\tedge := acCharset[input[i]]\n\t\tfullMatch = fullMatch && (node.edge[edge] == acTrieEdge)\n\t\tnode = &ac.nodes[node.next[edge]]\n\t\tif node.fail != 0 { // There is a match on this node's fail path\n\t\t\treturn true\n\t\t}\n\t\tif node.match != 0 { // There is a match on this node\n\t\t\tvalues := ac.values[node.match]\n\t\t\tif len(values[Substr]) > 0 { // Substr match succeeds unconditionally\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif fullMatch && input[i] == '.' && len(values[Domain]) > 0 { // Domain match only succeeds with dot separator on trie path\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn fullMatch && node.match != 0 // At the end of input, Domain and Full match will succeed if no fail edge is traversed\n}\n\n// Letter-Digit-Hyphen (LDH) subset (https://tools.ietf.org/html/rfc952):\n//   - Letters A to Z (no distinction is made between uppercase and lowercase)\n//   - Digits 0 to 9\n//   - Hyphens(-) and Periods(.)\n//\n// If for future the strmatcher are used for other scenarios than domain,\n// we could add a new Charset interface to represent variable charsets.\nvar acCharset = [256]int{\n\t'A': 1,\n\t'a': 1,\n\t'B': 2,\n\t'b': 2,\n\t'C': 3,\n\t'c': 3,\n\t'D': 4,\n\t'd': 4,\n\t'E': 5,\n\t'e': 5,\n\t'F': 6,\n\t'f': 6,\n\t'G': 7,\n\t'g': 7,\n\t'H': 8,\n\t'h': 8,\n\t'I': 9,\n\t'i': 9,\n\t'J': 10,\n\t'j': 10,\n\t'K': 11,\n\t'k': 11,\n\t'L': 12,\n\t'l': 12,\n\t'M': 13,\n\t'm': 13,\n\t'N': 14,\n\t'n': 14,\n\t'O': 15,\n\t'o': 15,\n\t'P': 16,\n\t'p': 16,\n\t'Q': 17,\n\t'q': 17,\n\t'R': 18,\n\t'r': 18,\n\t'S': 19,\n\t's': 19,\n\t'T': 20,\n\t't': 20,\n\t'U': 21,\n\t'u': 21,\n\t'V': 22,\n\t'v': 22,\n\t'W': 23,\n\t'w': 23,\n\t'X': 24,\n\t'x': 24,\n\t'Y': 25,\n\t'y': 25,\n\t'Z': 26,\n\t'z': 26,\n\t'-': 27,\n\t'.': 28,\n\t'0': 29,\n\t'1': 30,\n\t'2': 31,\n\t'3': 32,\n\t'4': 33,\n\t'5': 34,\n\t'6': 35,\n\t'7': 36,\n\t'8': 37,\n\t'9': 38,\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_ac_automation_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestACAutomatonMatcherGroup(t *testing.T) {\n\tcases1 := []struct {\n\t\tpattern string\n\t\tmType   Type\n\t\tinput   string\n\t\toutput  bool\n\t}{\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"www.v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"www.v3fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"xv2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t\tinput:   \"v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t\tinput:   \"xv2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t}\n\tfor _, test := range cases1 {\n\t\tac := NewACAutomatonMatcherGroup()\n\t\tmatcher, err := test.mType.New(test.pattern)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(ac, matcher, 0))\n\t\tac.Build()\n\t\tif m := ac.MatchAny(test.input); m != test.output {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n\t{\n\t\tcases2Input := []struct {\n\t\t\tpattern string\n\t\t\tmType   Type\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"163.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"m.126.com\",\n\t\t\t\tmType:   Full,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"3.com\",\n\t\t\t\tmType:   Full,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"google.com\",\n\t\t\t\tmType:   Substr,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"vgoogle.com\",\n\t\t\t\tmType:   Substr,\n\t\t\t},\n\t\t}\n\t\tac := NewACAutomatonMatcherGroup()\n\t\tfor _, test := range cases2Input {\n\t\t\tmatcher, err := test.mType.New(test.pattern)\n\t\t\tcommon.Must(err)\n\t\t\tcommon.Must(AddMatcherToGroup(ac, matcher, 0))\n\t\t}\n\t\tac.Build()\n\t\tcases2Output := []struct {\n\t\t\tpattern string\n\t\t\tres     bool\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"126.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"m.163.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"mm163.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"m.126.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"163.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"63.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"oogle.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"vvgoogle.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t}\n\t\tfor _, test := range cases2Output {\n\t\t\tif m := ac.MatchAny(test.pattern); m != test.res {\n\t\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t\t}\n\t\t}\n\t}\n\n\t{\n\t\tcases3Input := []struct {\n\t\t\tpattern string\n\t\t\tmType   Type\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"video.google.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"gle.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t}\n\t\tac := NewACAutomatonMatcherGroup()\n\t\tfor _, test := range cases3Input {\n\t\t\tmatcher, err := test.mType.New(test.pattern)\n\t\t\tcommon.Must(err)\n\t\t\tcommon.Must(AddMatcherToGroup(ac, matcher, 0))\n\t\t}\n\t\tac.Build()\n\t\tcases3Output := []struct {\n\t\t\tpattern string\n\t\t\tres     bool\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"google.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t}\n\t\tfor _, test := range cases3Output {\n\t\t\tif m := ac.MatchAny(test.pattern); m != test.res {\n\t\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t\t}\n\t\t}\n\t}\n\n\t{\n\t\tcases4Input := []struct {\n\t\t\tpattern string\n\t\t\tmType   Type\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"apis\",\n\t\t\t\tmType:   Substr,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"googleapis.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t}\n\t\tac := NewACAutomatonMatcherGroup()\n\t\tfor _, test := range cases4Input {\n\t\t\tmatcher, err := test.mType.New(test.pattern)\n\t\t\tcommon.Must(err)\n\t\t\tcommon.Must(AddMatcherToGroup(ac, matcher, 0))\n\t\t}\n\t\tac.Build()\n\t\tcases4Output := []struct {\n\t\t\tpattern string\n\t\t\tres     bool\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"gapis.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t}\n\t\tfor _, test := range cases4Output {\n\t\t\tif m := ac.MatchAny(test.pattern); m != test.res {\n\t\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestACAutomatonMatcherGroupSubstr(t *testing.T) {\n\tpatterns := []struct {\n\t\tpattern string\n\t\tmType   Type\n\t}{\n\t\t{\n\t\t\tpattern: \"apis\",\n\t\t\tmType:   Substr,\n\t\t},\n\t\t{\n\t\t\tpattern: \"google\",\n\t\t\tmType:   Substr,\n\t\t},\n\t\t{\n\t\t\tpattern: \"apis\",\n\t\t\tmType:   Substr,\n\t\t},\n\t}\n\tcases := []struct {\n\t\tinput  string\n\t\toutput []uint32\n\t}{\n\t\t{\n\t\t\tinput:  \"google.com\",\n\t\t\toutput: []uint32{1},\n\t\t},\n\t\t{\n\t\t\tinput:  \"apis.com\",\n\t\t\toutput: []uint32{0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"googleapis.com\",\n\t\t\toutput: []uint32{1, 0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"fonts.googleapis.com\",\n\t\t\toutput: []uint32{1, 0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"apis.googleapis.com\",\n\t\t\toutput: []uint32{0, 2, 1, 0, 2},\n\t\t},\n\t}\n\tmatcherGroup := NewACAutomatonMatcherGroup()\n\tfor id, entry := range patterns {\n\t\tmatcher, err := entry.mType.New(entry.pattern)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(matcherGroup, matcher, uint32(id)))\n\t}\n\tmatcherGroup.Build()\n\tfor _, test := range cases {\n\t\tif r := matcherGroup.Match(test.input); !reflect.DeepEqual(r, test.output) {\n\t\t\tt.Error(\"unexpected output: \", r, \" for test case \", test)\n\t\t}\n\t}\n}\n\n// See https://github.com/v2fly/v2ray-core/issues/92#issuecomment-673238489\nfunc TestACAutomatonMatcherGroupAsIndexMatcher(t *testing.T) {\n\trules := []struct {\n\t\tType   Type\n\t\tDomain string\n\t}{\n\t\t// Regex not supported by ACAutomationMatcherGroup\n\t\t// {\n\t\t// \tType:   Regex,\n\t\t// \tDomain: \"apis\\\\.us$\",\n\t\t// },\n\t\t{\n\t\t\tType:   Substr,\n\t\t\tDomain: \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Substr,\n\t\t\tDomain: \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"fonts.googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"example.com\",\n\t\t},\n\t}\n\tcases := []struct {\n\t\tInput  string\n\t\tOutput []uint32\n\t}{\n\t\t{\n\t\t\tInput:  \"www.baidu.com\",\n\t\t\tOutput: []uint32{5, 9, 4},\n\t\t},\n\t\t{\n\t\t\tInput:  \"fonts.googleapis.com\",\n\t\t\tOutput: []uint32{8, 3, 7, 4, 2, 6},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.googleapis.com\",\n\t\t\tOutput: []uint32{3, 7, 4, 2, 6},\n\t\t},\n\t\t{\n\t\t\tInput:  \"testapis.us\",\n\t\t\tOutput: []uint32{2, 6 /*, 1*/},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.com\",\n\t\t\tOutput: []uint32{10, 4},\n\t\t},\n\t}\n\tmatcherGroup := NewACAutomatonMatcherGroup()\n\tfor i, rule := range rules {\n\t\tmatcher, err := rule.Type.New(rule.Domain)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(matcherGroup, matcher, uint32(i+2)))\n\t}\n\tmatcherGroup.Build()\n\tfor _, test := range cases {\n\t\tif m := matcherGroup.Match(test.Input); !reflect.DeepEqual(m, test.Output) {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_domain.go",
    "content": "package strmatcher\n\ntype trieNode struct {\n\tvalues   []uint32\n\tchildren map[string]*trieNode\n}\n\n// DomainMatcherGroup is an implementation of MatcherGroup.\n// It uses trie to optimize both memory consumption and lookup speed. Trie node is domain label based.\ntype DomainMatcherGroup struct {\n\troot *trieNode\n}\n\nfunc NewDomainMatcherGroup() *DomainMatcherGroup {\n\treturn &DomainMatcherGroup{\n\t\troot: new(trieNode),\n\t}\n}\n\n// AddDomainMatcher implements MatcherGroupForDomain.AddDomainMatcher.\nfunc (g *DomainMatcherGroup) AddDomainMatcher(matcher DomainMatcher, value uint32) {\n\tnode := g.root\n\tpattern := matcher.Pattern()\n\tfor i := len(pattern); i > 0; {\n\t\tvar part string\n\t\tfor j := i - 1; ; j-- {\n\t\t\tif pattern[j] == '.' {\n\t\t\t\tpart = pattern[j+1 : i]\n\t\t\t\ti = j\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif j == 0 {\n\t\t\t\tpart = pattern[j:i]\n\t\t\t\ti = j\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif node.children == nil {\n\t\t\tnode.children = make(map[string]*trieNode)\n\t\t}\n\t\tnext := node.children[part]\n\t\tif next == nil {\n\t\t\tnext = new(trieNode)\n\t\t\tnode.children[part] = next\n\t\t}\n\t\tnode = next\n\t}\n\n\tnode.values = append(node.values, value)\n}\n\n// Match implements MatcherGroup.Match.\nfunc (g *DomainMatcherGroup) Match(input string) []uint32 {\n\tmatches := make([][]uint32, 0, 5)\n\tnode := g.root\n\tfor i := len(input); i > 0; {\n\t\tfor j := i - 1; ; j-- {\n\t\t\tif input[j] == '.' { // Domain label found\n\t\t\t\tnode = node.children[input[j+1:i]]\n\t\t\t\ti = j\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif j == 0 { // The last part of domain label\n\t\t\t\tnode = node.children[input[j:i]]\n\t\t\t\ti = j\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif node == nil { // No more match if no trie edge transition\n\t\t\tbreak\n\t\t}\n\t\tif len(node.values) > 0 { // Found matched matchers\n\t\t\tmatches = append(matches, node.values)\n\t\t}\n\t\tif node.children == nil { // No more match if leaf node reached\n\t\t\tbreak\n\t\t}\n\t}\n\treturn CompositeMatchesReverse(matches)\n}\n\n// MatchAny implements MatcherGroup.MatchAny.\nfunc (g *DomainMatcherGroup) MatchAny(input string) bool {\n\tnode := g.root\n\tfor i := len(input); i > 0; {\n\t\tfor j := i - 1; ; j-- {\n\t\t\tif input[j] == '.' {\n\t\t\t\tnode = node.children[input[j+1:i]]\n\t\t\t\ti = j\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif j == 0 {\n\t\t\t\tnode = node.children[input[j:i]]\n\t\t\t\ti = j\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif node == nil {\n\t\t\treturn false\n\t\t}\n\t\tif len(node.values) > 0 {\n\t\t\treturn true\n\t\t}\n\t\tif node.children == nil {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_domain_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestDomainMatcherGroup(t *testing.T) {\n\tpatterns := []struct {\n\t\tPattern string\n\t\tValue   uint32\n\t}{\n\t\t{\n\t\t\tPattern: \"v2fly.org\",\n\t\t\tValue:   1,\n\t\t},\n\t\t{\n\t\t\tPattern: \"google.com\",\n\t\t\tValue:   2,\n\t\t},\n\t\t{\n\t\t\tPattern: \"x.a.com\",\n\t\t\tValue:   3,\n\t\t},\n\t\t{\n\t\t\tPattern: \"a.b.com\",\n\t\t\tValue:   4,\n\t\t},\n\t\t{\n\t\t\tPattern: \"c.a.b.com\",\n\t\t\tValue:   5,\n\t\t},\n\t\t{\n\t\t\tPattern: \"x.y.com\",\n\t\t\tValue:   4,\n\t\t},\n\t\t{\n\t\t\tPattern: \"x.y.com\",\n\t\t\tValue:   6,\n\t\t},\n\t}\n\ttestCases := []struct {\n\t\tDomain string\n\t\tResult []uint32\n\t}{\n\t\t{\n\t\t\tDomain: \"x.v2fly.org\",\n\t\t\tResult: []uint32{1},\n\t\t},\n\t\t{\n\t\t\tDomain: \"y.com\",\n\t\t\tResult: nil,\n\t\t},\n\t\t{\n\t\t\tDomain: \"a.b.com\",\n\t\t\tResult: []uint32{4},\n\t\t},\n\t\t{ // Matches [c.a.b.com, a.b.com]\n\t\t\tDomain: \"c.a.b.com\",\n\t\t\tResult: []uint32{5, 4},\n\t\t},\n\t\t{\n\t\t\tDomain: \"c.a..b.com\",\n\t\t\tResult: nil,\n\t\t},\n\t\t{\n\t\t\tDomain: \".com\",\n\t\t\tResult: nil,\n\t\t},\n\t\t{\n\t\t\tDomain: \"com\",\n\t\t\tResult: nil,\n\t\t},\n\t\t{\n\t\t\tDomain: \"\",\n\t\t\tResult: nil,\n\t\t},\n\t\t{\n\t\t\tDomain: \"x.y.com\",\n\t\t\tResult: []uint32{4, 6},\n\t\t},\n\t}\n\tg := NewDomainMatcherGroup()\n\tfor _, pattern := range patterns {\n\t\tAddMatcherToGroup(g, DomainMatcher(pattern.Pattern), pattern.Value)\n\t}\n\tfor _, testCase := range testCases {\n\t\tr := g.Match(testCase.Domain)\n\t\tif !reflect.DeepEqual(r, testCase.Result) {\n\t\t\tt.Error(\"Failed to match domain: \", testCase.Domain, \", expect \", testCase.Result, \", but got \", r)\n\t\t}\n\t}\n}\n\nfunc TestEmptyDomainMatcherGroup(t *testing.T) {\n\tg := NewDomainMatcherGroup()\n\tr := g.Match(\"v2fly.org\")\n\tif len(r) != 0 {\n\t\tt.Error(\"Expect [], but \", r)\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_full.go",
    "content": "package strmatcher\n\n// FullMatcherGroup is an implementation of MatcherGroup.\n// It uses a hash table to facilitate exact match lookup.\ntype FullMatcherGroup struct {\n\tmatchers map[string][]uint32\n}\n\nfunc NewFullMatcherGroup() *FullMatcherGroup {\n\treturn &FullMatcherGroup{\n\t\tmatchers: make(map[string][]uint32),\n\t}\n}\n\n// AddFullMatcher implements MatcherGroupForFull.AddFullMatcher.\nfunc (g *FullMatcherGroup) AddFullMatcher(matcher FullMatcher, value uint32) {\n\tdomain := matcher.Pattern()\n\tg.matchers[domain] = append(g.matchers[domain], value)\n}\n\n// Match implements MatcherGroup.Match.\nfunc (g *FullMatcherGroup) Match(input string) []uint32 {\n\treturn g.matchers[input]\n}\n\n// MatchAny implements MatcherGroup.Any.\nfunc (g *FullMatcherGroup) MatchAny(input string) bool {\n\t_, found := g.matchers[input]\n\treturn found\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_full_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestFullMatcherGroup(t *testing.T) {\n\tpatterns := []struct {\n\t\tPattern string\n\t\tValue   uint32\n\t}{\n\t\t{\n\t\t\tPattern: \"v2fly.org\",\n\t\t\tValue:   1,\n\t\t},\n\t\t{\n\t\t\tPattern: \"google.com\",\n\t\t\tValue:   2,\n\t\t},\n\t\t{\n\t\t\tPattern: \"x.a.com\",\n\t\t\tValue:   3,\n\t\t},\n\t\t{\n\t\t\tPattern: \"x.y.com\",\n\t\t\tValue:   4,\n\t\t},\n\t\t{\n\t\t\tPattern: \"x.y.com\",\n\t\t\tValue:   6,\n\t\t},\n\t}\n\ttestCases := []struct {\n\t\tDomain string\n\t\tResult []uint32\n\t}{\n\t\t{\n\t\t\tDomain: \"v2fly.org\",\n\t\t\tResult: []uint32{1},\n\t\t},\n\t\t{\n\t\t\tDomain: \"y.com\",\n\t\t\tResult: nil,\n\t\t},\n\t\t{\n\t\t\tDomain: \"x.y.com\",\n\t\t\tResult: []uint32{4, 6},\n\t\t},\n\t}\n\tg := NewFullMatcherGroup()\n\tfor _, pattern := range patterns {\n\t\tAddMatcherToGroup(g, FullMatcher(pattern.Pattern), pattern.Value)\n\t}\n\tfor _, testCase := range testCases {\n\t\tr := g.Match(testCase.Domain)\n\t\tif !reflect.DeepEqual(r, testCase.Result) {\n\t\t\tt.Error(\"Failed to match domain: \", testCase.Domain, \", expect \", testCase.Result, \", but got \", r)\n\t\t}\n\t}\n}\n\nfunc TestEmptyFullMatcherGroup(t *testing.T) {\n\tg := NewFullMatcherGroup()\n\tr := g.Match(\"v2fly.org\")\n\tif len(r) != 0 {\n\t\tt.Error(\"Expect [], but \", r)\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_mph.go",
    "content": "package strmatcher\n\nimport (\n\t\"math/bits\"\n\t\"sort\"\n\t\"strings\"\n\t\"unsafe\"\n)\n\n// PrimeRK is the prime base used in Rabin-Karp algorithm.\nconst PrimeRK = 16777619\n\n// RollingHash calculates the rolling murmurHash of given string based on a provided suffix hash.\nfunc RollingHash(hash uint32, input string) uint32 {\n\tfor i := len(input) - 1; i >= 0; i-- {\n\t\thash = hash*PrimeRK + uint32(input[i])\n\t}\n\treturn hash\n}\n\n// MemHash is the hash function used by go map, it utilizes available hardware instructions(behaves\n// as aeshash if aes instruction is available).\n// With different seed, each MemHash<seed> performs as distinct hash functions.\nfunc MemHash(seed uint32, input string) uint32 {\n\treturn uint32(strhash(unsafe.Pointer(&input), uintptr(seed))) // nosemgrep\n}\n\nconst (\n\tmphMatchTypeCount = 2 // Full and Domain\n)\n\ntype mphRuleInfo struct {\n\trollingHash uint32\n\tmatchers    [mphMatchTypeCount][]uint32\n}\n\n// MphMatcherGroup is an implementation of MatcherGroup.\n// It implements Rabin-Karp algorithm and minimal perfect hash table for Full and Domain matcher.\ntype MphMatcherGroup struct {\n\trules      []string   // RuleIdx -> pattern string, index 0 reserved for failed lookup\n\tvalues     [][]uint32 // RuleIdx -> registered matcher values for the pattern (Full Matcher takes precedence)\n\tlevel0     []uint32   // RollingHash & Mask -> seed for Memhash\n\tlevel0Mask uint32     // Mask restricting RollingHash to 0 ~ len(level0)\n\tlevel1     []uint32   // Memhash<seed> & Mask -> stored index for rules\n\tlevel1Mask uint32     // Mask for restricting Memhash<seed> to 0 ~ len(level1)\n\truleInfos  *map[string]mphRuleInfo\n}\n\nfunc NewMphMatcherGroup() *MphMatcherGroup {\n\treturn &MphMatcherGroup{\n\t\trules:      []string{\"\"},\n\t\tvalues:     [][]uint32{nil},\n\t\tlevel0:     nil,\n\t\tlevel0Mask: 0,\n\t\tlevel1:     nil,\n\t\tlevel1Mask: 0,\n\t\truleInfos:  &map[string]mphRuleInfo{}, // Only used for building, destroyed after build complete\n\t}\n}\n\n// AddFullMatcher implements MatcherGroupForFull.\nfunc (g *MphMatcherGroup) AddFullMatcher(matcher FullMatcher, value uint32) {\n\tpattern := strings.ToLower(matcher.Pattern())\n\tg.addPattern(0, \"\", pattern, matcher.Type(), value)\n}\n\n// AddDomainMatcher implements MatcherGroupForDomain.\nfunc (g *MphMatcherGroup) AddDomainMatcher(matcher DomainMatcher, value uint32) {\n\tpattern := strings.ToLower(matcher.Pattern())\n\thash := g.addPattern(0, \"\", pattern, matcher.Type(), value) // For full domain match\n\tg.addPattern(hash, pattern, \".\", matcher.Type(), value)     // For partial domain match\n}\n\nfunc (g *MphMatcherGroup) addPattern(suffixHash uint32, suffixPattern string, pattern string, matcherType Type, value uint32) uint32 {\n\tfullPattern := pattern + suffixPattern\n\tinfo, found := (*g.ruleInfos)[fullPattern]\n\tif !found {\n\t\tinfo = mphRuleInfo{rollingHash: RollingHash(suffixHash, pattern)}\n\t\tg.rules = append(g.rules, fullPattern)\n\t\tg.values = append(g.values, nil)\n\t}\n\tinfo.matchers[matcherType] = append(info.matchers[matcherType], value)\n\t(*g.ruleInfos)[fullPattern] = info\n\treturn info.rollingHash\n}\n\n// Build builds a minimal perfect hash table for insert rules.\n// Algorithm used: Hash, displace, and compress. See http://cmph.sourceforge.net/papers/esa09.pdf\nfunc (g *MphMatcherGroup) Build() error {\n\truleCount := len(*g.ruleInfos)\n\tg.level0 = make([]uint32, nextPow2(ruleCount/4))\n\tg.level0Mask = uint32(len(g.level0) - 1)\n\tg.level1 = make([]uint32, nextPow2(ruleCount))\n\tg.level1Mask = uint32(len(g.level1) - 1)\n\n\t// Create buckets based on all rule's rolling hash\n\tbuckets := make([][]uint32, len(g.level0))\n\tfor ruleIdx := 1; ruleIdx < len(g.rules); ruleIdx++ { // Traverse rules starting from index 1 (0 reserved for failed lookup)\n\t\truleInfo := (*g.ruleInfos)[g.rules[ruleIdx]]\n\t\tbucketIdx := ruleInfo.rollingHash & g.level0Mask\n\t\tbuckets[bucketIdx] = append(buckets[bucketIdx], uint32(ruleIdx))\n\t\tg.values[ruleIdx] = append(ruleInfo.matchers[Full], ruleInfo.matchers[Domain]...) // nolint:gocritic\n\t}\n\tg.ruleInfos = nil // Set ruleInfos nil to release memory\n\n\t// Sort buckets in descending order with respect to each bucket's size\n\tbucketIdxs := make([]int, len(buckets))\n\tfor bucketIdx := range buckets {\n\t\tbucketIdxs[bucketIdx] = bucketIdx\n\t}\n\tsort.Slice(bucketIdxs, func(i, j int) bool { return len(buckets[bucketIdxs[i]]) > len(buckets[bucketIdxs[j]]) })\n\n\t// Exercise Hash, Displace, and Compress algorithm to construct minimal perfect hash table\n\toccupied := make([]bool, len(g.level1)) // Whether a second-level hash has been already used\n\thashedBucket := make([]uint32, 0, 4)    // Second-level hashes for each rule in a specific bucket\n\tfor _, bucketIdx := range bucketIdxs {\n\t\tbucket := buckets[bucketIdx]\n\t\thashedBucket = hashedBucket[:0]\n\t\tseed := uint32(0)\n\t\tfor len(hashedBucket) != len(bucket) {\n\t\t\tfor _, ruleIdx := range bucket {\n\t\t\t\tmemHash := MemHash(seed, g.rules[ruleIdx]) & g.level1Mask\n\t\t\t\tif occupied[memHash] { // Collision occurred with this seed\n\t\t\t\t\tfor _, hash := range hashedBucket { // Revert all values in this hashed bucket\n\t\t\t\t\t\toccupied[hash] = false\n\t\t\t\t\t\tg.level1[hash] = 0\n\t\t\t\t\t}\n\t\t\t\t\thashedBucket = hashedBucket[:0]\n\t\t\t\t\tseed++ // Try next seed\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\toccupied[memHash] = true\n\t\t\t\tg.level1[memHash] = ruleIdx // The final value in the hash table\n\t\t\t\thashedBucket = append(hashedBucket, memHash)\n\t\t\t}\n\t\t}\n\t\tg.level0[bucketIdx] = seed // Displacement value for this bucket\n\t}\n\treturn nil\n}\n\n// Lookup searches for input in minimal perfect hash table and returns its index. 0 indicates not found.\nfunc (g *MphMatcherGroup) Lookup(rollingHash uint32, input string) uint32 {\n\ti0 := rollingHash & g.level0Mask\n\tseed := g.level0[i0]\n\ti1 := MemHash(seed, input) & g.level1Mask\n\tif n := g.level1[i1]; g.rules[n] == input {\n\t\treturn n\n\t}\n\treturn 0\n}\n\n// Match implements MatcherGroup.Match.\nfunc (g *MphMatcherGroup) Match(input string) []uint32 {\n\tmatches := make([][]uint32, 0, 5)\n\thash := uint32(0)\n\tfor i := len(input) - 1; i >= 0; i-- {\n\t\thash = hash*PrimeRK + uint32(input[i])\n\t\tif input[i] == '.' {\n\t\t\tif mphIdx := g.Lookup(hash, input[i:]); mphIdx != 0 {\n\t\t\t\tmatches = append(matches, g.values[mphIdx])\n\t\t\t}\n\t\t}\n\t}\n\tif mphIdx := g.Lookup(hash, input); mphIdx != 0 {\n\t\tmatches = append(matches, g.values[mphIdx])\n\t}\n\treturn CompositeMatchesReverse(matches)\n}\n\n// MatchAny implements MatcherGroup.MatchAny.\nfunc (g *MphMatcherGroup) MatchAny(input string) bool {\n\thash := uint32(0)\n\tfor i := len(input) - 1; i >= 0; i-- {\n\t\thash = hash*PrimeRK + uint32(input[i])\n\t\tif input[i] == '.' {\n\t\t\tif g.Lookup(hash, input[i:]) != 0 {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn g.Lookup(hash, input) != 0\n}\n\nfunc nextPow2(v int) int {\n\tif v <= 1 {\n\t\treturn 1\n\t}\n\tconst MaxUInt = ^uint(0)\n\tn := (MaxUInt >> bits.LeadingZeros(uint(v))) + 1\n\treturn int(n)\n}\n\n//go:noescape\n//go:linkname strhash runtime.strhash\nfunc strhash(p unsafe.Pointer, h uintptr) uintptr\n"
  },
  {
    "path": "common/strmatcher/matchergroup_mph_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestMphMatcherGroup(t *testing.T) {\n\tcases1 := []struct {\n\t\tpattern string\n\t\tmType   Type\n\t\tinput   string\n\t\toutput  bool\n\t}{\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"www.v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"www.v3fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"xv2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t\tinput:   \"v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t\tinput:   \"xv2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t}\n\tfor _, test := range cases1 {\n\t\tmph := NewMphMatcherGroup()\n\t\tmatcher, err := test.mType.New(test.pattern)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(mph, matcher, 0))\n\t\tmph.Build()\n\t\tif m := mph.MatchAny(test.input); m != test.output {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n\t{\n\t\tcases2Input := []struct {\n\t\t\tpattern string\n\t\t\tmType   Type\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"163.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"m.126.com\",\n\t\t\t\tmType:   Full,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"3.com\",\n\t\t\t\tmType:   Full,\n\t\t\t},\n\t\t}\n\t\tmph := NewMphMatcherGroup()\n\t\tfor _, test := range cases2Input {\n\t\t\tmatcher, err := test.mType.New(test.pattern)\n\t\t\tcommon.Must(err)\n\t\t\tcommon.Must(AddMatcherToGroup(mph, matcher, 0))\n\t\t}\n\t\tmph.Build()\n\t\tcases2Output := []struct {\n\t\t\tpattern string\n\t\t\tres     bool\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"126.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"m.163.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"mm163.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"m.126.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"163.com\",\n\t\t\t\tres:     true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"63.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"oogle.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"vvgoogle.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t}\n\t\tfor _, test := range cases2Output {\n\t\t\tif m := mph.MatchAny(test.pattern); m != test.res {\n\t\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tcases3Input := []struct {\n\t\t\tpattern string\n\t\t\tmType   Type\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"video.google.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpattern: \"gle.com\",\n\t\t\t\tmType:   Domain,\n\t\t\t},\n\t\t}\n\t\tmph := NewMphMatcherGroup()\n\t\tfor _, test := range cases3Input {\n\t\t\tmatcher, err := test.mType.New(test.pattern)\n\t\t\tcommon.Must(err)\n\t\t\tcommon.Must(AddMatcherToGroup(mph, matcher, 0))\n\t\t}\n\t\tmph.Build()\n\t\tcases3Output := []struct {\n\t\t\tpattern string\n\t\t\tres     bool\n\t\t}{\n\t\t\t{\n\t\t\t\tpattern: \"google.com\",\n\t\t\t\tres:     false,\n\t\t\t},\n\t\t}\n\t\tfor _, test := range cases3Output {\n\t\t\tif m := mph.MatchAny(test.pattern); m != test.res {\n\t\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// See https://github.com/v2fly/v2ray-core/issues/92#issuecomment-673238489\nfunc TestMphMatcherGroupAsIndexMatcher(t *testing.T) {\n\trules := []struct {\n\t\tType   Type\n\t\tDomain string\n\t}{\n\t\t// Regex not supported by MphMatcherGroup\n\t\t// {\n\t\t// \tType:   Regex,\n\t\t// \tDomain: \"apis\\\\.us$\",\n\t\t// },\n\t\t// Substr not supported by MphMatcherGroup\n\t\t// {\n\t\t// \tType:   Substr,\n\t\t// \tDomain: \"apis\",\n\t\t// },\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t// Substr not supported by MphMatcherGroup, We add another matcher to preserve index\n\t\t{\n\t\t\tType:   Domain,        // Substr,\n\t\t\tDomain: \"example.com\", // \"apis\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"fonts.googleapis.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Full,\n\t\t\tDomain: \"www.baidu.com\",\n\t\t},\n\t\t{ // This matcher (index 10) is swapped with matcher (index 6) to test that full matcher takes high priority.\n\t\t\tType:   Full,\n\t\t\tDomain: \"example.com\",\n\t\t},\n\t\t{\n\t\t\tType:   Domain,\n\t\t\tDomain: \"example.com\",\n\t\t},\n\t}\n\tcases := []struct {\n\t\tInput  string\n\t\tOutput []uint32\n\t}{\n\t\t{\n\t\t\tInput:  \"www.baidu.com\",\n\t\t\tOutput: []uint32{5, 9, 4},\n\t\t},\n\t\t{\n\t\t\tInput:  \"fonts.googleapis.com\",\n\t\t\tOutput: []uint32{8, 3, 7, 4 /*2, 6*/},\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.googleapis.com\",\n\t\t\tOutput: []uint32{3, 7, 4 /*2, 6*/},\n\t\t},\n\t\t{\n\t\t\tInput: \"testapis.us\",\n\t\t\t// Output: []uint32{ /*2, 6*/ /*1,*/ },\n\t\t\tOutput: nil,\n\t\t},\n\t\t{\n\t\t\tInput:  \"example.com\",\n\t\t\tOutput: []uint32{10, 6, 11, 4},\n\t\t},\n\t}\n\tmatcherGroup := NewMphMatcherGroup()\n\tfor i, rule := range rules {\n\t\tmatcher, err := rule.Type.New(rule.Domain)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(matcherGroup, matcher, uint32(i+3)))\n\t}\n\tmatcherGroup.Build()\n\tfor _, test := range cases {\n\t\tif m := matcherGroup.Match(test.Input); !reflect.DeepEqual(m, test.Output) {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n}\n\nfunc TestEmptyMphMatcherGroup(t *testing.T) {\n\tg := NewMphMatcherGroup()\n\tg.Build()\n\tr := g.Match(\"v2fly.org\")\n\tif len(r) != 0 {\n\t\tt.Error(\"Expect [], but \", r)\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_simple.go",
    "content": "package strmatcher\n\ntype matcherEntry struct {\n\tmatcher Matcher\n\tvalue   uint32\n}\n\n// SimpleMatcherGroup is an implementation of MatcherGroup.\n// It simply stores all matchers in an array and sequentially matches them.\ntype SimpleMatcherGroup struct {\n\tmatchers []matcherEntry\n}\n\n// AddMatcher implements MatcherGroupForAll.AddMatcher.\nfunc (g *SimpleMatcherGroup) AddMatcher(matcher Matcher, value uint32) {\n\tg.matchers = append(g.matchers, matcherEntry{\n\t\tmatcher: matcher,\n\t\tvalue:   value,\n\t})\n}\n\n// Match implements MatcherGroup.Match.\nfunc (g *SimpleMatcherGroup) Match(input string) []uint32 {\n\tresult := []uint32{}\n\tfor _, e := range g.matchers {\n\t\tif e.matcher.Match(input) {\n\t\t\tresult = append(result, e.value)\n\t\t}\n\t}\n\treturn result\n}\n\n// MatchAny implements MatcherGroup.MatchAny.\nfunc (g *SimpleMatcherGroup) MatchAny(input string) bool {\n\tfor _, e := range g.matchers {\n\t\tif e.matcher.Match(input) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_simple_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestSimpleMatcherGroup(t *testing.T) {\n\tpatterns := []struct {\n\t\tpattern string\n\t\tmType   Type\n\t}{\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Regex,\n\t\t},\n\t}\n\tcases := []struct {\n\t\tinput  string\n\t\toutput []uint32\n\t}{\n\t\t{\n\t\t\tinput:  \"www.v2fly.org\",\n\t\t\toutput: []uint32{0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"v2fly.org\",\n\t\t\toutput: []uint32{0, 1, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"www.v3fly.org\",\n\t\t\toutput: []uint32{},\n\t\t},\n\t\t{\n\t\t\tinput:  \"2fly.org\",\n\t\t\toutput: []uint32{},\n\t\t},\n\t\t{\n\t\t\tinput:  \"xv2fly.org\",\n\t\t\toutput: []uint32{2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"v2flyxorg\",\n\t\t\toutput: []uint32{2},\n\t\t},\n\t}\n\tmatcherGroup := &SimpleMatcherGroup{}\n\tfor id, entry := range patterns {\n\t\tmatcher, err := entry.mType.New(entry.pattern)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(matcherGroup, matcher, uint32(id)))\n\t}\n\tfor _, test := range cases {\n\t\tif r := matcherGroup.Match(test.input); !reflect.DeepEqual(r, test.output) {\n\t\t\tt.Error(\"unexpected output: \", r, \" for test case \", test)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_substr.go",
    "content": "package strmatcher\n\nimport (\n\t\"sort\"\n\t\"strings\"\n)\n\n// SubstrMatcherGroup is implementation of MatcherGroup,\n// It is simply implmeneted to comply with the priority specification of Substr matchers.\ntype SubstrMatcherGroup struct {\n\tpatterns []string\n\tvalues   []uint32\n}\n\n// AddSubstrMatcher implements MatcherGroupForSubstr.AddSubstrMatcher.\nfunc (g *SubstrMatcherGroup) AddSubstrMatcher(matcher SubstrMatcher, value uint32) {\n\tg.patterns = append(g.patterns, matcher.Pattern())\n\tg.values = append(g.values, value)\n}\n\n// Match implements MatcherGroup.Match.\nfunc (g *SubstrMatcherGroup) Match(input string) []uint32 {\n\tvar result []uint32\n\tfor i, pattern := range g.patterns {\n\t\tfor j := strings.LastIndex(input, pattern); j != -1; j = strings.LastIndex(input[:j], pattern) {\n\t\t\tresult = append(result, uint32(j)<<16|uint32(i)&0xffff) // uint32: position (higher 16 bit) | patternIdx (lower 16 bit)\n\t\t}\n\t}\n\t// sort.Slice will trigger allocation no matter what input is. See https://github.com/golang/go/issues/17332\n\t// We optimize the sorting by length to prevent memory allocation as possible.\n\tswitch len(result) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\t// No need to sort\n\tcase 2:\n\t\t// Do a simple swap if unsorted\n\t\tif result[0] > result[1] {\n\t\t\tresult[0], result[1] = result[1], result[0]\n\t\t}\n\tdefault:\n\t\t// Sort the match results in dictionary order, so that:\n\t\t//   1. Pattern matched at smaller position (meaning matched further) takes precedence.\n\t\t//   2. When patterns matched at same position, pattern with smaller index (meaning inserted early) takes precedence.\n\t\tsort.Slice(result, func(i, j int) bool { return result[i] < result[j] })\n\t}\n\tfor i, entry := range result {\n\t\tresult[i] = g.values[entry&0xffff] // Get pattern value from its index (the lower 16 bit)\n\t}\n\treturn result\n}\n\n// MatchAny implements MatcherGroup.MatchAny.\nfunc (g *SubstrMatcherGroup) MatchAny(input string) bool {\n\tfor _, pattern := range g.patterns {\n\t\tif strings.Contains(input, pattern) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "common/strmatcher/matchergroup_substr_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestSubstrMatcherGroup(t *testing.T) {\n\tpatterns := []struct {\n\t\tpattern string\n\t\tmType   Type\n\t}{\n\t\t{\n\t\t\tpattern: \"apis\",\n\t\t\tmType:   Substr,\n\t\t},\n\t\t{\n\t\t\tpattern: \"google\",\n\t\t\tmType:   Substr,\n\t\t},\n\t\t{\n\t\t\tpattern: \"apis\",\n\t\t\tmType:   Substr,\n\t\t},\n\t}\n\tcases := []struct {\n\t\tinput  string\n\t\toutput []uint32\n\t}{\n\t\t{\n\t\t\tinput:  \"google.com\",\n\t\t\toutput: []uint32{1},\n\t\t},\n\t\t{\n\t\t\tinput:  \"apis.com\",\n\t\t\toutput: []uint32{0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"googleapis.com\",\n\t\t\toutput: []uint32{1, 0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"fonts.googleapis.com\",\n\t\t\toutput: []uint32{1, 0, 2},\n\t\t},\n\t\t{\n\t\t\tinput:  \"apis.googleapis.com\",\n\t\t\toutput: []uint32{0, 2, 1, 0, 2},\n\t\t},\n\t}\n\tmatcherGroup := &SubstrMatcherGroup{}\n\tfor id, entry := range patterns {\n\t\tmatcher, err := entry.mType.New(entry.pattern)\n\t\tcommon.Must(err)\n\t\tcommon.Must(AddMatcherToGroup(matcherGroup, matcher, uint32(id)))\n\t}\n\tfor _, test := range cases {\n\t\tif r := matcherGroup.Match(test.input); !reflect.DeepEqual(r, test.output) {\n\t\t\tt.Error(\"unexpected output: \", r, \" for test case \", test)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchers.go",
    "content": "package strmatcher\n\nimport (\n\t\"errors\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/net/idna\"\n)\n\n// FullMatcher is an implementation of Matcher.\ntype FullMatcher string\n\nfunc (FullMatcher) Type() Type {\n\treturn Full\n}\n\nfunc (m FullMatcher) Pattern() string {\n\treturn string(m)\n}\n\nfunc (m FullMatcher) String() string {\n\treturn \"full:\" + m.Pattern()\n}\n\nfunc (m FullMatcher) Match(s string) bool {\n\treturn string(m) == s\n}\n\n// DomainMatcher is an implementation of Matcher.\ntype DomainMatcher string\n\nfunc (DomainMatcher) Type() Type {\n\treturn Domain\n}\n\nfunc (m DomainMatcher) Pattern() string {\n\treturn string(m)\n}\n\nfunc (m DomainMatcher) String() string {\n\treturn \"domain:\" + m.Pattern()\n}\n\nfunc (m DomainMatcher) Match(s string) bool {\n\tpattern := m.Pattern()\n\tif !strings.HasSuffix(s, pattern) {\n\t\treturn false\n\t}\n\treturn len(s) == len(pattern) || s[len(s)-len(pattern)-1] == '.'\n}\n\n// SubstrMatcher is an implementation of Matcher.\ntype SubstrMatcher string\n\nfunc (SubstrMatcher) Type() Type {\n\treturn Substr\n}\n\nfunc (m SubstrMatcher) Pattern() string {\n\treturn string(m)\n}\n\nfunc (m SubstrMatcher) String() string {\n\treturn \"keyword:\" + m.Pattern()\n}\n\nfunc (m SubstrMatcher) Match(s string) bool {\n\treturn strings.Contains(s, m.Pattern())\n}\n\n// RegexMatcher is an implementation of Matcher.\ntype RegexMatcher struct {\n\tpattern *regexp.Regexp\n}\n\nfunc (*RegexMatcher) Type() Type {\n\treturn Regex\n}\n\nfunc (m *RegexMatcher) Pattern() string {\n\treturn m.pattern.String()\n}\n\nfunc (m *RegexMatcher) String() string {\n\treturn \"regexp:\" + m.Pattern()\n}\n\nfunc (m *RegexMatcher) Match(s string) bool {\n\treturn m.pattern.MatchString(s)\n}\n\n// New creates a new Matcher based on the given pattern.\nfunc (t Type) New(pattern string) (Matcher, error) {\n\tswitch t {\n\tcase Full:\n\t\treturn FullMatcher(pattern), nil\n\tcase Substr:\n\t\treturn SubstrMatcher(pattern), nil\n\tcase Domain:\n\t\tpattern, err := ToDomain(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn DomainMatcher(pattern), nil\n\tcase Regex: // 1. regex matching is case-sensitive\n\t\tregex, err := regexp.Compile(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &RegexMatcher{pattern: regex}, nil\n\tdefault:\n\t\treturn nil, errors.New(\"unknown matcher type\")\n\t}\n}\n\n// NewDomainPattern creates a new Matcher based on the given domain pattern.\n// It works like `Type.New`, but will do validation and conversion to ensure it's a valid domain pattern.\nfunc (t Type) NewDomainPattern(pattern string) (Matcher, error) {\n\tswitch t {\n\tcase Full:\n\t\tpattern, err := ToDomain(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn FullMatcher(pattern), nil\n\tcase Substr:\n\t\tpattern, err := ToDomain(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn SubstrMatcher(pattern), nil\n\tcase Domain:\n\t\tpattern, err := ToDomain(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn DomainMatcher(pattern), nil\n\tcase Regex: // Regex's charset not in LDH subset\n\t\tregex, err := regexp.Compile(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &RegexMatcher{pattern: regex}, nil\n\tdefault:\n\t\treturn nil, errors.New(\"unknown matcher type\")\n\t}\n}\n\n// ToDomain converts input pattern to a domain string, and return error if such a conversion cannot be made.\n//  1. Conforms to Letter-Digit-Hyphen (LDH) subset (https://tools.ietf.org/html/rfc952):\n//     * Letters A to Z (no distinction between uppercase and lowercase, we convert to lowers)\n//     * Digits 0 to 9\n//     * Hyphens(-) and Periods(.)\n//  2. If any non-ASCII characters, domain are converted from Internationalized domain name to Punycode.\nfunc ToDomain(pattern string) (string, error) {\n\tfor {\n\t\tisASCII, hasUpper := true, false\n\t\tfor i := 0; i < len(pattern); i++ {\n\t\t\tc := pattern[i]\n\t\t\tif c >= utf8.RuneSelf {\n\t\t\t\tisASCII = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tswitch {\n\t\t\tcase 'A' <= c && c <= 'Z':\n\t\t\t\thasUpper = true\n\t\t\tcase 'a' <= c && c <= 'z':\n\t\t\tcase '0' <= c && c <= '9':\n\t\t\tcase c == '-':\n\t\t\tcase c == '.':\n\t\t\tdefault:\n\t\t\t\treturn \"\", errors.New(\"pattern string does not conform to Letter-Digit-Hyphen (LDH) subset\")\n\t\t\t}\n\t\t}\n\t\tif !isASCII {\n\t\t\tvar err error\n\t\t\tpattern, err = idna.Punycode.ToASCII(pattern)\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\tif hasUpper {\n\t\t\tpattern = strings.ToLower(pattern)\n\t\t}\n\t\tbreak\n\t}\n\treturn pattern, nil\n}\n\n// MatcherGroupForAll is an interface indicating a MatcherGroup could accept all types of matchers.\ntype MatcherGroupForAll interface {\n\tAddMatcher(matcher Matcher, value uint32)\n}\n\n// MatcherGroupForFull is an interface indicating a MatcherGroup could accept FullMatchers.\ntype MatcherGroupForFull interface {\n\tAddFullMatcher(matcher FullMatcher, value uint32)\n}\n\n// MatcherGroupForDomain is an interface indicating a MatcherGroup could accept DomainMatchers.\ntype MatcherGroupForDomain interface {\n\tAddDomainMatcher(matcher DomainMatcher, value uint32)\n}\n\n// MatcherGroupForSubstr is an interface indicating a MatcherGroup could accept SubstrMatchers.\ntype MatcherGroupForSubstr interface {\n\tAddSubstrMatcher(matcher SubstrMatcher, value uint32)\n}\n\n// MatcherGroupForRegex is an interface indicating a MatcherGroup could accept RegexMatchers.\ntype MatcherGroupForRegex interface {\n\tAddRegexMatcher(matcher *RegexMatcher, value uint32)\n}\n\n// AddMatcherToGroup is a helper function to try to add a Matcher to any kind of MatcherGroup.\n// It returns error if the MatcherGroup does not accept the provided Matcher's type.\n// This function is provided to help writing code to test a MatcherGroup.\nfunc AddMatcherToGroup(g MatcherGroup, matcher Matcher, value uint32) error {\n\tif g, ok := g.(IndexMatcher); ok {\n\t\tg.Add(matcher)\n\t\treturn nil\n\t}\n\tif g, ok := g.(MatcherGroupForAll); ok {\n\t\tg.AddMatcher(matcher, value)\n\t\treturn nil\n\t}\n\tswitch matcher := matcher.(type) {\n\tcase FullMatcher:\n\t\tif g, ok := g.(MatcherGroupForFull); ok {\n\t\t\tg.AddFullMatcher(matcher, value)\n\t\t\treturn nil\n\t\t}\n\tcase DomainMatcher:\n\t\tif g, ok := g.(MatcherGroupForDomain); ok {\n\t\t\tg.AddDomainMatcher(matcher, value)\n\t\t\treturn nil\n\t\t}\n\tcase SubstrMatcher:\n\t\tif g, ok := g.(MatcherGroupForSubstr); ok {\n\t\t\tg.AddSubstrMatcher(matcher, value)\n\t\t\treturn nil\n\t\t}\n\tcase *RegexMatcher:\n\t\tif g, ok := g.(MatcherGroupForRegex); ok {\n\t\t\tg.AddRegexMatcher(matcher, value)\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn errors.New(\"cannot add matcher to matcher group\")\n}\n\n// CompositeMatches flattens the matches slice to produce a single matched indices slice.\n// It is designed to avoid new memory allocation as possible.\nfunc CompositeMatches(matches [][]uint32) []uint32 {\n\tswitch len(matches) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\treturn matches[0]\n\tdefault:\n\t\tresult := make([]uint32, 0, 5)\n\t\tfor i := 0; i < len(matches); i++ {\n\t\t\tresult = append(result, matches[i]...)\n\t\t}\n\t\treturn result\n\t}\n}\n\n// CompositeMatches flattens the matches slice to produce a single matched indices slice.\n// It is designed that:\n//  1. All matchers are concatenated in reverse order, so the matcher that matches further ranks higher.\n//  2. Indices in the same matcher keeps their original order.\n//  3. Avoid new memory allocation as possible.\nfunc CompositeMatchesReverse(matches [][]uint32) []uint32 {\n\tswitch len(matches) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\treturn matches[0]\n\tdefault:\n\t\tresult := make([]uint32, 0, 5)\n\t\tfor i := len(matches) - 1; i >= 0; i-- {\n\t\t\tresult = append(result, matches[i]...)\n\t\t}\n\t\treturn result\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/matchers_test.go",
    "content": "package strmatcher_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"unsafe\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n)\n\nfunc TestMatcher(t *testing.T) {\n\tcases := []struct {\n\t\tpattern string\n\t\tmType   Type\n\t\tinput   string\n\t\toutput  bool\n\t}{\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"www.v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"www.v3fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Domain,\n\t\t\tinput:   \"xv2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t\tinput:   \"v2fly.org\",\n\t\t\toutput:  true,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Full,\n\t\t\tinput:   \"xv2fly.org\",\n\t\t\toutput:  false,\n\t\t},\n\t\t{\n\t\t\tpattern: \"v2fly.org\",\n\t\t\tmType:   Regex,\n\t\t\tinput:   \"v2flyxorg\",\n\t\t\toutput:  true,\n\t\t},\n\t}\n\tfor _, test := range cases {\n\t\tmatcher, err := test.mType.New(test.pattern)\n\t\tcommon.Must(err)\n\t\tif m := matcher.Match(test.input); m != test.output {\n\t\t\tt.Error(\"unexpected output: \", m, \" for test case \", test)\n\t\t}\n\t}\n}\n\nfunc TestToDomain(t *testing.T) {\n\t{ // Test normal ASCII domain, which should not trigger new string data allocation\n\t\tinput := \"v2fly.org\"\n\t\tdomain, err := ToDomain(input)\n\t\tif err != nil {\n\t\t\tt.Error(\"unexpected error: \", err)\n\t\t}\n\t\tif domain != input {\n\t\t\tt.Error(\"unexpected output: \", domain, \" for test case \", input)\n\t\t}\n\t\tif (*reflect.StringHeader)(unsafe.Pointer(&input)).Data != (*reflect.StringHeader)(unsafe.Pointer(&domain)).Data {\n\t\t\tt.Error(\"different string data of output: \", domain, \" and test case \", input)\n\t\t}\n\t}\n\t{ // Test ASCII domain containing upper case letter, which should be converted to lower case\n\t\tinput := \"v2FLY.oRg\"\n\t\tdomain, err := ToDomain(input)\n\t\tif err != nil {\n\t\t\tt.Error(\"unexpected error: \", err)\n\t\t}\n\t\tif domain != \"v2fly.org\" {\n\t\t\tt.Error(\"unexpected output: \", domain, \" for test case \", input)\n\t\t}\n\t}\n\t{ // Test internationalized domain, which should be translated to ASCII punycode\n\t\tinput := \"v2fly.公益\"\n\t\tdomain, err := ToDomain(input)\n\t\tif err != nil {\n\t\t\tt.Error(\"unexpected error: \", err)\n\t\t}\n\t\tif domain != \"v2fly.xn--55qw42g\" {\n\t\t\tt.Error(\"unexpected output: \", domain, \" for test case \", input)\n\t\t}\n\t}\n\t{ // Test internationalized domain containing upper case letter\n\t\tinput := \"v2FLY.公益\"\n\t\tdomain, err := ToDomain(input)\n\t\tif err != nil {\n\t\t\tt.Error(\"unexpected error: \", err)\n\t\t}\n\t\tif domain != \"v2fly.xn--55qw42g\" {\n\t\t\tt.Error(\"unexpected output: \", domain, \" for test case \", input)\n\t\t}\n\t}\n\t{ // Test domain name of invalid character, which should return with error\n\t\tinput := \"{\"\n\t\t_, err := ToDomain(input)\n\t\tif err == nil {\n\t\t\tt.Error(\"unexpected non error for test case \", input)\n\t\t}\n\t}\n\t{ // Test domain name containing a space, which should return with error\n\t\tinput := \"Mijia Cloud\"\n\t\t_, err := ToDomain(input)\n\t\tif err == nil {\n\t\t\tt.Error(\"unexpected non error for test case \", input)\n\t\t}\n\t}\n\t{ // Test domain name containing an underscore, which should return with error\n\t\tinput := \"Mijia_Cloud.com\"\n\t\t_, err := ToDomain(input)\n\t\tif err == nil {\n\t\t\tt.Error(\"unexpected non error for test case \", input)\n\t\t}\n\t}\n\t{ // Test internationalized domain containing invalid character\n\t\tinput := \"Mijia Cloud.公司\"\n\t\t_, err := ToDomain(input)\n\t\tif err == nil {\n\t\t\tt.Error(\"unexpected non error for test case \", input)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "common/strmatcher/strmatcher.go",
    "content": "package strmatcher\n\n// Type is the type of the matcher.\ntype Type byte\n\nconst (\n\t// Full is the type of matcher that the input string must exactly equal to the pattern.\n\tFull Type = 0\n\t// Domain is the type of matcher that the input string must be a sub-domain or itself of the pattern.\n\tDomain Type = 1\n\t// Substr is the type of matcher that the input string must contain the pattern as a sub-string.\n\tSubstr Type = 2\n\t// Regex is the type of matcher that the input string must matches the regular-expression pattern.\n\tRegex Type = 3\n)\n\n// Matcher is the interface to determine a string matches a pattern.\n//   - This is a basic matcher to represent a certain kind of match semantic(full, substr, domain or regex).\ntype Matcher interface {\n\t// Type returns the matcher's type.\n\tType() Type\n\n\t// Pattern returns the matcher's raw string representation.\n\tPattern() string\n\n\t// String returns a string representation of the matcher containing its type and pattern.\n\tString() string\n\n\t// Match returns true if the given string matches a predefined pattern.\n\t//   * This method is seldom used for performance reason\n\t//     and is generally taken over by their corresponding MatcherGroup.\n\tMatch(input string) bool\n}\n\n// MatcherGroup is an advanced type of matcher to accept a bunch of basic Matchers (of certain type, not all matcher types).\n// For example:\n//   - FullMatcherGroup accepts FullMatcher and uses a hash table to facilitate lookup.\n//   - DomainMatcherGroup accepts DomainMatcher and uses a trie to optimize both memory consumption and lookup speed.\ntype MatcherGroup interface {\n\t// Match returns all matched matchers with their corresponding values.\n\tMatch(input string) []uint32\n\n\t// MatchAny returns true as soon as one matching matcher is found.\n\tMatchAny(input string) bool\n}\n\n// IndexMatcher is a general type of matcher thats accepts all kinds of basic matchers.\n// It should:\n//   - Accept all Matcher types with no exception.\n//   - Optimize string matching with a combination of MatcherGroups.\n//   - Obey certain priority order specification when returning matched Matchers.\ntype IndexMatcher interface {\n\t// Size returns number of matchers added to IndexMatcher.\n\tSize() uint32\n\n\t// Add adds a new Matcher to IndexMatcher, and returns its index. The index will never be 0.\n\tAdd(matcher Matcher) uint32\n\n\t// Build builds the IndexMatcher to be ready for matching.\n\tBuild() error\n\n\t// Match returns the indices of all matchers that matches the input.\n\t//   * Empty array is returned if no such matcher exists.\n\t//   * The order of returned matchers should follow priority specification.\n\t// Priority specification:\n\t//   1. Priority between matcher types: full > domain > substr > regex.\n\t//   2. Priority of same-priority matchers matching at same position: the early added takes precedence.\n\t//   3. Priority of domain matchers matching at different levels: the further matched domain takes precedence.\n\t//   4. Priority of substr matchers matching at different positions: the further matched substr takes precedence.\n\tMatch(input string) []uint32\n\n\t// MatchAny returns true as soon as one matching matcher is found.\n\tMatchAny(input string) bool\n}\n"
  },
  {
    "path": "common/taggedfeatures/configloader.go",
    "content": "package taggedfeatures\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/v5cfg\"\n)\n\nfunc LoadJSONConfig(ctx context.Context, interfaceType, defaultImpl string, message json.RawMessage) (*Config, error) {\n\ttype ItemStub struct {\n\t\tMemberType string          `json:\"type\"`\n\t\tTag        string          `json:\"tag\"`\n\t\tValue      json.RawMessage `json:\"settings\"`\n\t}\n\ttype namedStub []ItemStub\n\tvar stub namedStub\n\terr := json.Unmarshal(message, &stub)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconfig := &Config{Features: map[string]*anypb.Any{}}\n\tfor _, v := range stub {\n\t\tif v.MemberType == \"\" {\n\t\t\tv.MemberType = defaultImpl\n\t\t}\n\t\tpack, err := v5cfg.LoadHeterogeneousConfigFromRawJSON(ctx, interfaceType, v.MemberType, v.Value)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Features[v.Tag] = serial.ToTypedMessage(pack)\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "common/taggedfeatures/creator.go",
    "content": "package taggedfeatures\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\nfunc NewHolderFromConfig(ctx context.Context, config *Config, memberType interface{}) (features.TaggedFeatures, error) {\n\tholder := NewHolder(ctx, memberType)\n\tfor k, v := range config.Features {\n\t\tvar err error\n\t\tinstance, err := serial.GetInstanceOf(v)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to get instance\").Base(err)\n\t\t}\n\t\tobj, err := common.CreateObject(ctx, instance)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create object\").Base(err)\n\t\t}\n\n\t\tif feat, ok := obj.(features.Feature); ok {\n\t\t\terr = holder.AddFeaturesByTag(k, feat)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"unable to add feature\").Base(err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\treturn nil, newError(\"not a feature \", k)\n\t}\n\treturn holder, nil\n}\n"
  },
  {
    "path": "common/taggedfeatures/errors.generated.go",
    "content": "package taggedfeatures\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/taggedfeatures/holder.go",
    "content": "package taggedfeatures\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\ntype Holder struct {\n\taccess     *sync.RWMutex\n\tfeatures   map[string]features.Feature\n\tmemberType reflect.Type\n\tctx        context.Context\n}\n\nfunc NewHolder(ctx context.Context, memberType interface{}) *Holder {\n\treturn &Holder{\n\t\tctx:        ctx,\n\t\taccess:     &sync.RWMutex{},\n\t\tfeatures:   make(map[string]features.Feature),\n\t\tmemberType: reflect.TypeOf(memberType),\n\t}\n}\n\nfunc (h *Holder) GetFeaturesByTag(tag string) (features.Feature, error) {\n\th.access.RLock()\n\tdefer h.access.RUnlock()\n\tfeature, ok := h.features[tag]\n\tif !ok {\n\t\treturn nil, newError(\"unable to find feature with tag\")\n\t}\n\treturn feature, nil\n}\n\nfunc (h *Holder) AddFeaturesByTag(tag string, feature features.Feature) error {\n\th.access.Lock()\n\tdefer h.access.Unlock()\n\tfeatureType := reflect.TypeOf(feature.Type())\n\tif !featureType.AssignableTo(h.memberType) {\n\t\treturn newError(\"feature is not assignable to the base type\")\n\t}\n\th.features[tag] = feature\n\treturn nil\n}\n\nfunc (h *Holder) RemoveFeaturesByTag(tag string) error {\n\th.access.Lock()\n\tdefer h.access.Unlock()\n\tdelete(h.features, tag)\n\treturn nil\n}\n\nfunc (h *Holder) GetFeaturesTag() ([]string, error) {\n\th.access.RLock()\n\tdefer h.access.RUnlock()\n\tvar ret []string\n\tfor key := range h.features {\n\t\tret = append(ret, key)\n\t}\n\treturn ret, nil\n}\n\nfunc (h *Holder) Start() error {\n\th.access.Lock()\n\tdefer h.access.Unlock()\n\tvar startTasks []func() error\n\tfor _, v := range h.features {\n\t\tstartTasks = append(startTasks, v.Start)\n\t}\n\treturn task.Run(h.ctx, startTasks...)\n}\n\nfunc (h *Holder) Close() error {\n\th.access.Lock()\n\tdefer h.access.Unlock()\n\n\tvar closeTasks []func() error\n\tfor _, v := range h.features {\n\t\tcloseTasks = append(closeTasks, v.Close)\n\t}\n\treturn task.Run(h.ctx, closeTasks...)\n}\n"
  },
  {
    "path": "common/taggedfeatures/skeleton.pb.go",
    "content": "package taggedfeatures\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\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tFeatures      map[string]*anypb.Any  `protobuf:\"bytes,1,rep,name=features,proto3\" json:\"features,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_common_taggedfeatures_skeleton_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_common_taggedfeatures_skeleton_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_common_taggedfeatures_skeleton_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetFeatures() map[string]*anypb.Any {\n\tif x != nil {\n\t\treturn x.Features\n\t}\n\treturn nil\n}\n\nvar File_common_taggedfeatures_skeleton_proto protoreflect.FileDescriptor\n\nconst file_common_taggedfeatures_skeleton_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$common/taggedfeatures/skeleton.proto\\x12 v2ray.core.common.taggedfeatures\\x1a\\x19google/protobuf/any.proto\\\"\\xaf\\x01\\n\" +\n\t\"\\x06Config\\x12R\\n\" +\n\t\"\\bfeatures\\x18\\x01 \\x03(\\v26.v2ray.core.common.taggedfeatures.Config.FeaturesEntryR\\bfeatures\\x1aQ\\n\" +\n\t\"\\rFeaturesEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12*\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x05value:\\x028\\x01B\\x81\\x01\\n\" +\n\t\"$com.v2ray.core.common.taggedfeaturesP\\x01Z4github.com/v2fly/v2ray-core/v5/common/taggedfeatures\\xaa\\x02 V2Ray.Core.Common.Taggedfeaturesb\\x06proto3\"\n\nvar (\n\tfile_common_taggedfeatures_skeleton_proto_rawDescOnce sync.Once\n\tfile_common_taggedfeatures_skeleton_proto_rawDescData []byte\n)\n\nfunc file_common_taggedfeatures_skeleton_proto_rawDescGZIP() []byte {\n\tfile_common_taggedfeatures_skeleton_proto_rawDescOnce.Do(func() {\n\t\tfile_common_taggedfeatures_skeleton_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_taggedfeatures_skeleton_proto_rawDesc), len(file_common_taggedfeatures_skeleton_proto_rawDesc)))\n\t})\n\treturn file_common_taggedfeatures_skeleton_proto_rawDescData\n}\n\nvar file_common_taggedfeatures_skeleton_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_common_taggedfeatures_skeleton_proto_goTypes = []any{\n\t(*Config)(nil),    // 0: v2ray.core.common.taggedfeatures.Config\n\tnil,               // 1: v2ray.core.common.taggedfeatures.Config.FeaturesEntry\n\t(*anypb.Any)(nil), // 2: google.protobuf.Any\n}\nvar file_common_taggedfeatures_skeleton_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.common.taggedfeatures.Config.features:type_name -> v2ray.core.common.taggedfeatures.Config.FeaturesEntry\n\t2, // 1: v2ray.core.common.taggedfeatures.Config.FeaturesEntry.value:type_name -> google.protobuf.Any\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_common_taggedfeatures_skeleton_proto_init() }\nfunc file_common_taggedfeatures_skeleton_proto_init() {\n\tif File_common_taggedfeatures_skeleton_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: unsafe.Slice(unsafe.StringData(file_common_taggedfeatures_skeleton_proto_rawDesc), len(file_common_taggedfeatures_skeleton_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_common_taggedfeatures_skeleton_proto_goTypes,\n\t\tDependencyIndexes: file_common_taggedfeatures_skeleton_proto_depIdxs,\n\t\tMessageInfos:      file_common_taggedfeatures_skeleton_proto_msgTypes,\n\t}.Build()\n\tFile_common_taggedfeatures_skeleton_proto = out.File\n\tfile_common_taggedfeatures_skeleton_proto_goTypes = nil\n\tfile_common_taggedfeatures_skeleton_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "common/taggedfeatures/skeleton.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.common.taggedfeatures;\noption csharp_namespace = \"V2Ray.Core.Common.Taggedfeatures\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/common/taggedfeatures\";\noption java_package = \"com.v2ray.core.common.taggedfeatures\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\n\nmessage Config {\n  map<string, google.protobuf.Any> features = 1;\n}"
  },
  {
    "path": "common/taggedfeatures/taggedfeatures.go",
    "content": "package taggedfeatures\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/task/common.go",
    "content": "package task\n\nimport \"github.com/v2fly/v2ray-core/v5/common\"\n\n// Close returns a func() that closes v.\nfunc Close(v interface{}) func() error {\n\treturn func() error {\n\t\treturn common.Close(v)\n\t}\n}\n"
  },
  {
    "path": "common/task/periodic.go",
    "content": "package task\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\n// Periodic is a task that runs periodically.\ntype Periodic struct {\n\t// Interval of the task being run\n\tInterval time.Duration\n\t// Execute is the task function\n\tExecute func() error\n\n\taccess  sync.Mutex\n\ttimer   *time.Timer\n\trunning bool\n}\n\nfunc (t *Periodic) hasClosed() bool {\n\tt.access.Lock()\n\tdefer t.access.Unlock()\n\n\treturn !t.running\n}\n\nfunc (t *Periodic) checkedExecute() error {\n\tif t.hasClosed() {\n\t\treturn nil\n\t}\n\n\tif err := t.Execute(); err != nil {\n\t\tt.access.Lock()\n\t\tt.running = false\n\t\tt.access.Unlock()\n\t\treturn err\n\t}\n\n\tt.access.Lock()\n\tdefer t.access.Unlock()\n\n\tif !t.running {\n\t\treturn nil\n\t}\n\n\tt.timer = time.AfterFunc(t.Interval, func() {\n\t\tt.checkedExecute()\n\t})\n\n\treturn nil\n}\n\n// Start implements common.Runnable.\nfunc (t *Periodic) Start() error {\n\tt.access.Lock()\n\tif t.running {\n\t\tt.access.Unlock()\n\t\treturn nil\n\t}\n\tt.running = true\n\tt.access.Unlock()\n\n\tif err := t.checkedExecute(); err != nil {\n\t\tt.access.Lock()\n\t\tt.running = false\n\t\tt.access.Unlock()\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (t *Periodic) Close() error {\n\tt.access.Lock()\n\tdefer t.access.Unlock()\n\n\tt.running = false\n\tif t.timer != nil {\n\t\tt.timer.Stop()\n\t\tt.timer = nil\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "common/task/periodic_test.go",
    "content": "package task_test\n\nimport (\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\nfunc TestPeriodicTaskStop(t *testing.T) {\n\tvar value uint64\n\ttask := &Periodic{\n\t\tInterval: time.Second * 2,\n\t\tExecute: func() error {\n\t\t\tatomic.AddUint64(&value, 1)\n\t\t\treturn nil\n\t\t},\n\t}\n\tcommon.Must(task.Start())\n\ttime.Sleep(time.Second * 5)\n\tcommon.Must(task.Close())\n\tvalue1 := atomic.LoadUint64(&value)\n\tif value1 != 3 {\n\t\tt.Fatal(\"expected 3, but got \", value1)\n\t}\n\n\ttime.Sleep(time.Second * 4)\n\tvalue2 := atomic.LoadUint64(&value)\n\tif value2 != 3 {\n\t\tt.Fatal(\"expected 3, but got \", value2)\n\t}\n\n\tcommon.Must(task.Start())\n\ttime.Sleep(time.Second * 3)\n\tvalue3 := atomic.LoadUint64(&value)\n\tif value3 != 5 {\n\t\tt.Fatal(\"Expected 5, but \", value3)\n\t}\n\tcommon.Must(task.Close())\n}\n"
  },
  {
    "path": "common/task/task.go",
    "content": "package task\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/semaphore\"\n)\n\n// OnSuccess executes g() after f() returns nil.\nfunc OnSuccess(f func() error, g func() error) func() error {\n\treturn func() error {\n\t\tif err := f(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn g()\n\t}\n}\n\n// Run executes a list of tasks in parallel, returns the first error encountered or nil if all tasks pass.\nfunc Run(ctx context.Context, tasks ...func() error) error {\n\tn := len(tasks)\n\ts := semaphore.New(n)\n\tdone := make(chan error, 1)\n\n\tfor _, task := range tasks {\n\t\t<-s.Wait()\n\t\tgo func(f func() error) {\n\t\t\terr := f()\n\t\t\tif err == nil {\n\t\t\t\ts.Signal()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tselect {\n\t\t\tcase done <- err:\n\t\t\tdefault:\n\t\t\t}\n\t\t}(task)\n\t}\n\n\tfor i := 0; i < n; i++ {\n\t\tselect {\n\t\tcase err := <-done:\n\t\t\treturn err\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-s.Wait():\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "common/task/taskDerive/derive.go",
    "content": "package taskDerive\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "common/task/taskDerive/errors.generated.go",
    "content": "package taskDerive\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "common/task/taskDerive/tryAll.go",
    "content": "package taskDerive\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\nfunc RunTryAll(ctx context.Context, tasks ...func() error) []error {\n\terrors := make([]error, len(tasks))\n\twrappedTasks := make([]func() error, len(tasks))\n\tfor i, currentTask := range tasks {\n\t\tindex := i\n\t\twrappedTasks[i] = func() error {\n\t\t\terr := currentTask()\n\t\t\terrors[index] = err\n\t\t\tif err != nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn newError()\n\t\t}\n\t}\n\trunErr := task.Run(ctx, wrappedTasks...)\n\tif runErr != nil {\n\t\treturn nil\n\t}\n\treturn errors\n}\n"
  },
  {
    "path": "common/task/task_test.go",
    "content": "package task_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/task\"\n)\n\nfunc TestExecuteParallel(t *testing.T) {\n\terr := Run(context.Background(),\n\t\tfunc() error {\n\t\t\ttime.Sleep(time.Millisecond * 200)\n\t\t\treturn errors.New(\"test\")\n\t\t}, func() error {\n\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\treturn errors.New(\"test2\")\n\t\t})\n\n\tif r := cmp.Diff(err.Error(), \"test\"); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestExecuteParallelContextCancel(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\terr := Run(ctx, func() error {\n\t\ttime.Sleep(time.Millisecond * 2000)\n\t\treturn errors.New(\"test\")\n\t}, func() error {\n\t\ttime.Sleep(time.Millisecond * 5000)\n\t\treturn errors.New(\"test2\")\n\t}, func() error {\n\t\tcancel()\n\t\treturn nil\n\t})\n\n\terrStr := err.Error()\n\tif !strings.Contains(errStr, \"canceled\") {\n\t\tt.Error(\"expected error string to contain 'canceled', but actually not: \", errStr)\n\t}\n}\n\nfunc BenchmarkExecuteOne(b *testing.B) {\n\tnoop := func() error {\n\t\treturn nil\n\t}\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(Run(context.Background(), noop))\n\t}\n}\n\nfunc BenchmarkExecuteTwo(b *testing.B) {\n\tnoop := func() error {\n\t\treturn nil\n\t}\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(Run(context.Background(), noop, noop))\n\t}\n}\n"
  },
  {
    "path": "common/type.go",
    "content": "package common\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/registry\"\n)\n\n// ConfigCreator is a function to create an object by a config.\ntype ConfigCreator func(ctx context.Context, config interface{}) (interface{}, error)\n\nvar typeCreatorRegistry = make(map[reflect.Type]ConfigCreator)\n\n// RegisterConfig registers a global config creator. The config can be nil but must have a type.\nfunc RegisterConfig(config interface{}, configCreator ConfigCreator) error {\n\tconfigType := reflect.TypeOf(config)\n\tif _, found := typeCreatorRegistry[configType]; found {\n\t\treturn newError(configType.Name() + \" is already registered\").AtError()\n\t}\n\ttypeCreatorRegistry[configType] = configCreator\n\n\tregistry.RegisterImplementation(config, nil)\n\treturn nil\n}\n\n// CreateObject creates an object by its config. The config type must be registered through RegisterConfig().\nfunc CreateObject(ctx context.Context, config interface{}) (interface{}, error) {\n\tconfigType := reflect.TypeOf(config)\n\tcreator, found := typeCreatorRegistry[configType]\n\tif !found {\n\t\treturn nil, newError(configType.String() + \" is not registered\").AtError()\n\t}\n\treturn creator(ctx, config)\n}\n"
  },
  {
    "path": "common/type_test.go",
    "content": "package common_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype TConfig struct {\n\tvalue int\n}\n\ntype YConfig struct {\n\tvalue string\n}\n\nfunc TestObjectCreation(t *testing.T) {\n\tf := func(ctx context.Context, t interface{}) (interface{}, error) {\n\t\treturn func() int {\n\t\t\treturn t.(*TConfig).value\n\t\t}, nil\n\t}\n\n\tMust(RegisterConfig((*TConfig)(nil), f))\n\terr := RegisterConfig((*TConfig)(nil), f)\n\tif err == nil {\n\t\tt.Error(\"expect non-nil error, but got nil\")\n\t}\n\n\tg, err := CreateObject(context.Background(), &TConfig{value: 2})\n\tMust(err)\n\tif v := g.(func() int)(); v != 2 {\n\t\tt.Error(\"expect return value 2, but got \", v)\n\t}\n\n\t_, err = CreateObject(context.Background(), &YConfig{value: \"T\"})\n\tif err == nil {\n\t\tt.Error(\"expect non-nil error, but got nil\")\n\t}\n}\n"
  },
  {
    "path": "common/units/bytesize.go",
    "content": "package units\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nvar (\n\terrInvalidSize = errors.New(\"invalid size\")\n\terrInvalidUnit = errors.New(\"invalid or unsupported unit\")\n)\n\n// ByteSize is the size of bytes\ntype ByteSize uint64\n\nconst (\n\t_ = iota\n\t// KB = 1KB\n\tKB ByteSize = 1 << (10 * iota)\n\t// MB = 1MB\n\tMB\n\t// GB = 1GB\n\tGB\n\t// TB = 1TB\n\tTB\n\t// PB = 1PB\n\tPB\n\t// EB = 1EB\n\tEB\n)\n\nfunc (b ByteSize) String() string {\n\tunit := \"\"\n\tvalue := float64(0)\n\tswitch {\n\tcase b == 0:\n\t\treturn \"0\"\n\tcase b < KB:\n\t\tunit = \"B\"\n\t\tvalue = float64(b)\n\tcase b < MB:\n\t\tunit = \"KB\"\n\t\tvalue = float64(b) / float64(KB)\n\tcase b < GB:\n\t\tunit = \"MB\"\n\t\tvalue = float64(b) / float64(MB)\n\tcase b < TB:\n\t\tunit = \"GB\"\n\t\tvalue = float64(b) / float64(GB)\n\tcase b < PB:\n\t\tunit = \"TB\"\n\t\tvalue = float64(b) / float64(TB)\n\tcase b < EB:\n\t\tunit = \"PB\"\n\t\tvalue = float64(b) / float64(PB)\n\tdefault:\n\t\tunit = \"EB\"\n\t\tvalue = float64(b) / float64(EB)\n\t}\n\tresult := strconv.FormatFloat(value, 'f', 2, 64)\n\tresult = strings.TrimSuffix(result, \".0\")\n\treturn result + unit\n}\n\n// Parse parses ByteSize from string\nfunc (b *ByteSize) Parse(s string) error {\n\ts = strings.TrimSpace(s)\n\ts = strings.ToUpper(s)\n\ti := strings.IndexFunc(s, unicode.IsLetter)\n\tif i == -1 {\n\t\treturn errInvalidUnit\n\t}\n\n\tbytesString, multiple := s[:i], s[i:]\n\tbytes, err := strconv.ParseFloat(bytesString, 64)\n\tif err != nil || bytes <= 0 {\n\t\treturn errInvalidSize\n\t}\n\tswitch multiple {\n\tcase \"B\":\n\t\t*b = ByteSize(bytes)\n\tcase \"K\", \"KB\", \"KIB\":\n\t\t*b = ByteSize(bytes * float64(KB))\n\tcase \"M\", \"MB\", \"MIB\":\n\t\t*b = ByteSize(bytes * float64(MB))\n\tcase \"G\", \"GB\", \"GIB\":\n\t\t*b = ByteSize(bytes * float64(GB))\n\tcase \"T\", \"TB\", \"TIB\":\n\t\t*b = ByteSize(bytes * float64(TB))\n\tcase \"P\", \"PB\", \"PIB\":\n\t\t*b = ByteSize(bytes * float64(PB))\n\tcase \"E\", \"EB\", \"EIB\":\n\t\t*b = ByteSize(bytes * float64(EB))\n\tdefault:\n\t\treturn errInvalidUnit\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "common/units/bytesize_test.go",
    "content": "package units_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/units\"\n)\n\nfunc TestByteSizes(t *testing.T) {\n\tsize := units.ByteSize(0)\n\tassertSizeString(t, size, \"0\")\n\tsize++\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00B\"),\n\t\tsize,\n\t)\n\tsize <<= 10\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00KB\"),\n\t\tsize,\n\t)\n\tsize <<= 10\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00MB\"),\n\t\tsize,\n\t)\n\tsize <<= 10\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00GB\"),\n\t\tsize,\n\t)\n\tsize <<= 10\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00TB\"),\n\t\tsize,\n\t)\n\tsize <<= 10\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00PB\"),\n\t\tsize,\n\t)\n\tsize <<= 10\n\tassertSizeValue(t,\n\t\tassertSizeString(t, size, \"1.00EB\"),\n\t\tsize,\n\t)\n}\n\nfunc assertSizeValue(t *testing.T, size string, expected units.ByteSize) {\n\tactual := units.ByteSize(0)\n\terr := actual.Parse(size)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif actual != expected {\n\t\tt.Errorf(\"expect %s, but got %s\", expected, actual)\n\t}\n}\n\nfunc assertSizeString(t *testing.T, size units.ByteSize, expected string) string {\n\tactual := size.String()\n\tif actual != expected {\n\t\tt.Errorf(\"expect %s, but got %s\", expected, actual)\n\t}\n\treturn expected\n}\n"
  },
  {
    "path": "common/uuid/uuid.go",
    "content": "package uuid\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n)\n\nvar byteGroups = []int{8, 4, 4, 4, 12}\n\ntype UUID [16]byte\n\n// String returns the string representation of this UUID.\nfunc (u *UUID) String() string {\n\tbytes := u.Bytes()\n\tresult := hex.EncodeToString(bytes[0 : byteGroups[0]/2])\n\tstart := byteGroups[0] / 2\n\tfor i := 1; i < len(byteGroups); i++ {\n\t\tnBytes := byteGroups[i] / 2\n\t\tresult += \"-\"\n\t\tresult += hex.EncodeToString(bytes[start : start+nBytes])\n\t\tstart += nBytes\n\t}\n\treturn result\n}\n\n// Bytes returns the bytes representation of this UUID.\nfunc (u *UUID) Bytes() []byte {\n\treturn u[:]\n}\n\n// Equals returns true if this UUID equals another UUID by value.\nfunc (u *UUID) Equals(another *UUID) bool {\n\tif u == nil && another == nil {\n\t\treturn true\n\t}\n\tif u == nil || another == nil {\n\t\treturn false\n\t}\n\treturn bytes.Equal(u.Bytes(), another.Bytes())\n}\n\n// New creates a UUID with random value.\nfunc New() UUID {\n\tvar uuid UUID\n\tcommon.Must2(rand.Read(uuid.Bytes()))\n\treturn uuid\n}\n\n// ParseBytes converts a UUID in byte form to object.\nfunc ParseBytes(b []byte) (UUID, error) {\n\tvar uuid UUID\n\tif len(b) != 16 {\n\t\treturn uuid, errors.New(\"invalid UUID: \", b)\n\t}\n\tcopy(uuid[:], b)\n\treturn uuid, nil\n}\n\n// ParseString converts a UUID in string form to object.\nfunc ParseString(str string) (UUID, error) {\n\tvar uuid UUID\n\n\ttext := []byte(str)\n\tif len(text) < 32 {\n\t\treturn uuid, errors.New(\"invalid UUID: \", str)\n\t}\n\n\tb := uuid.Bytes()\n\n\tfor _, byteGroup := range byteGroups {\n\t\tif text[0] == '-' {\n\t\t\ttext = text[1:]\n\t\t}\n\n\t\tif _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup]); err != nil {\n\t\t\treturn uuid, err\n\t\t}\n\n\t\ttext = text[byteGroup:]\n\t\tb = b[byteGroup/2:]\n\t}\n\n\treturn uuid, nil\n}\n"
  },
  {
    "path": "common/uuid/uuid_test.go",
    "content": "package uuid_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\nfunc TestParseBytes(t *testing.T) {\n\tstr := \"2418d087-648d-4990-86e8-19dca1d006d3\"\n\tbytes := []byte{0x24, 0x18, 0xd0, 0x87, 0x64, 0x8d, 0x49, 0x90, 0x86, 0xe8, 0x19, 0xdc, 0xa1, 0xd0, 0x06, 0xd3}\n\n\tuuid, err := ParseBytes(bytes)\n\tcommon.Must(err)\n\tif diff := cmp.Diff(uuid.String(), str); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n\n\t_, err = ParseBytes([]byte{1, 3, 2, 4})\n\tif err == nil {\n\t\tt.Fatal(\"Expect error but nil\")\n\t}\n}\n\nfunc TestParseString(t *testing.T) {\n\tstr := \"2418d087-648d-4990-86e8-19dca1d006d3\"\n\texpectedBytes := []byte{0x24, 0x18, 0xd0, 0x87, 0x64, 0x8d, 0x49, 0x90, 0x86, 0xe8, 0x19, 0xdc, 0xa1, 0xd0, 0x06, 0xd3}\n\n\tuuid, err := ParseString(str)\n\tcommon.Must(err)\n\tif r := cmp.Diff(expectedBytes, uuid.Bytes()); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n\n\t_, err = ParseString(\"2418d087\")\n\tif err == nil {\n\t\tt.Fatal(\"Expect error but nil\")\n\t}\n\n\t_, err = ParseString(\"2418d087-648k-4990-86e8-19dca1d006d3\")\n\tif err == nil {\n\t\tt.Fatal(\"Expect error but nil\")\n\t}\n}\n\nfunc TestNewUUID(t *testing.T) {\n\tuuid := New()\n\tuuid2, err := ParseString(uuid.String())\n\n\tcommon.Must(err)\n\tif uuid.String() != uuid2.String() {\n\t\tt.Error(\"uuid string: \", uuid.String(), \" != \", uuid2.String())\n\t}\n\tif r := cmp.Diff(uuid.Bytes(), uuid2.Bytes()); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestRandom(t *testing.T) {\n\tuuid := New()\n\tuuid2 := New()\n\n\tif uuid.String() == uuid2.String() {\n\t\tt.Error(\"duplicated uuid\")\n\t}\n}\n\nfunc TestEquals(t *testing.T) {\n\tvar uuid *UUID\n\tvar uuid2 *UUID\n\tif !uuid.Equals(uuid2) {\n\t\tt.Error(\"empty uuid should equal\")\n\t}\n\n\tuuid3 := New()\n\tif uuid.Equals(&uuid3) {\n\t\tt.Error(\"nil uuid equals non-nil uuid\")\n\t}\n}\n"
  },
  {
    "path": "config.go",
    "content": "package core\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n)\n\nconst (\n\t// FormatAuto represents all available formats by auto selecting\n\tFormatAuto = \"auto\"\n\t// FormatJSON represents json format\n\tFormatJSON = \"json\"\n\t// FormatTOML represents toml format\n\tFormatTOML = \"toml\"\n\t// FormatYAML represents yaml format\n\tFormatYAML = \"yaml\"\n\t// FormatProtobuf represents protobuf format\n\tFormatProtobuf = \"protobuf\"\n\t// FormatProtobufShort is the short of FormatProtobuf\n\tFormatProtobufShort = \"pb\"\n)\n\n// ConfigFormat is a configurable format of V2Ray config file.\ntype ConfigFormat struct {\n\tName      []string\n\tExtension []string\n\tLoader    ConfigLoader\n}\n\n// ConfigLoader is a utility to load V2Ray config from external source.\ntype ConfigLoader func(input interface{}) (*Config, error)\n\nvar (\n\tconfigLoaders      = make([]*ConfigFormat, 0)\n\tconfigLoaderByName = make(map[string]*ConfigFormat)\n\tconfigLoaderByExt  = make(map[string]*ConfigFormat)\n)\n\n// RegisterConfigLoader add a new ConfigLoader.\nfunc RegisterConfigLoader(format *ConfigFormat) error {\n\tfor _, name := range format.Name {\n\t\tif _, found := configLoaderByName[name]; found {\n\t\t\treturn newError(name, \" already registered.\")\n\t\t}\n\t\tconfigLoaderByName[name] = format\n\t}\n\n\tfor _, ext := range format.Extension {\n\t\tlext := strings.ToLower(ext)\n\t\tif f, found := configLoaderByExt[lext]; found {\n\t\t\treturn newError(ext, \" already registered to \", f.Name)\n\t\t}\n\t\tconfigLoaderByExt[lext] = format\n\t}\n\tconfigLoaders = append(configLoaders, format)\n\treturn nil\n}\n\nfunc getExtension(filename string) string {\n\text := filepath.Ext(filename)\n\treturn strings.ToLower(ext)\n}\n\n// GetLoaderExtensions get config loader extensions.\nfunc GetLoaderExtensions(formatName string) ([]string, error) {\n\tif formatName == FormatAuto {\n\t\treturn GetAllExtensions(), nil\n\t}\n\tif f, found := configLoaderByName[formatName]; found {\n\t\treturn f.Extension, nil\n\t}\n\treturn nil, newError(\"config loader not found: \", formatName).AtWarning()\n}\n\n// GetAllExtensions get all extensions supported\nfunc GetAllExtensions() []string {\n\textensions := make([]string, 0)\n\tfor _, f := range configLoaderByName {\n\t\textensions = append(extensions, f.Extension...)\n\t}\n\treturn extensions\n}\n\n// LoadConfig loads multiple config with given format from given source.\n// input accepts:\n// * string of a single filename/url(s) to open to read\n// * []string slice of multiple filename/url(s) to open to read\n// * io.Reader that reads a config content (the original way)\nfunc LoadConfig(formatName string, input interface{}) (*Config, error) {\n\tcnt := getInputCount(input)\n\tif cnt == 0 {\n\t\tlog.Println(\"Using config from STDIN\")\n\t\tinput = os.Stdin\n\t\tcnt = 1\n\t}\n\tif formatName == FormatAuto && cnt == 1 {\n\t\t// This ensures only to call auto loader for multiple files,\n\t\t// so that it can only care about merging scenarios\n\t\treturn loadSingleConfigAutoFormat(input)\n\t}\n\t// if input is a slice with single element, extract it\n\t// so that unmergeable loaders don't need to deal with\n\t// slices\n\ts := reflect.Indirect(reflect.ValueOf(input))\n\tk := s.Kind()\n\tif (k == reflect.Slice || k == reflect.Array) && s.Len() == 1 {\n\t\tvalue := reflect.Indirect(s.Index(0))\n\t\tif value.Kind() == reflect.String {\n\t\t\t// string type alias\n\t\t\tinput = fmt.Sprint(value.Interface())\n\t\t} else {\n\t\t\tinput = value.Interface()\n\t\t}\n\t}\n\tf, found := configLoaderByName[formatName]\n\tif !found {\n\t\treturn nil, newError(\"config loader not found: \", formatName).AtWarning()\n\t}\n\treturn f.Loader(input)\n}\n\n// loadSingleConfigAutoFormat loads a single config with from given source.\n// input accepts:\n// * string of a single filename/url(s) to open to read\n// * io.Reader that reads a config content (the original way)\nfunc loadSingleConfigAutoFormat(input interface{}) (*Config, error) {\n\tswitch v := input.(type) {\n\tcase cmdarg.Arg:\n\t\treturn loadSingleConfigAutoFormatFromFile(v.String())\n\tcase string:\n\t\treturn loadSingleConfigByTryingAllLoaders(v)\n\tcase io.Reader:\n\t\tdata, err := buf.ReadAllToBytes(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn loadSingleConfigByTryingAllLoaders(data)\n\tdefault:\n\t\treturn loadSingleConfigByTryingAllLoaders(v)\n\t}\n}\n\nfunc loadSingleConfigAutoFormatFromFile(file string) (*Config, error) {\n\textension := getExtension(file)\n\tif extension != \"\" {\n\t\tlowerName := strings.ToLower(extension)\n\t\tif f, found := configLoaderByExt[lowerName]; found {\n\t\t\treturn f.Loader(file)\n\t\t}\n\t\treturn nil, newError(\"config loader not found for: \", extension).AtWarning()\n\t}\n\n\treturn loadSingleConfigByTryingAllLoaders(file)\n}\n\nfunc loadSingleConfigByTryingAllLoaders(input interface{}) (*Config, error) {\n\tvar errorReasons strings.Builder\n\n\tfor _, f := range configLoaders {\n\t\tif f.Name[0] == FormatAuto {\n\t\t\tcontinue\n\t\t}\n\t\tc, err := f.Loader(input)\n\t\tif err == nil {\n\t\t\treturn c, nil\n\t\t}\n\t\terrorReasons.WriteString(fmt.Sprintf(\"unable to parse as %v:%v;\", f.Name[0], err.Error()))\n\t}\n\n\treturn nil, newError(\"tried all loaders but failed when attempting to parse: \", input, \";\", errorReasons.String()).AtWarning()\n}\n\nfunc getInputCount(input interface{}) int {\n\ts := reflect.Indirect(reflect.ValueOf(input))\n\tk := s.Kind()\n\tif k == reflect.Slice || k == reflect.Array {\n\t\treturn s.Len()\n\t}\n\treturn 1\n}\n\nfunc loadProtobufConfig(data []byte) (*Config, error) {\n\tconfig := new(Config)\n\tif err := proto.Unmarshal(data, config); err != nil {\n\t\treturn nil, err\n\t}\n\treturn config, nil\n}\n\nfunc init() {\n\tcommon.Must(RegisterConfigLoader(&ConfigFormat{\n\t\tName:      []string{FormatProtobuf, FormatProtobufShort},\n\t\tExtension: []string{\".pb\"},\n\t\tLoader: func(input interface{}) (*Config, error) {\n\t\t\tswitch v := input.(type) {\n\t\t\tcase string:\n\t\t\t\tr, err := cmdarg.LoadArg(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\tdata, err := buf.ReadAllToBytes(r)\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 loadProtobufConfig(data)\n\t\t\tcase io.Reader:\n\t\t\t\tdata, err := buf.ReadAllToBytes(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\treturn loadProtobufConfig(data)\n\t\t\tdefault:\n\t\t\t\treturn nil, newError(\"unknown type\")\n\t\t\t}\n\t\t},\n\t}))\n}\n"
  },
  {
    "path": "config.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.10\n// \tprotoc        v5.28.1\n// source: config.proto\n\npackage core\n\nimport (\n\ttransport \"github.com/v2fly/v2ray-core/v5/transport\"\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\tunsafe \"unsafe\"\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// Config is the master config of V2Ray. V2Ray takes this config as input and\n// functions accordingly.\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Inbound handler configurations. Must have at least one item.\n\tInbound []*InboundHandlerConfig `protobuf:\"bytes,1,rep,name=inbound,proto3\" json:\"inbound,omitempty\"`\n\t// Outbound handler configurations. Must have at least one item. The first\n\t// item is used as default for routing.\n\tOutbound []*OutboundHandlerConfig `protobuf:\"bytes,2,rep,name=outbound,proto3\" json:\"outbound,omitempty\"`\n\t// App is for configurations of all features in V2Ray. A feature must\n\t// implement the Feature interface, and its config type must be registered\n\t// through common.RegisterConfig.\n\tApp []*anypb.Any `protobuf:\"bytes,4,rep,name=app,proto3\" json:\"app,omitempty\"`\n\t// Transport settings.\n\t// Deprecated. Each inbound and outbound should choose their own transport\n\t// config. Date to remove: 2020-01-13\n\t//\n\t// Deprecated: Marked as deprecated in config.proto.\n\tTransport *transport.Config `protobuf:\"bytes,5,opt,name=transport,proto3\" json:\"transport,omitempty\"`\n\t// Configuration for extensions. The config may not work if corresponding\n\t// extension is not loaded into V2Ray. V2Ray will ignore such config during\n\t// initialization.\n\tExtension     []*anypb.Any `protobuf:\"bytes,6,rep,name=extension,proto3\" json:\"extension,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetInbound() []*InboundHandlerConfig {\n\tif x != nil {\n\t\treturn x.Inbound\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetOutbound() []*OutboundHandlerConfig {\n\tif x != nil {\n\t\treturn x.Outbound\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetApp() []*anypb.Any {\n\tif x != nil {\n\t\treturn x.App\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in config.proto.\nfunc (x *Config) GetTransport() *transport.Config {\n\tif x != nil {\n\t\treturn x.Transport\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetExtension() []*anypb.Any {\n\tif x != nil {\n\t\treturn x.Extension\n\t}\n\treturn nil\n}\n\n// InboundHandlerConfig is the configuration for inbound handler.\ntype InboundHandlerConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Tag of the inbound handler. The tag must be unique among all inbound\n\t// handlers\n\tTag string `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\t// Settings for how this inbound proxy is handled.\n\tReceiverSettings *anypb.Any `protobuf:\"bytes,2,opt,name=receiver_settings,json=receiverSettings,proto3\" json:\"receiver_settings,omitempty\"`\n\t// Settings for inbound proxy. Must be one of the inbound proxies.\n\tProxySettings *anypb.Any `protobuf:\"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3\" json:\"proxy_settings,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *InboundHandlerConfig) Reset() {\n\t*x = InboundHandlerConfig{}\n\tmi := &file_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *InboundHandlerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*InboundHandlerConfig) ProtoMessage() {}\n\nfunc (x *InboundHandlerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_config_proto_msgTypes[1]\n\tif 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 InboundHandlerConfig.ProtoReflect.Descriptor instead.\nfunc (*InboundHandlerConfig) Descriptor() ([]byte, []int) {\n\treturn file_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *InboundHandlerConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *InboundHandlerConfig) GetReceiverSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.ReceiverSettings\n\t}\n\treturn nil\n}\n\nfunc (x *InboundHandlerConfig) GetProxySettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.ProxySettings\n\t}\n\treturn nil\n}\n\n// OutboundHandlerConfig is the configuration for outbound handler.\ntype OutboundHandlerConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Tag of this outbound handler.\n\tTag string `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\t// Settings for how to dial connection for this outbound handler.\n\tSenderSettings *anypb.Any `protobuf:\"bytes,2,opt,name=sender_settings,json=senderSettings,proto3\" json:\"sender_settings,omitempty\"`\n\t// Settings for this outbound proxy. Must be one of the outbound proxies.\n\tProxySettings *anypb.Any `protobuf:\"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3\" json:\"proxy_settings,omitempty\"`\n\t// If not zero, this outbound will be expired in seconds. Not used for now.\n\tExpire int64 `protobuf:\"varint,4,opt,name=expire,proto3\" json:\"expire,omitempty\"`\n\t// Comment of this outbound handler. Not used for now.\n\tComment       string `protobuf:\"bytes,5,opt,name=comment,proto3\" json:\"comment,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *OutboundHandlerConfig) Reset() {\n\t*x = OutboundHandlerConfig{}\n\tmi := &file_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *OutboundHandlerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OutboundHandlerConfig) ProtoMessage() {}\n\nfunc (x *OutboundHandlerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_config_proto_msgTypes[2]\n\tif 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 OutboundHandlerConfig.ProtoReflect.Descriptor instead.\nfunc (*OutboundHandlerConfig) Descriptor() ([]byte, []int) {\n\treturn file_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *OutboundHandlerConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *OutboundHandlerConfig) GetSenderSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.SenderSettings\n\t}\n\treturn nil\n}\n\nfunc (x *OutboundHandlerConfig) GetProxySettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.ProxySettings\n\t}\n\treturn nil\n}\n\nfunc (x *OutboundHandlerConfig) GetExpire() int64 {\n\tif x != nil {\n\t\treturn x.Expire\n\t}\n\treturn 0\n}\n\nfunc (x *OutboundHandlerConfig) GetComment() string {\n\tif x != nil {\n\t\treturn x.Comment\n\t}\n\treturn \"\"\n}\n\nvar File_config_proto protoreflect.FileDescriptor\n\nconst file_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\fconfig.proto\\x12\\n\" +\n\t\"v2ray.core\\x1a\\x19google/protobuf/any.proto\\x1a\\x16transport/config.proto\\\"\\xa5\\x02\\n\" +\n\t\"\\x06Config\\x12:\\n\" +\n\t\"\\ainbound\\x18\\x01 \\x03(\\v2 .v2ray.core.InboundHandlerConfigR\\ainbound\\x12=\\n\" +\n\t\"\\boutbound\\x18\\x02 \\x03(\\v2!.v2ray.core.OutboundHandlerConfigR\\boutbound\\x12&\\n\" +\n\t\"\\x03app\\x18\\x04 \\x03(\\v2\\x14.google.protobuf.AnyR\\x03app\\x12>\\n\" +\n\t\"\\ttransport\\x18\\x05 \\x01(\\v2\\x1c.v2ray.core.transport.ConfigB\\x02\\x18\\x01R\\ttransport\\x122\\n\" +\n\t\"\\textension\\x18\\x06 \\x03(\\v2\\x14.google.protobuf.AnyR\\textensionJ\\x04\\b\\x03\\x10\\x04\\\"\\xa8\\x01\\n\" +\n\t\"\\x14InboundHandlerConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12A\\n\" +\n\t\"\\x11receiver_settings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x10receiverSettings\\x12;\\n\" +\n\t\"\\x0eproxy_settings\\x18\\x03 \\x01(\\v2\\x14.google.protobuf.AnyR\\rproxySettings\\\"\\xd7\\x01\\n\" +\n\t\"\\x15OutboundHandlerConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x12=\\n\" +\n\t\"\\x0fsender_settings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x0esenderSettings\\x12;\\n\" +\n\t\"\\x0eproxy_settings\\x18\\x03 \\x01(\\v2\\x14.google.protobuf.AnyR\\rproxySettings\\x12\\x16\\n\" +\n\t\"\\x06expire\\x18\\x04 \\x01(\\x03R\\x06expire\\x12\\x18\\n\" +\n\t\"\\acomment\\x18\\x05 \\x01(\\tR\\acommentBD\\n\" +\n\t\"\\x0ecom.v2ray.coreP\\x01Z#github.com/v2fly/v2ray-core/v5;core\\xaa\\x02\\n\" +\n\t\"V2Ray.Coreb\\x06proto3\"\n\nvar (\n\tfile_config_proto_rawDescOnce sync.Once\n\tfile_config_proto_rawDescData []byte\n)\n\nfunc file_config_proto_rawDescGZIP() []byte {\n\tfile_config_proto_rawDescOnce.Do(func() {\n\t\tfile_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_config_proto_rawDesc), len(file_config_proto_rawDesc)))\n\t})\n\treturn file_config_proto_rawDescData\n}\n\nvar file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_config_proto_goTypes = []any{\n\t(*Config)(nil),                // 0: v2ray.core.Config\n\t(*InboundHandlerConfig)(nil),  // 1: v2ray.core.InboundHandlerConfig\n\t(*OutboundHandlerConfig)(nil), // 2: v2ray.core.OutboundHandlerConfig\n\t(*anypb.Any)(nil),             // 3: google.protobuf.Any\n\t(*transport.Config)(nil),      // 4: v2ray.core.transport.Config\n}\nvar file_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.Config.inbound:type_name -> v2ray.core.InboundHandlerConfig\n\t2, // 1: v2ray.core.Config.outbound:type_name -> v2ray.core.OutboundHandlerConfig\n\t3, // 2: v2ray.core.Config.app:type_name -> google.protobuf.Any\n\t4, // 3: v2ray.core.Config.transport:type_name -> v2ray.core.transport.Config\n\t3, // 4: v2ray.core.Config.extension:type_name -> google.protobuf.Any\n\t3, // 5: v2ray.core.InboundHandlerConfig.receiver_settings:type_name -> google.protobuf.Any\n\t3, // 6: v2ray.core.InboundHandlerConfig.proxy_settings:type_name -> google.protobuf.Any\n\t3, // 7: v2ray.core.OutboundHandlerConfig.sender_settings:type_name -> google.protobuf.Any\n\t3, // 8: v2ray.core.OutboundHandlerConfig.proxy_settings:type_name -> google.protobuf.Any\n\t9, // [9:9] is the sub-list for method output_type\n\t9, // [9:9] is the sub-list for method input_type\n\t9, // [9:9] is the sub-list for extension type_name\n\t9, // [9:9] is the sub-list for extension extendee\n\t0, // [0:9] is the sub-list for field type_name\n}\n\nfunc init() { file_config_proto_init() }\nfunc file_config_proto_init() {\n\tif File_config_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: unsafe.Slice(unsafe.StringData(file_config_proto_rawDesc), len(file_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_config_proto_goTypes,\n\t\tDependencyIndexes: file_config_proto_depIdxs,\n\t\tMessageInfos:      file_config_proto_msgTypes,\n\t}.Build()\n\tFile_config_proto = out.File\n\tfile_config_proto_goTypes = nil\n\tfile_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core;\noption csharp_namespace = \"V2Ray.Core\";\noption go_package = \"github.com/v2fly/v2ray-core/v5;core\";\noption java_package = \"com.v2ray.core\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\nimport \"transport/config.proto\";\n\n// Config is the master config of V2Ray. V2Ray takes this config as input and\n// functions accordingly.\nmessage Config {\n  // Inbound handler configurations. Must have at least one item.\n  repeated InboundHandlerConfig inbound = 1;\n\n  // Outbound handler configurations. Must have at least one item. The first\n  // item is used as default for routing.\n  repeated OutboundHandlerConfig outbound = 2;\n\n  reserved 3;\n\n  // App is for configurations of all features in V2Ray. A feature must\n  // implement the Feature interface, and its config type must be registered\n  // through common.RegisterConfig.\n  repeated google.protobuf.Any app = 4;\n\n  // Transport settings.\n  // Deprecated. Each inbound and outbound should choose their own transport\n  // config. Date to remove: 2020-01-13\n  v2ray.core.transport.Config transport = 5 [deprecated = true];\n\n  // Configuration for extensions. The config may not work if corresponding\n  // extension is not loaded into V2Ray. V2Ray will ignore such config during\n  // initialization.\n  repeated google.protobuf.Any extension = 6;\n}\n\n// InboundHandlerConfig is the configuration for inbound handler.\nmessage InboundHandlerConfig {\n  // Tag of the inbound handler. The tag must be unique among all inbound\n  // handlers\n  string tag = 1;\n  // Settings for how this inbound proxy is handled.\n  google.protobuf.Any receiver_settings = 2;\n  // Settings for inbound proxy. Must be one of the inbound proxies.\n  google.protobuf.Any proxy_settings = 3;\n}\n\n// OutboundHandlerConfig is the configuration for outbound handler.\nmessage OutboundHandlerConfig {\n  // Tag of this outbound handler.\n  string tag = 1;\n  // Settings for how to dial connection for this outbound handler.\n  google.protobuf.Any sender_settings = 2;\n  // Settings for this outbound proxy. Must be one of the outbound proxies.\n  google.protobuf.Any proxy_settings = 3;\n  // If not zero, this outbound will be expired in seconds. Not used for now.\n  int64 expire = 4;\n  // Comment of this outbound handler. Not used for now.\n  string comment = 5;\n}\n"
  },
  {
    "path": "context.go",
    "content": "package core\n\nimport (\n\t\"context\"\n)\n\n// V2rayKey is the key type of Instance in Context, exported for test.\ntype v2rayKeyType int\n\nconst v2rayKey v2rayKeyType = 1\n\n// FromContext returns an Instance from the given context, or nil if the context doesn't contain one.\nfunc FromContext(ctx context.Context) *Instance {\n\tif s, ok := ctx.Value(v2rayKey).(*Instance); ok {\n\t\treturn s\n\t}\n\treturn nil\n}\n\n// MustFromContext returns an Instance from the given context, or panics if not present.\nfunc MustFromContext(ctx context.Context) *Instance {\n\tv := FromContext(ctx)\n\tif v == nil {\n\t\tpanic(\"V is not in context.\")\n\t}\n\treturn v\n}\n\n/*\n\ttoContext returns ctx from the given context, or creates an Instance if the context doesn't find that.\n\nIt is unsupported to use this function to create a context that is suitable to invoke V2Ray's internal component\nin third party code, you shouldn't use //go:linkname to alias of this function into your own package and\nuse this function in your third party code.\n\nFor third party code, usage enabled by creating a context to interact with V2Ray's internal component is unsupported,\nand may break at any time.\n*/\nfunc toContext(ctx context.Context, v *Instance) context.Context {\n\tif FromContext(ctx) != v {\n\t\tctx = context.WithValue(ctx, v2rayKey, v)\n\t}\n\treturn ctx\n}\n\n/*\nToBackgroundDetachedContext create a detached context from another context\nInternal API\n*/\nfunc ToBackgroundDetachedContext(ctx context.Context) context.Context {\n\treturn &temporaryValueDelegationFix{context.Background(), ctx}\n}\n\ntype temporaryValueDelegationFix struct {\n\tcontext.Context\n\tvalue context.Context\n}\n\nfunc (t *temporaryValueDelegationFix) Value(key interface{}) interface{} {\n\treturn t.value.Value(key)\n}\n"
  },
  {
    "path": "context_test.go",
    "content": "package core_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t_ \"unsafe\"\n\n\t. \"github.com/v2fly/v2ray-core/v5\"\n)\n\nfunc TestFromContextPanic(t *testing.T) {\n\tdefer func() {\n\t\tr := recover()\n\t\tif r == nil {\n\t\t\tt.Error(\"expect panic, but nil\")\n\t\t}\n\t}()\n\n\tMustFromContext(context.Background())\n}\n"
  },
  {
    "path": "core.go",
    "content": "// Package core provides an entry point to use V2Ray core functionalities.\n//\n// V2Ray makes it possible to accept incoming network connections with certain\n// protocol, process the data, and send them through another connection with\n// the same or a difference protocol on demand.\n//\n// It may be configured to work with multiple protocols at the same time, and\n// uses the internal router to tunnel through different inbound and outbound\n// connections.\npackage core\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"runtime\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nvar (\n\tversion  = \"5.47.0\"\n\tbuild    = \"Custom\"\n\tcodename = \"V2Fly, a community-driven edition of V2Ray.\"\n\tintro    = \"A unified platform for anti-censorship.\"\n)\n\n// Version returns V2Ray's version as a string, in the form of \"x.y.z\" where x, y and z are numbers.\n// \".z\" part may be omitted in regular releases.\nfunc Version() string {\n\treturn version\n}\n\n// VersionStatement returns a list of strings representing the full version info.\nfunc VersionStatement() []string {\n\treturn []string{\n\t\tserial.Concat(\"V2Ray \", Version(), \" (\", codename, \") \", build, \" (\", runtime.Version(), \" \", runtime.GOOS, \"/\", runtime.GOARCH, \")\"),\n\t\tintro,\n\t}\n}\n\n/*\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::c:::::::::::::::::::::::ccc:::cccc::::::c:::::cccc::::cc::::::::::::::::::::::::ccccccc::cccccccccc::cc:::;:::::::::::::::::::::::::::ccc:::cccc:ccc::::::c:::::::::::::::::::::::::::cccc:cccccccccccccccccccccc:;;::::::::::::::::::c::::ccc::::::ccc:::ccc::cccccc::::cc:cc:::ccccccccccccccccccccccccccccccccccccccc\n:::;::::::::::::::::::::::::::::::::::::::::::::::cc:::::::::::::::::::::::::::::::::::::ccc::cc:::::c:::::::::::ccc::ccc:::::ccc::::::cc:::::cccc:::::::::::::::::::::cccccccccccccccccccccccccc:::::::::::::::::::::::::cc::ccc::::::::::::::c::c::::::::::::c::::::::c::::::cccccccccccccccccccccccccc:;:::::::::::::::ccc::cccccccc::c:cccc::cc:::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::cc::::::::cc::::::::::::ccccc:::::ccccccccc::cccc::ccccccc:::c::::::::c:c:::::cccccccccccccccccccccccccc::::::::::::::::::::::::cc:::::ccc:::c::::::::::::::::c::::::::::::::::::::::ccccccccccccccccccccccccccc:::::::::::::::::::::cccccc:ccccc::ccccccccc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::;;::::::::::::::::::::::::::::::::::::::::::::::::::::::::c:::::::::::::::::::::cc::::::::::::::::c:::cc::::c::::::::cccccc::::cccccccccc::ccccccc::c::::::::c::::::::ccccccccccccccccccccccccc:::::::::::::::::::::::::c::::cccc:::cc:::cc:::::::::::::::::::::::::::c::::::ccccccccccccccccccccccccccc::::::::::::::::::::cccc::cccccc:ccc:cccccccccccccccc:cccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::cc:::::::::::::::ccc:::::c:::cc::::::::::::::::::::::cc:::c::cccc::::::::::cccccccccccc:ccc::c:::::::ccc:::::::cccccccccccccccccccccccccc:::::::::::::::::::cccccccccccccc::::::::ccc::c::cc:::cc::::::::::::::cc:::::cccccccccccccccccccccccccccc::::::::::::::::::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::::::::::::::::::::::::::::::::::::::::::::::::::::::c::::::::::::::::::::c::::::::::::::::::::ccccc::::::::::::ccc::cc:::::cccc::::cccccccccccc::::cccccc:::ccccc:::::cccccccccccccccccccccccccc::::::::::::::::::::c:cc:::cc::::::::::::cc::cc:::::::cccc::::::c:::::cc::::::ccccccccccccccccccccccccccc:::::::::ccc::::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::cc:::::::::::::::ccccccc:::::ccccc::ccc::ccccccccccccccccccccccccccccccc:cccc::::cccccc::::cccccccccccccccccccccccccc::::::::::::::::c:::::cc::::::::cc:::cccc::::cc::::ccc:ccc::c:::::::::cccc::::ccccccccccccccccccccccccccc::::::::::cc::::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::::::::::::::::::::::::::::::::::::::::::::::::::::c::::::::cc::::::::::::::cc:::::::ccccc:::c:::::ccc::cccc:::cccccc:ccccccccccccccccccccccccccccccccccc::::ccccccc:::cccccccccccccccccccccccccc:::::::::cc:::::::::::::cc:::cc::cccccccc::cccccc::ccccccccc:c::::::::ccc:::::cccccccccccccccccccccccccccc:::::::::ccc:::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::::::::::::::::::::::::::::::::::::::::::::cc:::::::::ccc:::::c::::::cc:::cccc:::c:::ccccc::::ccc::cccccccccc::cccccc::ccccccccccccccccccccccccccccccccccc:ccccccccc::ccccccccccccccccccccccccccc:::::::::::::::::::::::::cc:cccc::cccccccccccc:ccc::cccccc:ccc::::::::cccc:::::ccccccccccccccccccccccccccc:::::::::ccc:::::c:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::::::::::::::::c:::::::c:::::c:::::cc::::::::::::cccccc::::ccccccccc:::::::ccccccccccccccccccccccc:cccccccccccccccccccccccllccccccccccccccccccccc::cccccccccccccccccccccccccccc:::::::::c:::::::::::ccccccccccccccccccccccc::cc:::::cccccccc:::cc:::ccccc::::ccccccccccccccccccccccccccc:::::::::cccc::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::::::::::cc::cc:::::::c:::::::::::::c:::cc:::::::cccccc::::cccccccc:cc:::ccccccccccccccccccccccccccccccccccccccccccccccoxk00Okxddoolllllloodxkkxdoloolccccccccccccccccccccccccc:::::::::c:::::::::cccccccc::cc::ccccc:::cccccc:ccc:ccccccccc:ccccc:::cc:cc:::ccccccccccccccccccccccccccc:::::::::ccccc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::::::::::::::::::c::::::::ccc:::cc:::::::c::::cc::c::::c:::ccc:::ccc::::::ccc:::ccccccccccccccccccccccccccccccccccccccccccccloxxkOO0OkkkkOKXK00000000KKK0KKXXNNWWWWNXKKK0kdoolclloooddollccccccccc:::::::::cc:::::cccccccccccc:ccccccccc::cccccccccccccc:cccccc:ccccc:::cc:cc:::cccccccccccccccccccccccccccc:::::::cccccc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::::::::::::::::::::c::ccc:::cc::cc::ccc:::::cc:::cc::::ccc::cccc:cccccccccccccccccccccccccccccccccccccccdkO0KKK0000OOkkOKXXXXXXXXXNNXKXNNNNNNNNNNNXXXXXKKKOO0KKKKKKK0Oxxoolllcc:::::::::cc::::ccc::cccc:cccccccc:ccccccccccccccccccccccccccccccc:cc:::cc:::::ccccccccccccccccccccccccccccc::::::::c::c:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::::::::::ccc::::c:::c:ccc::c::ccccc:ccc::::ccccccccc:cc:cccccccccccccc:ccccccccccccccccccccccccccccccccccccccclxOOOO00KKKKKKK00KKXXNNNNXNNNNXXXXXNNNNNNNNNXXKKXXXXXXXXXXXKKXXNXXK00KOdl::::::::ccc:::::cccccccccccc:cccc::ccccccccccccccccccccccccccccc::cc:::ccc:cc::ccccccccccccccccccccccccccccc:::::::cccc::::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::::::::::::::::::ccccccccc:cc::cccc::ccc:ccccc:ccc:::ccccccccccccccccccccccccc:ccccccccccccccccccccccccccccccccccclok000O0XNNNNNXK00KKXK0K0xxk000KXXXXXNNNNNNNXNNNNNNXXXXXNNXXXXXKX0dodxxxxddxOOxl::::::::cccc::::ccccccccccccccccccccc::cccccccccccccccccccccccccccccc::cccccc:::cccccccccccccccccccccccccccc::::::::ccccc::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:::::::::::::c::::cccc:::c::ccccccccc::cc:ccccc:ccc::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclx0XNNNXNXXXNNNXKKKKXXX0OOxooddoodkKXKKKKXNXXNXXXXKKKKXX00KXKKXXNNXK0kko:;;::cccccc::::::::ccc::::ccccccccccccccccccccccccccccccccccccccccccccccccccccc::cccccc:::cccccccccccccccccccccccccccc::::::::cccccc:::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::::::::::::::cc:ccc::ccccc:cccccccccc::cccccccccccccccccccccccccccccc:cccccccccccccccccccccccccccccccccccccccclxKNNNNXOO0KOkO0KXXNXXXXK0kololllol:lO0kkxkOKXXXXK0kkxddxO000OOkOO0KKXNNNXOxl:::coolc::::::::ccc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccc:::cccccc:::ccccccccccccccccccccccccccccc::::ccccccccc::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n:ccc::::::::::cc:c:::cccccccccccccccccccccccccccc:ccccccccccccccccccccccccccccccccccccccccc:ccccccccccccccccccoOXNWWNN0dcllldO0KKXXXXXXXXKxllldkkkxxdlc;;lOK00OOOd:;;;:cdk0OxkxoodxxkOOOOO0Okl,cO0kl::::::::ccc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccc::cccccc::ccccccccccccccccccccccccccccc:::cc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n::cc:::::::::c::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccldO00KNNNXKOddk0KXXXXXXXXXXKK0OOOOO0KKxc;,,.;oxxddxkOx:;,;loddxxolddlc::ccccc:;cooox0KKkl:::::ccccc:::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::ccccccccccccccccccccccccccccc:::::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\nc:cc:::c::cccccc::ccccccccccc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccldkkxdxkKK000kxkkOO0000OOOOOkdloOKKO0K0dc,...;ccc:lxO0dccclllccloolllc:;;;:cc:;.,:cok0Okkkl::::cccccc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::ccccccccccccccccccccccccccccc:::::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\nccc::::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclx0KK0OxdxOOOxl::codxxdoooolccoxO0K00kdoodl;''',;;;:lxOOdollccc::cc:;;;;,'',;;;;'','';:coxxl::::cccccc:::cccccccccccccccccccccccccccccccccccccccccccccccccccccccc:cccccc::cccccccccccccccccccccccccccccc::c::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccccccccccccccccccccc\ncc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccldxOKXNXKOxxdl:;;,,,,,,,ckOx;:k00Okkxolc;;;:;,''',,'',:ok0kocc::,.',,;;;;,''',;,;,...',;:ccc::::::ccccc:::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::ccccclcccclcccccccccccccccccc::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcc\nccc::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccooloOKKKK0Oo:;,''..'.. ;xO0OxxOkxdddddoll:;,..,,,,;'.'',:ll:,,,,'..'''',,;;,,,,;;;,',,;;::cc:cccc:ccccc::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::ccccllccccccclcclllcccccccclcc::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllccccccccccccc\ncccc:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclollxOOOO0Oxl:;'''',;;;cdxodxdoolllldk00Od:,'..,;,;;;,,'.....'',,,,,'''.''''.....,,,''',::ccc:cccc::ccccc:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:::cccclcccllcclcccllcccccccclcc:::ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcclcclcccccccccccccccc\nccc:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclxkxdddxO0Oxdoc;'',;:ldxdlc:coolcc::ldxolc;;::,..,,;;;;;;'...'';cccc::;,,,,,,,'....,',;:oolccccccccccccccc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::cclcccccllccccclccclcllllclccc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllccccclllcccccccccccccccccccccl\ncc::cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclxOOxddxkkkdoool:;,.';ccc:::::;::::::cc;;;:cdddo:'''',;;;;;;,,;:codddolc:;;,,,;,,''',,,,;:llllc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllclllcccccccclllllllllllcccccccccccccccccccccccccccccccccccccccccccccccccccllccllccccccllccccccccccccllcccccccllcccccc\nccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclxkkkkO00koc;,'.';;,...;;::;::;,,;:::::::;;;::::::;'''',,,,;,;;:loxkkOkxdolc:;;;,,,'...',:lllclccccc::cccccc:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:cclllllllclllcccclllllllllllcccccccccccccccccccccccccccccccccccccccccccccccccccllcclllcccccccccccccccccllclccllccclccccccc\nccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccldddkOOO00OOOOxl,.';;'...,;;;;;;,;;;;:::;;::;,'',;;,',,,,,,,,;;:loodxxxxxxxddoolc:;;,...;cdkkdlllc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllcllllllccclllllllclllllcccccccccccccccccccccccllccccccccccclccclcccllccccllcccccccccccccccllcclllccclccllccccccccccc\ncccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccloodOOkkkOOOOOOkxc,;:,.   ..',;;;;;;'',,,,,,,;,...,;,,;;;,,,;;;:clllllcc::clodxxddolc;'',;:ccodlccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:cclllllllllllllllllllllllllllc:ccccccccccccccccccccllccclllcccccccccllcccccccccccccccccclccccccllcccccccclccccccccccccccc\nccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclollxOkxxxxxxxddddoc;'....     ..,;;;,'....';,.','.',,;::::;;;;;::cloddddooc:;::cclddolc:;:::::cllllc:cccccccclcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccccc:ccllllllllllllllllllllllllcllc:cccccccccccccccccccccccccllccccccccccccccccccccllccccccllllcccccccccccccccccccccccccccccll\nccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccdkkxdooollccc:::;'..........  ..,,,;,''',;,.''',,,;:ccc:::::::::::cccclccc::::::cloolllc:ccccccllccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccccc::cllllllllllllllllllllllllllllc:cccccccccccccccccccccccccccccccccccccccclllllccccclllccccccccccccccccccccccccccllllllllll\ncccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccoxdxkdl::::::cc;,,''..      .....',,,;;,,,,,'',;;:cloodollc::;;;;:;;,,;;;;::::::c:looooolcclllllllcccccccccccccccccccccccccclllcccccccccccccccccccccccccccclccclccccccccccccccccccccccllllllllllllllllllllllllllllc:cccccccccccccccccccccccccccccclllcclllllllllllcccccccccccccccccccccccccclllllllllllllllll\nccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllloooc:;,'',;;,,;:.....    ....'',,,,,,,,;;;:ccooddxxxxxdol:;;;:ccc::;;;,;;;;;;clollllllllllllllcccccccccccccccccccclccccclccccccccccccccccccccccclcccccccccllcccclcccccccccccccccccllllllllllllllllllllllllllllccccccccccclcccccccccccclllclllllllllllccclllccccccccccccccccccccccllllllllllllllllllllllll\ncccccccccccccccclccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::;,,;:;..  ';;';c;'';;'.   ....'',,,;;;;;;:clodddxxxxkkkkkkxdoddxxdol:,,,,;;,;:oxdlllllllllllllllcccccccccccccccclcccccccclccccclllcccccccccllcccclcccccccclllccccccccccccccccccccccclllllllllllllllllllllllllllcccccccccccccccllcccccccccccclcccccccccccccccccccccccccccccclllllllllllllllllllllllllllllll\nccc::cccccccccccccccccccclccccllcccccccccccclcccccccccccccccccccccccccccccccccccccccccccccccccclccol:;,,''''....','';:;,:;.     ...',,,,;;;;;:ccloddxxxxxkkOOOO000Okxddool;'',,;;:loxOkoclllllllllllllcccccccccclccccccccccccccccclccllllllcccccccclcccccccccccclllcccccccccccccccllccccccllllllllllllllllllllllllllllccccccccccccccllccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllll\nccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcccclllccccccccccccccccclllllo:;,,,',,,,,,,,'';::::,.      ..',,;;;::::cccooddxxxxkkkOOO00000Okxolllc;;:::coxkO00dllllllllllllllccccccccccccccccccccccllllcclcclllllllcccccclllccccccccccclcccclcccccccccccccccccccclllllllllllllllllllllllllllllcccccccccllccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllllll\nccccccllccllccccccccccccccccccccccccccccccccccccccccclccccccccccccccccccccclllcclccccccllcccclcclccc:;;;,,,,,,;;;::;;:c::;'.  .....',;;:::::ccllloddxxxxxkkkkOOO000000OkxdolooddxkOOO00Oolllllllllllllcccccccccccccccllllcclllllcllcclllllllcllccllllcccccccccccccccccccccccccccccclllcccccllllllllllllllllllllllllllllc:cccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllll\nccccccccccccccclccllccllllllcccclccccccccccccccccccccccccccccccccccccccclllllllllcccllcclllllllcllcc:::::;;,',;;;:cl::lc:;;,,,,'...,;:::ccclollllooddddddxxxxkkkkOO00000OOOOOOO00OOOOO00xlllllllllllllccccccccccclcccclllcclllclccccclccccccccccccccccccccccccccccccccccccccccllcllllllccccllllllllllllllllllllllllllllc:cccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll\nccccccccccccccccccccclcccllcccclllclllclllllccccccccccccccccccccccccccccccccccccccccccccccccccccccccc:::;''...,;;;::;;:clcc:::::;;,;:::cccloooooooooooodddddddxxxkkOOOOO0000000KKKK00O0KOollllllllllllccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllcccccclcccccccclllllllllllllllllllllllllllllc:ccccccccccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll\ncccccccccccccccccccccccccccccccccccccccccclllclccclcccllllllllcclllccccccccccccccccccccccccccccccccccc:;,.....,;;;:;;,,;;::clllllcc::ccllllllloooooooooooddddddxxkkkOOOOOOOOOOOOOO00K0KKKxllllllllllllcccccccccccccccccccccccccllllcclllllllllllcclllllllllllllcccllccllllllclccccccccccccccllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll\ncccccccccccccccccccccccccccccccccccccccccccccccccccccccllcccccccccccllcccccclllccllllllllllllllllllllcc:;;,..';:::;;,,'.'',,;::cc:::clloooolloddodddoooooddddddxxxkkOOOOOOOkxodxkO00KKKXXOolllllllllllccccccclccclllllllllllcclllcllllcllllllllllllcccccllllcccccccccccccccllcccccccccccc::clllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllool\nllllllllllllccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllclllllllcc:;,..,;;;,,,,,''...',,;;;;;:loooooddddddddddddoooddddddxxxkkkkkkkkkxddOKXXXXKKXXXKxllllllllllllcccccccccccccccllcclllcllccclccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll\nllllllllllllllllllllllllllllcllccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccc:,'';:;,,,,,,;,'...',,,,;;;clooddddoodddddddooddooodddddxxxxkkkkkkkOkxkkxdxxkkxxkOkolllllllllllccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllolllllllllllllllllllllllllllooloooloo\nllllllllllllllllllllllllllllllllllllllllllllllcllcccccccccccccccccccccccccccccccccccccccccccccccccccccc:,.,cllc:;;;;;;;,,'',;;;;;;:llooddddodddddddddddooooodddddxxxkkkkkO0KOdc;..'',:cccoollllllllllllccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloollllllllllllllollllolooooooooo\nllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllcccccccccccccccccccccccccccccccccc::;;cllol:;;;:::;,'',;;;;;;:clloooodddooddddddoooooodddddddxxxkkOOO00K0ko:;;;:;clllllllllllllllllc:ccccccccccccccccccccclccclllcllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllollllllllllllloooolllllloooooooooollolll\nllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllcllollcccc:;,'',;;,,,,;;;;;:::ccllloooooooooooooooooooodddddddxxkkkkkOO0KK0kdlclolllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllollllllllllllllllllllllllllllllllllllllllllllllllllllllllloooollllloollooolllloooooooollooooooloolllllcc\nllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllollool::;,;;;:;'..',,,,;;;::::::ccclllllllooooooooooooooddddddddxxxxxdddxO0000Oxllollllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllolllllllllllllllllllllllllllllllllllllllllllllllllllllllllllollllllloollloollloooooooooollooollolllllcccc::::::\nlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllldo:;;:cllll:'...;;;::ccccccccccccccllllllllloooooooooooodddddddddolclooollloollllllllllllllllllllllollllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllooolllloooollllllloooollloooloooooolooooooooolllllcccc::::::::::::::\nllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllc:clooooollcc:;..';::clllllolcccccccccccllllllllllllloooooooooddddxkkkxdxxxxoclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloollllloollllllolllllllllllllllollllllllloooolllooooooolllllllloolloolloooloooolllllcccc::::;:::::::::::::::::\nlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllc:::::::c:::;,',;;:clooooddolcccccccccccccccllllllllloooooooddddxkOOOkdlloddooloollllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloollllllloolloollllollllllllllllllollooollllllllllloooloooooooolllloollllllloooooolllllllccc::::::;::::::::::::::::cccccccc\nlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllc:::::::::;;,'''.,:cloodddddolcccccccccccllcclccclllllloooooddxxkOOOOkdoccclooooolollllllllllolllllllllllllllllollllllllllllllllllllllllllllllllllllllllllllllllllllllllllloolllllllllllllollooooooooooooolllloooooollllooooollllloooollooooooooooooooooollllllccccc::::::::::::::::::::::::ccccccclllllllo\nlllllllllllllllllllllllllllllllllllllllllolllllllllllllllllllllllllllllllllllllllllllllllllllllllllllc::;:::;;::cc:;'.,:coodddxxddolc:cccllllllllllllclllllllllooodxxkO000K00kdoooolllllllllollllllllolllllllllolllloolloolllllllllllllllllllllllolllllllllllllllloolllllllllllllloollllooooolloooooooooooooooooooooooooolllloollooooooooooollooooooollllllcccc:::::::;:::::::::::::::::ccccccclllllllllllllllll\nooollllllllloolllllllllllllllllllllllllooollllllllllllllllllllllllllllllllllllllllllllllllllllllllloolc:;;;:::cclllllc:clodddxxxxxdolc::cccllllllllllllllllllllllooddxkO00KKKKK0kdooollllooloooooollooollllllllloolllllllllllllllllllllllllllllllllllllllllllooolllollllllllllllllllolloollooolooloolooooooooooooooooooooooolooollooooooollllllllccccc::::::::;:::::::::::::::ccccccccllllllllloolllllllllccc:::\nlloooolllollloollllllllllllllllllllllllllooollllllllolllllllllllloolllllllllllolloolllllllllllllllllollc:;;:::::::::cclllodddxxxxxxddlc::::ccccccclllllllllllllllllloodxxkOOOOkkxdolooooooooooooolllooolllllllllooollloolllllllloolllooloollloolllllloollllooooollllollloollloolooloooooolloollooooooloooooooooooooooooooooooooollllllccccc:::::::;::::::::::::::::::::ccccccclllllllllloollllllllcccc::::cccccl\nooooolllllllllollllllolllllllolllooolllllloooollllllllllllollllllllllolllllllllllllllllllllllllloolllllccc:c::::::;;::lloodddxxxxkkxxdolcc::ccccccclcclllllllllllllllllloooddddoddoooooooooooooooooooooooooooooooloooooollllllllooollllllooollooolllooooooooolllloooooolllllloolllooooolooooollooooooooooooooooooooooooooooolc:::;;;;;;:;;;::::::::::::::::cccccccclllllllllllloollllllllcccc:::::ccccclllllllll\nlllllllloooooolllooooollollooolllooooooolllooooolllllllllloooooooollooooooollooooollllooooolllooolloooolcccccc:::::::clooodddxxxkkkkkxdddoollllcccccclllllllllllloooollllloooooooooooooooooooooooooooooooooooooooollloooooooolllooolllllllllloooooooooooooooollooloooooooooooollloooooolooooooooooooooooooooooooooooooooooool:;,,;;;;;::::::::::cccccccccclllllllllloollolllllllccccc:::::ccccclllllllooolloollo\n:::c:cccccclllllllooooooooooooolloooooollooooooolooolllooooollooolllooooooolooooooolooooollooooooloooooolc::::::;;;:clooooodddxxxxkkkkkkxxxdddolllcccccclllllllloooooooooooddddoooooooooooooooooooooooooooooooooooooooooooooooolooooolooolloooooooooooooooooooooooooooooooooooolloooooooollllllloooooooooooooooooooooooooooolc:;;;;:::::cccccccllllllllllloollllllllllccccc::cc:cccccclllllllloooooooooooooooolo\n::::::::::::::::::cccccccclllllllllllooooooooooooooollloooooolooooooooooooooooooooooooooolooooooooooooool:::::::;;;cllooooodddxxxxkkkkkkkkkxxxddoolllcccllllloooooooodddddddddoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooolllllllllllcccccc::::::cloooooooooooooooooooooooooooolcccccccllllllllllllooolllllllllccccc::::cccccclllllllllooooooooooooooooooooooolooo\n:::::::::::::::::::::::::::::::::::cccccccllllllllllllllllloooooooooooooooooooooooooooooooooooooooooooollc::c::::;:loooooooddddxxxkkkkkkkkkkxxxdddooollccccllllllooodddooooooooooooooooooooooooooooooooooooooooodxxkkOOOkkkkkxdooooooooooooooooooooooolollllllllllccccccc:::::::::::::::::::::::loooooooooooooooooooooooooooolllllllllllllolllllllccccccccccccccccclllllllooollooooolooooooooooooooooloooooooooo\nlllllccccccccc:c:::::::::::::::::::::::::::::::::::::::cccccccccccllllllllllooooooooooooooooooooooooooooolc:::::::clooooooooddddxxxkkkkkkkkkkxxxxxddddoollcclllloooooooooooooooooooooooooooooooooooooooooooodxkO0KKK000OOOOOOOOkkkxolllllllllccccccccc::::::::::::::::::::::::::::::::::::::::::loooooooooooooooooooooooooooollllllllllllool::::::cccccccllllllllooooooooloooooooooooooooooooooooooooooooooooooo\nloolooollollllllllllllccccccccc:::::::::::::::::::::::::::::::::::::::::::::cccccccccccccclllcllllllllllllc::::::cloooooooooddddxxxkkkkkkkkkxxxxxxxxxxxxxddollllooloooooooooooooooooooooooooooooooooooooolloO0OO0KNNNNNXK0OOOOOOOOkkxlc::::::::::::::::::::::::::::::::::::::cccccccccccllllllcclooooooooooooooooooooooooooooolllllllllollolccclllllllooolloooooollloolloooooolooooooooooooooooooooooooooooooooo\nllllooooooooooooooooooooolllllllllllllcccccccccccccccc::c::::::::::::::::::::::::::::::::::::::::::::::::::::::;;:loodddoooooddddxxxkkkkkkkxxxxxxxxxxxxxxxxdolllolcllccccclooooooooooooooooooooooooooooooloxkxdxkO0KXXNNNNX0OxxkOOOOO0ko::::::::::::::ccccccccccccccccccllllllllllllllllolooollllloooooooooooooooooooooooooooolllllllloollollllllloooloooooooooooooooooolooooooooooooooooooooooooooooooooooooooo\n::::ccccccllllllllllllloooloooooooooooloooollllllllllllllllllcccccccccccccccccccccccccccc::::::::::::::::::::::::cloooddoooooddddxxxkkkkkkkxxxxxdxxxxxxxxddddoollccll:::::cooooooooooooooooooooooooooooodddollllodxkkO0KXXNNNK0xddxkO00Odccccccccclllllllllllllllllloooolloooooooolllollllloollllloooooooooooooooooooooooooooollllllllollooolllllloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nllccccccccccc::cccccccccccllllllllloooooooooooooooooooooooooooooooolllllllllllllllllllllllllcclccccccccccccccc:::clooddddoooooddddxxxkkkkkkxxxddddxxdddddddddooollclolc:::coooooooooooooooooooooooooooxkkxlllllllllooxkO00KXXNNX0xooddddxdollllllooooooooooooooooooooolloolllllllcclcccclllloollllooooooooooooooooooooooooooooolllloloooooooollooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nlllloooolllllllllllccccccccccccccccccccccclllllllllllllooooooooooooooooooooooooooooooooooooooooooooollllllllollcccooddddddooooodddxxxkkkkkkkxxxxxxxxxdddddddoooollllodollclooooooooooooooooooooooooodxxxxollc:;,;:clllodxkO0KXXNNNKOxdoooxdoolooooooooollllllllllllcccccccc::cc:ccccccccloolllllllooooooooooooooooooooooooooooolllollooooooolllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\noooooooooooooooooooooooolllllllllllllcccccccccccccccccccccccccllllllllllllllllooooooooooooooooooooooooooooooooooloodddddddddoooddddxxkkkkkkkkkkkkkkkxxxddooooooolllldxdollloooooooooooooooooooooodddlclll:;:;,'''',;cclllodxO0KXNNNNXKOdoddlclccccccccccccccccccccccccccclllllllllllllllloooooollloooooooooooooooooooooooooooooollllooolooooollooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nooooooooooooooooooooooooooooooooooooooooooolllollllllllllllccccccccccccccccccccccccccccccclllllllllllllllllllllloddddddddddddddddddxxkkkkkkkkkkkkkkkkkxxddoooooolllodkxolllooooooooooooooooooooddol::::::::cccc:;,'''',:llloxOO00KKXXXXKOxolcclcclclllllllllllllloooooooooooooooolllllllloooooollllooooooooooooooooooooooooooooolloooooooooooolooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooolllllllllllllllllllcccclccccccccccccccccldxxddxxxdddddddddddxxkkkkkkkkkkkxxxxxkkkxxddddooooodxkkdlllooooooooooooooooooddolc:ccc:::lxkOkkkxddoc:;,;codk000OOOKKKKXXKOdooooooooooooooooooooooooooooooooooooooooooollooooooolllooooooooooooooooooooooooooooolllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodxxxxxxxxxxdddxddddddxkkOOOkkkxxxxxxxxxxxxxddxxddddddxkkdooodxxdooooooooooooddolcllllccccloxkkkkOO00KKKKK00KKK00000OOKKKKKXXX0kdoooooooooooooooooooooooooooooooooooooooollloooooolllooooooooooooooooooooooooooooolllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooxkkkkkxxxxxxxxxxxxddddxkOOOOOkkxxxdddddddddddxxxxxddxxkkOOOkdxO00OOkxxdooooooolllllllllccclloddddxxxkOKKKXXXK0OOO0KKK00KXXKKXXXXKOxoooooooooooooooooooooooooooooooooooooollloooooollloooooooooooooooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodxkOkkkkkkkkkkkkkkkxxdddxkOO0OOkxxddddddddooddxkkkkkxxkkkkOO00xloxkO0KKK0Okxollllllllllllcccclodooooooodxxxxk0KK0OOO00KK00KKKKKKXXXXX0kdoooooooooooooooooooooooooooooooooooolloooooollloooooooooooooooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodxkOOOOOkkkkkkkOkkkkkkxxdddxOO00OOxxdddooooooddkkkOOOkkkkkOOOOO0Oolooddxkkxxddoollooollllllcc:::clllccclloolccldk0KK00000000O0KKKKKKKKKXX0xooooooooooooooooooooooooooooooooooollooooooollooooooooooooooooddoooooooooooollooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodxkOO00000OOOOOOOOOOOOOOkkxxddxkO000OkxddoooooddxkOOOOOOOOOOOOOOOO00d:cooooooooddooooooolllllllccc:::::,,,'':olccccldk00000O000OO00KKKKKKKKKX0xooooooooooooooooooooooooooooooooooolooooooolllooodoooooooodddddooooooooooooolooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\nooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddxkOO00000000000OOOO0000000OOkkxxxxkO000OkdddddddxkkO00000OOOOOOO00OO000xl:cloddddddddoooollllllllllccc:cclcclodxxollllllodxO0000000OO0KKKKKKKXXXKKOdooooooooooooooooooooooooooooooooolooooooolllodoodoooooooddoooooooddddooooolloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodxkkO00KKKKKKKKKKK00000000000KKK00OkkkxxkO0KK0kxdddxxkOO00KKK00OOOO0000000KK0kdc::coddddddooooolllllllllllccccoddxkkkxxxdoodddddoxO0000000O0KKKKKKKXXXXXK0kdoooooooooooooooooooooooooooooooloooooooollooooddoodddddddddddoodoooooooolloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooood\nooooooooooooooooooooooooooooooooodooooooooooooooooooooooooooooooooooooooooooooooooooooooodxkkO0KKKKKKKKKKKKKKKKKKKKKKKKKKKKKXKKK00OOkkxk0KKKOOkkOOO000KKXXKK0OO00KKKKK0KKXK0kol::clooooooolllllllllllllllllllodddoooddxdodddxxdddkO00000000KKKKKXXXXXXKXKOdooooooooooooooooooooooooooooooooooooooollooooodoodddddddddddoodooooodoolloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\noooooooooooooooooooooooodoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodxkO0KKKKKKKKKKKKKKKKKKKKXKKXXKKKKKKKXXXXXXXK00OkkkOKXK00000KKKKKXXXXKKKKKXXXXXXXXXXXXX0kdlccccllllllllllllllllllllllllllcclllllloddxxxdxdddddkO0000000KKKKKXXKXXXKKK0xoooooooooooooooooooooooooooooooooooooollooddddoodddddddddddddddddddddoolodooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddoooooooooooo\nooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddddoodkO0KKKKKKKKKKKKKKKKKKKKKXXXXXXXXXXXXXXXXNNXNNNXKK00OkO0KXKKKXXXXXXXXNNXXXXNNNNNNNNXXXNNNNNX0kddocccccccccclllllllllllllloddoooollllllooxkxxxdddddxkO00000000KKKKKKKKKKKKOdoooooooooooooooooooooooooooooooooooooolooddddddddddooddddddddoddooddooloooooooooooooooooooooooooooooooooooooooooooooooooooooddddooodddooddooooooood\noooooooooooooooooooooooooooooooooodooooooooooooooooooooooodddooododddddooddooddxkOKXXKXKKKKKKKKKKKKKXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNXXXKKKXXXXXXNNXXXXNNNNNNNNNNNNNNNNNNNNNNNNNXK0kdol:;;;:::::ccccccllcccldkkOkxddooooooodxkkkxxxxxxxxkOOOOO00000KKKKKKKKKKOdooooooooooooooooooooooooooooooooooooolloddddddodddooddddddddddddddddooooooooooooooooooooooooooooooooooooooooodddooodddoooddddddddddddddddddooooodd\noooooodddddoooddoooooddooooooooooooooooodddoooddoooooooooooooddddddoooddxxkkO0KXXXXXXXXXXXXXXKXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNXXXNNNNNNNNNNNNNNNNNNNWWWNNNNNNNNNNNNNXX0Okdolc;;;;;;::::::ccccccldxxxdoooodddddddxxxxxxxxxxxdxxkkOOOOOOO00000KKKKK0kdoooooooooooooooooooooooooooooooooooolloddddddddddddddddddddddddodddooooooooooooodoooooooooooooddooddoooooooooodooodddooodddddddddddddddddddoodddo\ndooooddoodddddddoooooooodddddooooooooooooooooodoodddoodoodddddoooddxkO0KXXXXXXXXXXXXXXXXXXKKKK00KK00KKKKKXXXXXXXXXXXNNNNNNNNNNWWWWWWNNNNNNNNNNNNNWWNNNNNNNNNNWWNWWWWWWWNNWNNNNNNXK0kxdolc:;;;;;;;;;;:::ccc:codoooollooooddddddddddddddddddxxkkkkkkOOOOO000KKK0xoooooooooooooooooooooooooooooooodooooloddddddddddddddddddddddddddddoolodoooooddddooodoooooooooddoooooddoodoooddddodddddddddddddoddddddddddddddddo\nddoooooddddddddddddddddddddddddddddddddddoooooddddddooddddddodxkO0KXXXXXXXXXXXXXXXXXXXXXXKKK0Okkkxxk00KKXXXXXXXXNNNNNNNNNWWNNNNWWWWWWWWWWWWWWWNWWWWWNNNNNWWWWNNNWWWWWWWWWWWNNNNNXK0Okxdoolc:;;,,,,,,;;:clldO00OdoooolllllllllllooooooooodoodddxxxxxkkkkOOO0KK0Oxoddooooooooooooooooooooooooooooooooolodddddddddddddddddddddddddddddoooddddddooddooddooooooooooooddodddodddddddddooddddddddddddodddddoddddddddddd\nodddddddddddddddddddddddddddddddddddoodddddddddddddddddddodxO0KXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKK0000KKKXXXXXXXXNNNNNNNNNNNNNNNWWWWWWWWWWWWWWWWWWWWWWNNNNNNNNNNNWWWWWWWWWWWWWWNNXXXK0Okxxddolc:;;,,,,;cdkO0KXXNX0xoooolllllllllllllllllllollllooddddxxxkkOO000000xoodddooooooooooooooooooooooodddddoolodddddddddddddddddddddddddddddoooddooooooddoooodooddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddoddddddddddddddoodddoddddddddddddddddddddk0KXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKKKXXXXXXXXXNNNNNNNNNNNNNNNNWWWWWWWWWWWNNNNWWWWWWWNNNNNNNNNNNNNNNWWWWWWNNNNNXXXK00Okkxxddolc:;;;;;:okOO0KXXXXKkdooollllllccccccccccccccclllllooddddxxkOOO000KKkdoddooodddoooodddooooooooooddooooolooddddddddddddddddddddddddddddoooddoooooddddooodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddoddddddddddddddddddddddk0KKKKXXKXXXXXXKXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKXXXXXXXXXXNNNNNNNNNNNNNNNNNWWWNNNNNNNNNNNNNNNNNNNNNNNXXXXXXNNNNNNNNNNNNNNNNXXXK00OOkkxxxdolc:::::lxkO0KKXXXXX0kdooolllllllccccccccccccccclllloooodddxkkOOO0KKOdoddoooddooooooooooooodoooodoodooooodddddddddddddddddddddddddddddooododddddddddoddddddddodddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddddddddxO0KKKKKKKKKKKKKKXXXXXXXXXKKXXXXXXXXKKXXXXXXXXKKXXXXXXXXNNNNNNNNNNNNNNNNWNNNWWWWWWWWWWWNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWWNNNNXXKK000OOkkkxxddolcc:codxO0KKKXKXXKKkdoooollllllcccclccccccccccccclllloodxxkOOOOOOkdodddoddddoooodddooooooooodddddoooodddddddddddddddddddddddddddddooodddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddddddddddddddddddddddxO000KKKKKKKKKKKKKKKKKKKKKKKKXXXKKXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNWWWWWWWWWWWWWWWWWWWWNNNNNWWWWWWWWWWWNWWWWWWNNNNXXXKK000OOOOkkxxxddolclodxO00KKKKKKKK0kooooolllllcccccccccccccccc:ccllllodxxxxdoodxxdddooddddooddddddddoooooodddddoolodddddddddddddddddddddddddddddooodddddddddddoddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddddddxO0000KKKKKKKKKKKKKKKKKKKKKKKKKKKKKXKKXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNWWWWWWWWWWWWWWWWWWWWWWWWWNWWWWWWWWWWWWWWWWNNNNNNNXXXK0000OOOOkkkkxxddolloxkO0000KKKKKK0Oxdoloollllcccccccccccccc::::cccllllolllccclxxdododddooddddddddooddoooodddddolodddddddddddddddddddddddddddddoooddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddddddddddddddddddddxkOO00000KKKKKKKKKKKKKKKKKKKKKKKKKKKXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWWWWWWWWWWWWWWWWWWWWWWWWNNNNNNNNNWWWWWWWWNNNNNNNXXXKK0000OOOOkkkkxxddooddxkO00000KKK00Okxxddolllllllllllcccccccccccclllcccc::cccccdkxddddddooodddddddddddoooddddddooodddddddddddddddddddddddddddddolodddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddddxkO000000KKKKKKKKKKKKKKK0KKKKKKKKKKKXXXXXXXXNNXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWWWWWNNNNNNNNNWWWWWWWWNNNNNNNNNNNNNNNNNNNNNNNNNNXXXXKK000OOOOOkkkkkxddoddxkOO00000KKKOkxxkOOkkxdoollllllccccccccccccccc::;;::ccllldxkxddddddodddddddddddddooddddddoooddddddddddddddddddddddddddddddooddddddddddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddddxkOO00000KKKKKKKKKKK0000000KKKKKKKXXXXXXXXXXXXXXXXXXNXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNWWNNNNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXNNNNNNNNNNXXXXKKK0000OOOOOkkkkxdddddxkkOO00000KK0kxxkOO000KK0Oxdlllllcccc::::::::;;;;;;;:clooodxxddddddddddddddddddddooddddddoooodddddddddddddddddddddddddddddooddddddddddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddddddddddddddddddxkOOO000000000000000000000000000KKXXXXXXXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNXXXXKKKKKKKKKKKKKKKKXXXXXNNNNNNNNNXXXXXXKKK000OOOOOOkkkxxddddxxkkOO000KKKKOxxkO00KKKKKXXK0kdlllcccc::::;;;;;;;;;;:cloodddxxdddddddddddddddddddooddddddoooodddddddddddddddddddddddddddddooddddddddddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddxkkOOO00000000000000000000000000KKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNXXXKK00O000000KKKXXXXXNNNNNNNNNNXXXXXXXKKK00000OOOkkkkxxxddddxxkOO0000KKK0kkO0KKKKKKXXXXXXKxllccc:::::::;;;;;;;;;:clodddxkkddddddddddddddddddooddddddooooddddddddddddddddddddddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddxkOOOOO000000000000000000000000KKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXNXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNXKKK000KKXXXXNNNNNNNNNNNNNNXXXXXXKKKKK0000OOOOkkkxxxxxdddxkOOO00K000K0O0KKKKKKKXXXXXXXKxllccc::::::::;;;;;;;::coddxxkOkdddddddddddddddddoodddddddoooddddddddddddddddddddddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddddddddddddddddxkkOOOOOOO0000000000000000000KKKKKKKKXXXXXXKKKKKKKXXXXXXXXXXXXNNXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNWWWWWWNNXXXXXXXXXXXNNNNNNNNNNNNXXXXXXXXKKKK0000OOOOkkkkxxxxdddxxkOO000000KK00KKKKKKKKKXXXXXNKxlccc:::::::::;;;;;;;:clodxxkkkkdddddddddddddddddoddddddddooddddddddddddddddddddddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddddddddddddddddxkkkOOOOO0000000000000000000000000KKKKKKKKKKKKKKKKKKKKXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNWWWWNNNNNNXXXXXXXXXXNNNNNXXNNNXXXXXXXXKKKK0000OOOOkkkkkxxxxxxxxkOOO0000000000KKKKKKKKKXXXXXXKxllc:::::::::;;;:;;;;:codxkkkkkkddddddddddddddddoodddddddooddddddddddddddddddddddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddx\ndddddddddddddddddddddddddddddddddddddddddddddxxkkkkOOOOO000000000000000OO000000000000000KKKKKKKKKKKKXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNXXKKKKXXXXXXXXLOVEXYOUXFOREVERK0000OOOOkkkkxxxxxxxxxkkOOOO000000000000KKKKKKXXXXXX0dllc:::::::::;;;;;;;;:lodxkkkkkkxddddddddddddddoodddddddooddddddddddddddddddddddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddxxkkkkOOOOO000000000O0OOOOOOOOOOOOOOOOOO00000000000KKKKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNXXNNNXKK00KKKXXXXXXXXXXXXXXXXKKKKKKKK0000OOOkkkkkxxxxxxxxkkOOOOO00000O0000000KKKKKKXXXXKxllcc::::;;;;::::;;;;::codxxxxkOkddddddddddddddoodddddddooddddddddddddddddddddddddddddddooddddddddddddddddddddddddddddddddddddddddddddddddddddddxxdddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddxxkkkOOOOO000000000OOOOOOOOkkkxxkkkkkkkkOOOOOOO000000KKKKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNXNNNNXKK0KKKXXXXXXXXXXXXXXXXKKKKKKKK00000OOOOkkkkxxxxxxxxkkkOOOOOOOOkkOOOOO0000KKKKKKKKKxllccc::::;;:::;;;;;;;::cloodxxkkxddddddddddddddddddddddooodddddddddddddddddddddddddddddoodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddxxxkkOOOOOO0000000OOOOOOOOOkkxdddxxxxddxxkkkOOOOO000000KKKKKKKXXXXXKXXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXXXXXXXXXKKKKKKKKK0000OOOOkkkxxxxxxxxxxxkOOkkOkkkddxkkkkOO000000KKKKKklllccc::::::::;;;;;;;;;;:cloddxkkxddddddddddddddddddddddoodddddddddddddddddddddddddxddxdodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\nddddddddddddddddddddddddddddddddddddddddddddddxxkkkkOOOOOO000OOOOOOOOOOkkxollllooolodxxxxkkOOOOO000000KKKKKKKKXKKKKKXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNNNNNXXXXXXXXXXXXXXXXXXXKKKKKKKKK0000OOOOOkkkxxxxxdlccoxkkkkkkxxdlldxxxxkkOOO0000000Kkollccc:::::::::::;;;;;;;;;:codxkkkxddddddddddddoddddddddoodddddddddddddddddddddddddxxxxdooddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddddddddddddddddddddddddddddddddddddddxxkkkkOOOOOOOOO000000OOOOkkdlcccllccloddxxxkkkkOOO0000000KKKKKKKKKKKKKXXXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNNNXXKKKXXXXXXXXXKKKKKKKKKKKKKKK0000OOOOkkkkxxxxdol:codxkkkkxdo:;clodddxxkkOO0000KKK0dlllcc:::;;:::::::;;;;;;;;;:cldxkOkxdddddddddddoddddddddoodddddddddddddddddddddddddxxxxdooddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\ndddddddddddxxddddddddddddddddddddddddddddddddddxxxxkkkkOOOOOO000000OOOOOOOkdcccccccloodddxxxkkkkOOOOOO00000KKKKKKKKKKKKKKKKKKKKXXXXXXXXXXXXNNNNNNNNNNNNNNNNNNXXKKKKKKKKXKKKKKKKKKKKKKKKK0000000OOOkkkxxxxxddollodxxxxxdl:',;cclooddxxkkOO000KKKkollccc:::::;;;;::;;;;;;;,;;;cldxkOOkdddddddddddddddddddoodddddddddddddddddddddddddddxxdooddddddddddddddddddddddddddddddxxxxddddddddddddddddddddddddddddddddxxxxx\nddddddddddddddxxdddddddddddxdddddddxdddddxdooddddxxxkkkkkOOOO000000OOO000OOkocccccclooddddxxxxkkkkkkOOOOO00KKKKKXKKKKKKKKKKKKKXXXXXXXXXXXXXXXXXXNNNNNNNNNNNNXXXKKKKKKKKKKKKKKKKKKKKK000000000OOOOkkkkxxxddxdoooddxxxxdl;'',;;:cclooodxxkkOO000K0dllcccc::::::::;;;;;;;;;;;;;;:ldkO00kddddddddddddddddddoodddxxdxdddddddddddddxxxdddddxdoodxdddddddddxddddddddddddddddddddddddddddddddddddddddddddxxddxxxxxxxxxxx\ndddddddddddddxxdddddddddddddddddddxxdddddddoooodddxxxkkkkkOOOO0000000000000Oxoccc:clllooodddxxxkkkkkkkkkkkkO0KK000000KKKKKKKKKKKKXXXXXXXXXXXXXXXXXXXXXNNXXXNNXKK000KKKKKKKKKKKKKKKK00000000OOOOOkkkkxxddddddoooddddddl;'.',,;::ccllooodxxkkkOO00koccccc::::::::;;;:;;;;;;;;;;;:ldkO00Oxddddddddddddddddooddddxxddddddxxddxddxxxxxxxxdxddodxxdddddddddddddddddddxddddddddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxx\nxdddxdddxxddddddddddddddddddddxxxxxxdddddxdooooddddxxxxkkkOOOO00000000KKKK00Oxl::ccllllooooodddxxxxxxxkxxxdooooxkkOOO000000KKKKKKKKKKKKXXXXXXXXXXXXXXXXXXXXNNXXK0000000KKKKKKKKKKK00000OOOOOOOOkkkxxxdddddooooooodddl'...',;;;::cccllloodddxxkkOOdlcccc::::::;;;;:::;;;;;;;;;;;:ldkOO0Oxddddddddddddddddodxxdxxdxxxxxxxxxxxxxxxdxxxxxxddodxxddddddddddddddddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxdddxxxxxdddddddddddddddxxxddddddddddddooooodddddxxxkkOOOOO00000KKKKKKK00koc::ccllllllllooodddddxxxxxdoc::ldkOOO000000000KKKKKKKKKKKKKKKKKXXXXXXXXXXXXXXNXXXK00000000000000000000OOOOOOkkkkkkxxdddddoooooooodool,....',;;;;::cccccclllooddxxkxocccc::::::;;;;::;;;;;;;;;;;;;:lxkOOOOkdddddddddddddddoodxdxxxxxdxxxxxxxxxxxxxxxxxxxxdodxxdddddddddddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nddddddxxxxxxxxxxxxdxxxxxxxxxxxxxxxxxxxxddddooooooodddxxxkkkkOOOO000KKKKKKKKK00xl:;:ccllccccclllooodddddxxxdlcldkOOO0O00OOOO000000000KKKKKKKKKKKKKKKKKKKKKKXXNNNXKK000OO00000000000000OOOOkkkkkkkxxxdddooooooooooooo:',;''',;;;;:::ccccccccllloddxxocccc::::::::;;:;::;;;;;;;;;;;;:lxkkkOOkxdddddddddddddoodxxxxxxdddxxxxxxxxxxxxxxxxxxxdooxxddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\ndddddxxxddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdolloooooddxxxkkkkkOOO000KKKKKKKKKK0kd:,;:ccccccccccclloooodddddddodxkkkkOOOOOOOOOOOOOO000000000KKKKKKKKKKKKKKKKXXNNNNXXK00OOOOOOOO0OO000OOOOOOkkkkkxxxxdddooooollllloool;':oc;,,;;::::::cccccccccllooddocccc:::::::::;;;;;;;;;;;;;;;;;;coxxkkkOkxddddddddddddoodxdxxxxxxxxxxxxxxxxxxxxxxxxxxxddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxdxxxxxxxxxxxddxxxxxxxxxxxxxxdxxxdxxxxxxxdollooooooddxxxkkkkOOO00KKKKKKKKKKK0Oxc,',:ccccccccccccllllooooooodddxxxxkkkkkkkkkOOOOOO00000000000KKKKKKKKKKKKXNNNNNNNXXXK00OOOOOO0OOOO0000OOOOkkkkkxxxddddooooooolooodl,':ddl:;;;::::::ccccccccllllooolcccccc::::::;;;;;;;;;;;;;;;;;;;:loodxxkkkddxdddddddddoodddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxdxxxxxxxxxxxxxxxdxxxxxxxxxxxdolllooooooddxxxkkOO0000KKKKKKKKKKK0Oxl;..';::ccccccccccccllllloooooddddxxxxxxxkkkkkOOOOO0000000000KKKKKK0KKKXXNNNNNNNNNNNNNXXKKKKKKKKKKKKKK0000OOOOOkkxxddddddooooooodddc,cddddl:;:::::cccccccccclllloolcccccc::::::::;;;;;;;::;;;;;;;;;:ccloddxkxdddddddddddddxxxxxxxxxxxxxxxxxxxxxxxdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdxxxxxxxxxdollloooooooddxkOOO000KKKKKKKKKKKK00Oko:,..',;::::ccccccccccccllllooooddddxxxxxxxkkkkOOOOO0000KKKKKKKKXXXXXNNNNNWNNNNNNNNNNNNNXXXXXXXXXXXXXKKKKK0000OOOkkxxxdddddodddddxko:cdxdddoc::::cccccccccccllloddllccccc::::::::;;;;;;;::;;;;;;;;;;::cllodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxolllooodddddxkO0000KKKKKKKKKKKKKK00Oko:,...'',;;::ccccccccccccccllllooooddddxxxxxkkkOOOO000KKKKXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNXXXXXXXXXXXXKKKKKK00000OOkkkxxxxddddxxxkOklcdxdddddlc::cccccccccccclodxdlcccccc:::::::;;:;;;;;;;;;;;;;;;;;;;;:cloodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdooooddxxxkkOO000KKKKKKKKKKKK00K000Okdc,...'',,;;:cccccccccccccccccllllloodddxxxkkkOO000KKKKXXXXXXXXNNNNNNNNNNNNNNNNWWNNNNNNNNXXXXXXXXXXXXXKKKKKKK00000OOOkkkkxxxxxxxkkOOdldxdddddddlccccccccccccllodxdlccccc::::;;;;;::;;;;;;;;;;;;;;;;;;;;;:ccloxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdddddxkkOO00000K0KKKKKKKKKK0K000000Oxdc,...',,,,;;::cccccccccccccccllloooddxxkkOOOO0000KKKKKKKKXXXXXNNNNNNNNNNNNNNNNNNNNNNNNNNNXNNXXXXXXXXKKKKKKK000000OOOOkkkkkkkkkxkkkkxodxxxxxxxxxdlccllccccccllodddlcccccc::::::::::;;;;;;;;;;;;;;;::;;;;;;:codxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkkOOO00K00KKKKKKKKKKKK00K00000OOxdc,..''',,,;;::cccccccccclllllooodxxkkOOOO000000000KKKKKKKXXXXNNNNNNNNNWWWWNNNNNNNNXXXNXXXXNNNNNXXXXKKKKKKK000000OOOOOOkkkkkxkkxxxkkddxxxxxxxxxxxxdollllcccccllooolccccccc:::::::::;;;;;;;;;;;;;;;;::;;,,;;:ldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkkOOOO000000KKKKKKKK000000000000Okxoc'..''',,,;;::cccccclllllooodddxkkOOO0000000000KKKKKKXXXXXXNNNNNNNWNNNWWNNNNXXXXXXXKXXXXXXXXXXXXXXXKKKKKKK0000000OOOOOOkkkxxxxxxxxxxdxxxxxxxxxxxxxxdollllcccclllolcccccccc::::::::::::;;;;;;;;;;;;;::;;;;;:cdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkOOOO00000000KKKKKKK0000000000000Okxo:'.''',,,;;:::ccclllooooodddxxkkOOOO000000000KKKKXXXXXXXXXXXNNNNNNNNNNNNNXXXXKKKKKKKK00KKKKKKKKKKKKKKKKKKKKK0000000OOOkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxdolllcccllllllccccccc:::::::::;;;;;;;;;;;;;;;;;::;;;;:cdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkOO00000000000KKKKKKKKK0000000000OOkxo:'.''',,,;;::cclllooooddddxxxkkkkOOOO0000KKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXKK000OOOO000000K0000KKKKKKKKKKKKKK000000OOOkkkkxxxxxxxxxkkxxxxxxxxxxxxxxxxxxdollllccllllcccccccccc:::::::;;;;;;;;;;;;;;;;:::ccloodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkOO0000000000000000K00KK000000000OOkkxl;,'''',,;;::cclloooooddddxxxxxkkkkOOOO000KKKKKKKKXXXXXKKKKKKKKKKKKKKKKKKKKKK0000OOOOO00000KK0000000K000KKKK000000OOOOkkkkkxxxxxxxxxkkxxxxxxxxxxxxxxxxxxxxddolccclccccccccccc:::::::::;;;;;;;;;;;;;;;::clodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkOO000000000000000000000000000000OOOkdl;;,,,,,,;;::ccloooooodddddxxxxxxxkkOOOOO0000000KKKKKKKKKKKKKKKKKK0KKKKKKKK0000KKKK0000KKKKKKKK000000000000000000OOOOOkkkkkkxxxxxxxxkkxxxxxxxxxxxxxxxxxxxxxxxollcccccccccccc:::::::::::::;;;;;;;;;;;;::clloxkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkOO000000000000000000000000000000OOkxdl::;;,,,;;;::cloooooooddddddddxxxxkkkkkOOOO0000000000000000000000000KKKKKKKKKKKKXXKKKKKKKKKKKKKKKK0000000000OOOOOOOOkkkkkkkkkxxxxxxkkkxxxxxxxxxxxxxxxxxxxxxxxxdolccccccccc::::::::::::::::;;;;;;;;;;;;::ccloxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxddddoool\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkOOO000OOOOO00000000000000000000OOOkxdlc::;;;;;;;::clooooooooddddddddddxxkkkkkOOOO0000OOOOOOOOOOOOO000000KKKKKKKXXXXXXXXXXKKKKKKKKKKKKKKKK0000000OOOOOkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdocccccccc::cccc:::::::::;;;;;;;;;;;;;;;;:cloxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxddddooollllllcccc\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxddxkkOOOOOOOOOOO0000000000000000000OOOkxdolcc::;;;;;:cllloooddddddxxxxxxxxxxxxkkkkOO0000OOOOOOkkkkkkOOO0000KKKKKKKXXXXXXXXXXXKKKKKKKKKKKKKKKKK0000000OOOOOkkOkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxolccccccccc::::::::::::;;;;;;;;;;,;;;;;;:clodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxddddoooolllllcccccccccccccl\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdddxkkkOOOOOOOOOO00000000000K000000OOOkxdxdlcc::;;;;:cclloooddddxxxxkkxxxxxxxxkkkOOOOOO000OOOOOkkkOOOO0000KKKKKKKKKKXXXXXXXKKKKKKKKKKK0000000000000000OOOOOOOOOkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdlccccccc::::::::::::;;;;;;;;;;;;;;;;;;;:coxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkxxxxxxxxxddddoooolllllllccccccccccclllllllloooo\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxooodxxkkkOkkkkOOOOO00000000KK000000OOkxdxxxdocc:::;::ccclllooddxxxkkkkkkkkkkkkkkkkOOOOOOOOOOOOOOOOOO000000000KKKKKKKKKKKKKKKKKKK000000000000000000000OOOOOOkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdllccccccc:::::;;;::::;;;;;;;;;;;;;;;;;cdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkxxxxxxxdddddoooolllllccccccccccccllllllllllooooodddooooooo\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxooodxxkkkkkkkkkOOOOO00000000000000OOOkxdxxxxxolc::::::ccclloodddxxkkkkkkOOOOOkkkkkkkkkkkkkkkkkkkOOOO00000000000000000KKKKKKKKKK00000000000000000000OOOOOOkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdollccc::::::::;;:;:;;;;;;;;;;;;;;;;cdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdddddooooolllllllcccccccccccllllllllooooddddddooooooooooooodddd\nkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxooodxxkkkkkkkkkOOOOO00000000000000OOOkxdxxxxxxdlc:c:::cccclloodddxxxxkkkOOOOOkkxxxxxxxxxkxxxxxxxkkOOOOOOOOOOO000000000000000000OOkOOOOOOO00000000OOOOOkkkkkxxxxxxxxxxxdddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxolccc::::::::::::::;;;;;;;;;;::;cdxxxxxxxxxxxxxxxxxxxxxxxkxxxxkxxxxxxxxxxddddooooolllllllcccccccccccllllllllloooooodddddooooooooooooooodddxxxkkkkkkkk\nxxxxxxxkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxdoddxxkkkkkkkkkOOOOO0000000000000OOOkkxdxxxxxxxxolcc::ccllllloooodddxxxkkkOOOkkxxxddddddddddddxxxkkOOOOOOOOOOOOOOOOOOOOOO000OOkkkxxkkkkOOOOOOOOOOOOOOkkkxxxddoooodddddddoooodddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdolccc::::::::::::;;;;;;;;;;::cdxxxxxxxxxkxxxxxxxxxxxxxddddddooooollllllllccccccccccclccllllllllloooodddddddooooooooooooodddddxxxxkkkkkkkkkkkkkkkkkk\nllllooooooddddddddxxxxxxxxkkkkkkkkxkkkxdddxxxkkkkkkkkkOOOOOOO00000000000OOkkxdxxxxxxxxxxdocc:clllllllllooooddxxxxkkkkkxxddoooooooooddxxxkkkkkkkkkkOOOOOkkOOOOOOOOOOOkkkxxxxxxxkkkkkkOOOOOkkkkxxxdddoollooooooooollooodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdolc::::::::::::::;;;;;;;;:coxxxxxxxxddddoooooooollllllllcccccccccccclclllllllllllooooddddddooooooooooooooooddddxxxkkkkkkkkkkkkkkkkkkkkkkkkkkxxxdd\nllllllcccclllllllllllooooooooddddddddddddxxxkkkkkkkkkkOOOOOOOO00000000OOOkkkxdxxxxxxxxxxxxoccccllllllllllllooodddxxxxxddooolllllllooddxxxkkkkkkkkkkkkkkkkkkkkkkkOOOOOkkxxxxxxxkkkkkkkkkkkkxxxxdddoooolllllloooooooooodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxolc:::::::::::::;;::;;;:cloooolllllllccccccccclcclcllccllllllllloooooodddddddooooooooooooooddddddxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxddooollcccc\ndddddooooooooollllllllllcccccllllllllooddxxxxkkkkkkkkkOOOOOOOOOO000000OOOOkxdxxxxkkkkkkkkkxoccclcccccllllllllllooooooooolllllcccclloddxxxxkkkkkkkkkkkkkkkkkkkkkkkOOOOOkkkkkkkkkkkkkOOkkkkkxxxdddddoooolllllloooooodddxkkxxxkkxxkkxkkkkxxxxxxxxxxxxxxxxxddddddddddoolcccc::::::::::;;;;;;:cccccccccllllllllllloooooooooodddddddddoooooooooooooodddddddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxddddooolllccc::::::::::\nddddddddxxxxxxxdddddooooooooooooooollodddxxxxkkkkkkkkkOOOOOOOOOOOO000OOkkkxxdoodddddddddddddlcccclcclllllllllllllllllollllllccccclooddxxxxkkkkkkkkkkxkkkkkkkkOOOOOOOOOOOkkkOOOOOOOOOOOOkkkkxxxxdddooodddoooooodddddddxxxxxxxxdddddddddoooooooooooolllllllllllllllclccllcccccccccc:;;::cllooooooooooodddddddddddddooooooooodddodddddddddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxddddoolllccc::::::::::::::::::::::\ndddddddddddddddddoooodddddddddxxddxxddddxxxxkkkkkkkkkkkOkOOOOOOOOO000OOkkkxxolcllllllllllllllcccclllllllllllooooooooooooooolllcclloodddxxxkkkkkkkkkkkkkOOOOOOOOOOOOOOOOOOOOO000000OOOOOOOOOkkkxxddooddxxxxxdddddddddollllllllllllllllllllllccccllcccllllllllllllloolooooooooooodoooooodxxxddddooooooooooodddddddddddddddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxdddoolllcccc:::::::::::::::::::::::::::::::::\nkkkkkkkkkkkkkxxxxxdddddddddddddddddddoddxxxxkkkkkkkkkkkkkkOOOOOOOOOOOOkkxxxddoooooooooooooollllccclllllllllooooooooddddxddddoolloooddddxxxxxxxkkkkkkkOOOO00O000000000000000KKK000000000OOOOOkkkkxxddddddxxxxddddddddollllllllllooooooooooooooooooooooooodddddddddddddddddddooooooooooooddddddddddddddddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxdddooolllccccc::::::::::::::::::::::::::::::::::::::::::::\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxdddxxxxkkkkOOOkkxxxkkkkkOOOOOOOkkkkxxddddxdddxxxxxxxxxdddolccllllllllooooooodddddddxxdddddddddddddxxxxxxxxkkkOOOO0000000000KK00KKKKKKKKKKKKKKK000000O0OOOOkkkxxddooddddddddddooddddddxxddxxxxxxxxxxddddddddoooddoooooooooodddddddddddddddddddxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxdddoooolllcccc::::::::::::::::::::::::::::::::::::::::::::::::::::::::c:\nxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxdddxxxkkkOOOOOkkkxxxxxkkkkkkkkkkkkkxxddddddddddddddddddddoolccllllllloooooodddddddddddddddddddddddddxxxxxkkOO0000KKKKKKKKKKKKKKKXXKKKKKKKKKKKKK0000000OOOOkkkkxxdololloooooooloddoooooooododdddddddddddddddddddddddxdxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxdddoooollllcccccc::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::ccccccc::\ncllllloooodddddxxxxxkkkkkkkkkkkkkkkkxdddxxxkkOOOOOOOkkkxxxxxkkkkkkkkxxxxdddxkkkkkkkkkkxxxxxxxxxxdllllloooooooddddddddddddddoooooododdddddxxkkOO00KKKKKKXXXXXXXXXXXXXXXXKKKKKKKKKKKKK000000OOOOOkkkkxxdolllclclllllodddddddddxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxdddddooollllccccccc::::::::::::::::::::::::::::::::::::::::::::::::::::::::c:::cccccccccccccccccc::cc::::\n::::::::::::ccccccccclllloooooddddxxdoddxxkOOOOO000OOOkxxxxxxkkkkkkxxxxddddkkkkkkkkkkkkkkkkkkkkkkdolloodddxxxxxxddddddddooooooooddoodddxkkOO00KKKKKKXXXXXXXXXXXXXXXXKKKKKKKXKKKKKKKKK00000OOOOOkkkxxxddoollccccclloxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxddddoooolllllcccccccc::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::cccccccccccccccccc::::::::::ccccccccc\n::::::::::::::::::::::::::::::::::cclodxxkkOO00000000OOkxxxxxxxkkkkxxxddodxkkkkkkkkkkkkkkkkkkkkkkkxoloddxxxkkkOOkkkkkkkxxxxxxxxxxxxxxkkOO00KKKKKKKKKKKKKXXXXXXXXXXKKKKKKKKKKKKKKKKKKK00000OOOOkkkkxxddoooollccllllokkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxddddddoooooolllllccccccc:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::ccc::ccccccccccccccccccccc::::::::cc:::cccccccccccccccc\n:::::::::::::::::::::::::::::::::::clddxkkOO000KKKKKK00OkxxxxxxkkkxxxddolllloolooooooodddddddddxxxxdoodxxkkkO000000000000000000OOkkkkOO000KKKKKKKKKKKKKKKKXXXXXXKKKKKKKKKKKKKKKKKKKKKK0000OOOOkkkxxxddoooolllllllloxxxxxxdddxdddddddddoooolllllllllllccccccccccc:::::::::::::::::c:c::::::::::::::::::::::::::::::::::::::::::::::::::::cccccccccccccccccccccccccccccccc:::::::::::cccccccccccccccccccccccccc:::\n:::::::::::::::::::::::::::::::::::clddxkO000KKKKKKKKKK0Okxxxxxxkkkxxddocc:::::::::::::::::cccccccccldxxkOOO00KKKKKKKKKXXXXXXXKK00OOOO000KKKKKKKXKKKXXXXKKKXXXXKKKKKKKKKKKKKKKKKKKKKKKKK000OOkkkxxxxxdddooollllclccccccccccc:::::cc:::::::::::::c::::::::::::::::cc::::::::::::::::::::::::::::::::::::::::::::::cc:::::::ccccc:ccccccccccccccccccccccccc::::::::ccc::ccccccccccccccccccccccccccc:::::::::::::::\nccccccccccc::::::c::::::::::::::::ccodxkO0000KKKKKKXXXKK0Okxxxxxxkkxddol:::::::::::::::::::::::::cc:ldxkOO000KKKKKKXXXXXXXXXXXXXKK00000KKKKXXXXXXXXXXXXXXXXXXXXKKKK000KKXXXXXXXXXXXXXKKKKK00Okkkxxxxxxxxxddoollllc::::::ccc::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::cc::c::::cc:ccccccccccccccccccccccccccccccccccc:::ccccccccccccccccccccccccccccccccccccc::cc::::::::::::cccccccccccc\nccccccccccccccccccccccccccccccccccccodkO00KKKKKXXXXXXXXKK0Okxxxxxkxxdolc:::::::::::::::::::::::::c::lxkOO000KKKKKKXXXXXXXXNNNNNXXXKKKKKKXXXXXXXXXXXXXXXXXXXXXKKKK00000KXXXXXNNNNXXXXXXXXKKK00OOkxxxxkkkkkkxxddoolc:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::ccccccccccccccccccccccccccccccccccccccccccc::ccccccccccccccccccccccccccccccccccccc:cc:ccc:c::::::::cccccccccllllllllllllooo\ncccccc:ccccccc::cccccccccccccccccccloxO0KKKKKXXXXXXXXXXXKKOkkkkkkkxxdoccc:::::::c::c:::::::::::ccc:lxOOO00KKKKKKKXXXXXXXXXXNNNNXXXKKKXXXXXXXXXXXXXXXXNNNNNNNXXXXK0OO0KKXXXXNNNNNNXXXXXXXXKKK00OOkkkkOOOOkkkkxxddocc:::::::::::::c::::::::::::::::c::::::::cc::cccccccccccccccccccccccccccccccccccccccc:ccccccccccccccccccccccccccccccccccccccccccccccccccccc:cc:::c::::::::ccccccccclllclllllllloooooooooooooodd\ncccccccccccccccccccccccccccccccccccldkO00KKKKXXXXXXXXXXXXK0kkkkkkkxxolccccccccccccccccccccccccccccokO0000KKKKKKKXXXXXXXXXXXXNNXXXXKKKKKKXXXXXXXXXXXXXXNNNNNNNNNXXXXXXXXXXXXXNNNNNNNXXXXXXXKKK00OOkkOOOOOOOOkkkxxoccccccccc:ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc::cccccccccccccccccccccccccccccccccccccclcccccccccccccc::cc::c:::cccc::ccccccccccclllllllllllllooooooooooooooddddddddddddddd\nccccccccccclccllcccllcccccccccccccloxkO000KKKKXXXXXXXXXXXKK0OOOOOkkxocccccccccccccccccccccccccccldkO0000KKKKKKKKXXXXXXXXXXXXXXXXXKKKKKKKKKKKKXXXXXXXXXXXXXNNNXXXXK0OOOO0KXXXXXXXXXXXXXXXXKKKK000OOOO000000OOOkkkdlcccccccccccccccccccccccccccccccccccccccc:cccccccccccccccccccccccccccccccccccccccccllcccccccccccccccccccccccccccccccccccccccc::cccccccclccllllllllloooooooooooooodddddddddddddddddddddxxxxxxxxx\ncccccccccccccccccccccccccccccclcclloxkOO00KKKKXXXXNNXXXXXXXKK0000OOxlcccccccccccccccccccccccccccok0000KKKKKKKKKKXXXXXXXXXXXXXXXXXKKK0KKKKKKKKKKKKKKKXXXXXXXXXXXXXNXOddxkOKXXXXXXXXXXKXXXKKKKK000OOO0000000OOOOOOxocccccccccccccccccccccc:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclclllllllllllloooooooooooodddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nllllllllllcccccccccccccccccccccccclooxkO000KKKXXXXXXXXXXXXXXXXXXK0Odlllllcccccccccccccccccccccldk0000KKKKKKKKKXXXXXXXXXXXXXXXXXXXKKKK00KKKK0000KKKKKKKKKKXXXXXNNNNNXKKXNNNNXXXXKKKKKKKKKKKKKK000OOO0000000OOOOOOkdlcccccccclcccccccccccccccccccccccccccclccccccclllcccccccccccccccccccccccccccccccccccccccccccccccllllcclllllllllloooooooooooooooooddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxk\nddddddddoooooollolllllllllllllllllllloxkO00KKKKKXXXXXXXXXXXXNNXXK0OdlllllccllccllllllllllllllldO00KKKKKKKXXXXXXXXXXXXXXXXNNNNNXXXXKKKKKK000000000KKKKKKKKKKXXXXXNNNNNNNNNNXXXKKKKKKKKKKKKKKK000OOOO0000000OOOOOOOkolllllllcllllcclllccclcccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllloooooooooodddooodddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkxxxxxkkkkkkkkkkkkkkkkk\nkkxxxxxxxxxxxxxxxxxxdddddddddddoooollldxkO000KKKXXXXXXXXXXXXXXKKKK0dllllllllllllllllllllllllldOO00KKKKKKXXXXXXXXXXXXXNXXNNNNNNNXXXXKKKKK000000000000KKKKKKKKKKXXXXXNNNXXXXXKKKKKKK0KKKKKK00000OOOOO00000000OOOOOkkdlccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllloooooooooooooooddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkxxxkkkkkxkkkkxxkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkxkxkxxxxxxxxxxxxdollodxO0000KKKXXXXXXXXXXXXXXKKK0xoooooooollollllllllllllldkO000000KKKKXXXXXXXXNNNNNNNNNNNNNXXXXXXKKKKK00000000000000000KKKKKKXXXXXXXXXKKKKKKK0000000000000OOOOOO00K00000OOOOOkkxolllllllllllllllllllllllllllllllllllloooooooooooooooooooooddddddddddddddddddddddddxdddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkxxxxxkkxxkkkkkkxkkkkkkkkkxxxxkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxdooodxkOO000KKKXXXXXXXXXXXXXXKKKOxxxxxxxxddddddddddddddodxkO0000000KKKKXXXXXXXXXNNNNNNNNNNNXXXXXXXKKKKK000000000000000000KKKKKKKKKKKKKKKKK0000000000000OOOOOOOOO00KK0000OOOOOOkkdoooooooooooooooooooodddddddddddddddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxdoodxxkkkO000KKKXXXXXXXXXXXXXXKK0OkkkkkkkkxkkxxxxxxxxxxxxkkOOO00000000KKKKKKXXXXXXXXNNNNNNXXXXXXXKKKKKK0000000000000000000000000KKKKKK0000000OOOOOO0OOOOOOOOOOO00KKKK00000OOOOOkxxxxdddddxxxxdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkkkkkxxkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkddddxxxkkkOO000KKXXXXXXXXXXXXXXXKKOkkkkkkkkkkkkkkkkkkkkkkxkkkOOOOOO000000000KKKKKXXXXXXXXXXXXXXKKKKKKKKKK0000000000000000000000000KK000000000OOOOOOOOOOOOOOOOOOO00KKKKK000000OOOkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdddxxkkkOOO0000KKKKKXXXXXXXXXXXXXK0kkkkkkkkkkkkkkkkkkkkkxxxkkkkkkkOOOOOOOOOO000KKKKKKKKKXXXXXKKKKKKKKKKKKKKKK00000000000000000000000000000OOOOOOOOOOOOOOOOOOOOOO0KKKKKKK000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxdd\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxddxkkkOOOO0000KKKKKKXXXXXXXXXXXXK0kkkkkkkkkkkkkkkkkkkkkxxxxxkkkkkkkOOOOOOOOOOO0000KKKKKKXXXKKKKKKKKKKKKKKKKK0000000000000OO00000000000000OOOOOOOOOOOOOOOOOOOOO000KKKKKK0000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxdddooooooooooo\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxddxkkOOOO00000KKKKKXXXKKXXXXXXXXXKOkkkkkkkkkkkkkkkkkkkkxddxxxkkkkkkkkkkkkkkkkOOOO00000KKKKKKKK000000000K00000000000000000O00000000000000OOOOOOOOOOOOOOOOOOO000000KKKK000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxdddooooooooooooooooddddxxxx\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxdxxkkOOO000000KKKKKKKKXKKXXXXXXXXK0OkkkkkkkkkkkkkkkkkkkxxxxxkkkkkkkkkkkkkkkkkkkkkOOOOOO000000000000000000000000000000000000000000000000OOOOOOOOOOOOOOOOOOO000000KKKK0000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxddddoooooooooooooooooddddxxxxxxxxxxkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdddxkkOOO0000KKKKKKKXXXXKKKKXXXXXXK0OkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkxxxdxxxxxxkkkOOOOOOOOOOOO00000000000000OO0000000000000000OOOOOOOOOOOOOOOOOOOO00000000KKK0000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxddddddooooooddooooooooooddddxxxxxxxxxxxxkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdodxkkOOOOOO000KKKKXXXXXXKKKKKXXKKKK0kkkkkkkkkkkkkkkkkkkkxkkkkOOOkkkkkkkkkkkkkkxxxdddodddddxxxxkkkOOOOOO00OOOO0OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO00000000000000000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxddddddddooooodddddddddddddddddddxxxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkxdodxxkkOOOOO0000KKKXXXXXKKKKKKKKKKKK0OkkkkkkkkkkkkkkkkkkxxkkOOOOOOOOOOOkkkkkkkkkkkxxdoooooddxxxxxkkkkkOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO000000000000000000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkxxxxxxxxxxxxddddddddoooodddddddddddddddddddddxxxxxxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nddddddddddddddddddddxxxxxxxxxxxxxxdoddxkOOOOOO0000KKKKXXXKKKKKKKKKKKKK0OkkkkkkkkkkkkkkkkkkkkOOOO000000000OOOkkxxxxxxxxddooodddxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkOOOOOOOOOOOOOkkOOOOOOOOOOOOO00000000OOOOOOO0000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxkxxxxxxxxxxxxxdddddddddddddddddddddddddddddddddddxxxxxxxxxxxxxxxkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nxxxxxxxxxxxxxxxdddddddddddddddxdddooodxkOOOOOOO0000KKKKKKKKKKKKKKKKKKK0OkkkkkkkkkkkkkkkkkkkOOOO000000000000OOOkkxxxdddddddddddxxxkkxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOOOOOOOO0000OOOOOOOO00000000000OOOkxkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxddddddddddddddddddddddddddddddddddddddddddxxxxxxxxxxxxxxxkxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx\nkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxxdoodxkkOOO0OO000000KKKKKKKKKKKKKKKK00kdddddddddddddxxxxkOOO00000000000000000000OOkkxxxxxxxxxxddxkkxxxxxxxxxxxxxkkkkkxxkxxxxkkkkxxxkkkkkkkkkkkkkkkkkkkOOOOOOOOOOkkkkOO0000000000OOOkkxxxxxxxxdxxxxdddddddddddddddddddddddddddddddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxddddoooolloo\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdooodxkOOOOOO000000KKKKKKKKKKKKKKK000kxxxxdddddddddddxkkOOO0000000000000000KKKKKK000OOOOOkkkxxddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkxxkkkkkkkkOOOOOOOkkkkkkOO000000000OOOkkxxdddddddddddddddddddddddddddddxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxddooooollllllloooodddxxx\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxolodxkkOOOO0000000KKKKKKKKKKKKKKK000OkkkkkkkkxkxxkxxxkkOOO0000000000000KKKKKKKKKKKKKKKK000OkxxddddxxddxxddxxxxxxddddddddxddddddxxxxxdddxxxxxxxkkkkkkkkkkkkkkkxxxkkkOOOOOOOOOOkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxdddooooooolllloooooodddxxxxkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxooodxxkkOOO0000000KKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkOOO00000000000K0000KKKKKKKKKKKKKKKKK0Okxddddddddddddddddddddddddddddddddddddddddddddxxxxxkkkkkkkkkkkkkxxxkkxxxkkkkkkxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxddddooooooooooolooooooodddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdooodxxkOOO000000KKKKKXXXXKKKKKK000OkkkkkkkkkkkkkkkkkkkOOO0000000000K00000000KKKKKKKKKKKKKKK0Okddooooooooooodddddddddddddddddddddddddddddddddddxxxxxxkkkkkkkkxxxxxdoooooddxxxxxkkxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxdddddoooooooooooooooooddddxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\ndxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkdoooodxkkOOO0000KKKKXXXXXXXKKKKK00OOkkkkkkkkkkkkkkxkkkkOOO000000000KKKKK0000000KKKKKKKKKKKKKK0Okdooooooodoooooddoooodddddddoooooooooooooooooddddddxxxxxxxxxxxxxxxdollllodxkkkkkxxddxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxddddddoooooooollooooooooddddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nddddddddddddddddddddddddxxxxxxkkkkkxoooodxxkkOOO000KKKKXXXXXXXKKKKK00OkkkkkkkkkkkkkkkxxkkOOOO000000000KKKKKK00000KKKKKKKKKKKKKKKK0Okddooooooooooooooooooooooooddoooooooooooooooooooddddddxxxxxxdddddollloodxxxxxddddddxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxddddddoooooooooooolloooooooooddddxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkxxxxxxxddddddddddddddddooooddxxkkOO0000KKKKXXXKKKKKKKK00OkkkkkkkkkkkkkkkxxkkOOOO0000000000KKK0000KKKKKXXKKKKK000KKKKK00kxdoooooooooooooooolooooodkOOOOOkkxoooooooooooooooodddddddddddoolllodddddddddxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxdddddddddooooooooooooooooooooooooooodddddxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdoooodxxkkkOO0000KKKKKKKKKKKKKK0OxddddddddddddddddxkkkOOOO0000000000000000KKKKXXXXXXXXKKKKKKKKK00OxooooooolllllllllloodxkkxO00000kkxdoooooooooooloooooooooooooooodxkkkkkkkkkkkOOOOkxxxdddddddddddddoooooooooooooooooooooooooooooooooddddddddxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxoooodxxxkkkOOO000KKKKKKKKKKKKK00kkkkkkxxxxxxxxxxdxxkkOOOOO0000000000000000KKKKXXXXXXXXKKKKKKK0000kxoloollllllllllooodxO00kxdodddkkO0Okxolooooollllllllloooooooxk000000O00000000O0Oxdoooooooddddddddddddxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdlooddxxxkkkkOO00KKKKKKKKKKKK00OkkkkkkkkkkkkkkOkxxkkkOOOOO000000000000000KKKKKKKKKKKKKXXKXXKK0000OkxolllllllllloodxkxdxkOkdlcccldkO0OOOxdoooollllllclllooooodxO000000000000KKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxoloddxxkkkkkkOO000KKKKKKKKKK00OkkkkkkkkkkkkkkkkxxkkkOOOOOOO000000000000KK00KKKKKKKKKKKKKXXXXK0OkkOkxdlccccloddxxdoodxxk0KKKkddO0KK0OkxxxddoolllllllllllloodxO0000000000KKKKKK0000Okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdloodxxkkkkkkOOO00KKKKKKKKKK00OkkkkkkkkkkkkkkkkkkkkkkOOOOOO000000000000000KKKKKKKKK0KKKKKXXXXK0kxkkkkxolcclodxkkkkkkkO0OkkkkxxO000kdodkkkxoollllllllllloodxO0000KKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxooodxkkkkkOOOOOO000KKKKKKKK0OOkkkkkkkkkkkkkkkkkkOOkkkkOOO0000000000000000KKKKKKKKKK000KKKKKXXXKkddxkxxdlclllll::ododxxdolllllodddxddxdodooollllllllllloxkOO000KKKKKKKKKKKKKKK0000Okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdlllodkkkOOOOOOOO000KKKKKKK0OOkkkkkkkkkkkkkkkkkOOOOkkkOOO0000000000000000KKKKKKKKKK00KKKKKKKKXXKOxddddddoloooolloolllcccccccclllloocloodxdollllllllodxkOOO0000KKKKKKKKKKKKKKK0000Okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkoloodkkOOO00000000KKKKKKKK0OkkkkkkkkkkkkkkkkkOOOOOkkkOOO0000000000000000000KKKKKKKKKKKKKKKKKXXXXKOdooooolclloolc:ccccc::;;;::ccccllooolollccclllodxkOOO00000KKKKKKKKKKKKKKKKK000Okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOxloodxkO000KKKK00KKKKKKKXK0OkkkkkkkkkkkkkkkkkOOOOOkkkOOOO000000000000000000KKKKKKKKKKKKKKKKKKKXKKK0kolllccccccc:::cc:;,,,,,,,:ccclcccccclcllodxxkOOOO0000KKKKKKKKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkdoodxkOO00KKKKKKKKKKKXXXK0OkkkkkkkkkkkkkkkkkkkkkkkkkkOOOO0000000000000000000KKKKKKKKKKKKKKKKKKKKKKKOdlccccccccc:::;;,;loxxo:;::ccccc::clodxkkOkkkOO000KKKXXXKKKKKKKKKKKKKKK0000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxx\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxoodxxkO00KKKKKKKKKKKKXXXKOkkkkkkkkkkkkkxxkkkkkkkkkkkkOOOO0000000000000000000KKKKKKKKKKKKKKKKKKKKKK00xl:ccccccccc:::ldOKXXK0xlc:cccc:cldxkkkkkkkkOO00KXXXXXXXXXXXKKKKKKKKK00000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxdd\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdodkkkO00KKKKKKKKKKKKXXXK0kkkkkkkkkkkkkxxxkkkkkkkkkkkkOOOO0000000000000000000KKKKKKKKKKKKKKKKKKKKKKK0kl::ccccccccclokOKXXXXXOocccccloddxxxddddkO0KKXXXXNNXXXXXXXXXXXXXKKKK0000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxddddddddddooooo\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxodkkkO00KKKKKKKKKKKKKXXXKOkkkkkkkkkkkxddxxxxkxxxxxkkkkOOOOOO00000O000000000000KKKKKKKKK00KKKKKKKKKKK0ko:;:c::clldooxO0KXXXKKkllccloodooooodkOKXXXNXXXNNNNNNXXNXXXXXXXXKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxdddddddddddddoooollllllllllooll\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdoxkkOO000KKKKKXXXKKKKXXX0OkkkkkkkkkkxdddxxxxxxxxxxxkkkOOOOOOOOOOOO000OOO00000KK00KKKKKK00KKKKKKKKKKK0Oo;,;:::ldOxldkO0XXXKKOxolllooolodxOKKKXXXNNNNNNNNNNNNNNNXXXXXXXKKKK0000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxddddddddddoodoooolllllllllllloollloooooodddddd\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkdoxkOOO00OO0KKKKKKKKK0KKXX0OkkkkkkkkkdoodddxxxxxxxxxkkkOOOOOOOOOOO00OOOOO0000000000KKKK0000K000KKKKKK00Oo;',;:okKOllxO0KKXXK00kllolloxO0KKKKXXXXXXNNNNNNNNNNNNNNNXXXXXXKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkddddddddddddddddddooooolllllllllllllloooooooooddddddddddddoooooooolo\nxxxxxxxxxxxxxxxxxxkkkkkkkkkkkOOkkkkkkkOOkkkxddkkkOOOOOOOO0000000000KKKOkkkkkkkkkdooodddddddddxxxkkkkOOOOOOOOO0OOOOO000000000000KKK000000000KKKKK000ko,..:x0XKdlodxk0KK0OO0klloxO0KKKKKXXXXXXXNNNNNNNNNNNNNNNXXXXXXXKKKK00OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkxoooolllllllllloooolooooooooodddddddddddooooooooooooooooooooddddxx\nddddddddddddddddxdxxxxxxxxxxxxxxxxxxxxxxxxxxxdddxxkkkxxxxkkkOOOOkkOO0K0OOOkkkkOkdlooooddddddddxxxkkkkOOOOOOOOOOOOOO000000000O00000000000K000000K000Oko,'d0KKKKkolloxxxkxOXKxxO000KKKKKXXXXXXXNNNNNNNNNNNNNNNXXXXXXXKKKK00OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxxxxxxxxxxxxxxxxxxxxxxddddddddddxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkdoooloooooddddddddddooooooooooooooooooooooodddddxxxkkkkkkkkkkkkkk\nlllllllllllllllloooooooodddddddddddddddddddxxxdoooddddddddddxxkOOOOkO00OkxxxxxxxolloooddddddddxxxxkkkkkkkkOOOOOOOOO0000000O0000000000000000000000000OkooO00KKX0o;::ccccoOXX0000KKKKKKKXXXXXNNNNNNNXXXNNNNNNNNXXXXXXKKKKK00Okkkxxkxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxddddddddddddddddddddddddddoooooolllllllldkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkxxdoooooooooooooooooooodddddxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nxxdddddddddoooooooooolooolllllllllllllllllloodoollooooddddodddxxkkOOkO00OxddddddollllooodddddddddxxkkkkkkkkkOOOOOOOOOO000O000000000000000000000000000OkkkkkOO0Odc,'''';dOKK000KKKKKKXXXXXXXNNNNNNXXXXXXNNNNNNXXXXXXKKKKKK0Okxxxxdddddddddddddddddddddddddddddddddoooooooollllllllllllllllllllllllloolloooooddxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkxxdooodddddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\noooooooodooodddddddddxxxxxxxxxxxxddddddoooolccccccllooodddddxxxxxxkkkkO0KOxdollllllllooodddddddddxxxxkkkkkkkkkkOOOOOOOOOOOOOOO00000000000000000000000Oxxddodddddo:;,,:lxkOOOO0KKKXXXXXXXXXXXNNNNNXXXXXXXXXXNNXXXXXXXXXKKK00koooooooollllllllllllllllllllllllllllollloooolloooooooooodddddddddddddddddddddxkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nxxxxxxxxddddddddddoodddddooooooooooooooooool:::::cccllloddddxxkkkkkkOOOO0KXKK0kxollllooodddddxddxxxxxxkkkkkkkkkkOOOOOOOOOOOOOO0000000000000000000000Oxooolcccclll:;;;clooddddk0KKXXXXXXXXXXXXNNNNXXXXXXXXXXXNXXXXXXXXXXKKK0Odoooooooooooooooddoddddddddddddxxddddddddddddoooooooooooooooooddddddddddddddddxkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkxxxxxxxdddddddddddoc::::::::cclooooodxkkOOO00O00KKKXXK0xollloooddxxxxxxxxxxxkkkxkkkkkkkOOOOOOOOOOOOOO00000000000OOOO00000OOxccllc:ccccc:::::ccccllok0KKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKK0Oxdddddddddoodoooooooooooddoodddddoooodddoddddddddddddddxxxxxxkkkkkkkkkkkkkkkxkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkoc::;;;;;:::cllcccodxkkOO00000KKKKKXK0xoloooddxxxxxxxxxxxkkkkkkkkkkkkkkOOOOOOOOOOOO0000000000OOOOOOOOOOOxc,;c:::cccc:::::::ccclokO0KKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKK0kdxdddddddddddddxxdxxxxxxxxxkkkkkkkkkkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxc::;;:;;;:::clllcclodxkOOOO000KKKKKKKKOdoooddxxxxxkkkkkkkkkkkkkkkkkkkkkkkkkOOkOOOOO000000000OOOOOOOOOOkxl,',:::::::::::::ccccloxO0KKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKKK0OOOOOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkl:::;;;;;::::ccloollodxxkkOO000KKKKKKKKKkdoddxxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOOOOO00000000OOOkkkOOkkkxo:'.....''',;:::ccc::cdxO0KKKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKKK0Okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc::;;;;;;;;:::ccllcclodxxkOO0000000K00KK0kdddxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOOOOO000000000OOkkkkkkkkxoc;.     ...',,;,;,,:oxkO0000KKKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKKKKOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc::;;;;;;;;;;:::ccclllodxxxkOOOOO0000000KK0xdxxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOOOOO000000000OOOOkkkkkkxoc;'     ...'''',,,:odxkOO0000KKKKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKXKKKOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc::;;;;;;;;;;::::::cllooddxxxkkOOO000OO00KKKOxxxkkxkkkkkkkkkkkkkkkkkkkkkkkkkkOOOOOOO000000000OOOkkkkkxdol:,.   ..'',,,,;;:ldxkkOO000KKKKKKKKKKKKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKKK0OkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdcc::;;;;;;;;;;:::::::looodddddxkOOO0OO0OO00O0OxxxxxkkkkkkkkkkxxkkkkkkkkkkkkkkkkkOOOOOOOO000000OOkkkkxxdol:,.   ..',,,;;;:lddxxkOO0000KKKKKKKKKKKKXXXKXXXXXXXXXXXXXXXXXXXXXXXXXKKKK0OkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxlc::;;;;;;;;;;;:::::::cloooooodxkOOOO0OkkkkkOOkxxxxkkkkkkkkkkxxxkkkxxxkkkkkkkkkkkOOOOOOOOO000OOOkkkxxddolc;.   ..',,;:::lodxxxkOOO00000000KKKKKKKKKKKKKKKKKKKKKKKXXXXXXXXXXXXXXXXXK0Okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxoc::;;;;;;;;;;;:::::::::llooolloxxkkOOdloxxkO0OkxxkkkkkkkkkkxxxxxxxxxxxxxxxkkkkkkOOOOOOOOOO00OOOkxxxxddolc:'  ..'',;;::clodxxxkkOOO0000000KKKKKKKKKKKKKKKKKKKKKKKKXXXXXXXXXXXXXXXXKK0OkkkkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdl:::;;;;;;;;;;;;::::::;:clddddooddxOOdcldxxkO0OkkkkkkkkkkkkxxxxxxxxxxxxxxxxkkkkkOOkkOOOOOOO00OOkxxxdddolc:'   .'',;;:cloddxxxkkOOOO0000000K00KKK00KKKKKKKKKKKKKKKXXXXXXXXXXXXXXXXKKK0OkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkoc::;;;;;;;;;;;;;;::cccccloddoooddxkOkolodxkO00OkkkkOkkkkkkxxxxxxxxxxxxxxxxxxkkkkkkkkOOOOOO0OOOkkxddddolc:,. ..',;;:cllodddxxkkkOOOO0000000000000000KKKKKKKKKKKKKXXXXXXXXXXXXXXXXXXKK0OkkkkkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxoc::;;;;;;;;;;;;:c::ccc::::cllodxkOO0kocodxkO00OkkkkkkkkxxxxxxxxxxxxxxxxxxxkkkkkkkkkOOOOOOOOOOOkxxddoolc:,.  .',;;:cllodddxxxkkkOOOO000000000000000KKKKKKKKKKKKXXXXXXXXXXXXXXXXXXXXK0OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxl:::;;;;;;;;;;;;::;;;;;;;::ldkkkkOKKKOocldxkO00OkkkkkkxxxxxxxxxxxxxxxxxxxxkkkkkkkkOOOOOOOOOOOOkxxddoolc:,.  .',;:ccllloddddxxkkkOOOOO00000000000000KKKKKKKKKKKKKKXXXXXXXXXXXXXXXXXKK0OkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc:::;;;;;;;;;;;::::::::::::ldkOOOO000OocdkkO000OkxxxxxxxxxxxxxxxxxxxxxxxxxxxkkkkOOOOOOOOOOOOOkxxddoolc:,.  ..,;:cclllodddxxxxxkOOOOOOO000000000000KKKKKKKKKKKKKKKKXXXXXXXXXXXXXXXKKK0OOOkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkOko:::;;;;;;;;;;;:cccccc::::::coxxxxkkO0xcokkxxkkkkxxxxxxxxddxxxdxxxxxxxkkxxxxxkkkkOOOOOOOOOOOkkxxddoolc:,.  ..';::cllloodddxxxxkkkOOOOOOOOOO00000000KKKKKKKKKKKKKKKKXXXXXXXXXXXXXXKKK0OOOOkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc::::::;;;;;;;;:lloolc:;::;;:loxxxkkOkccoxxolodxxxdddddddxxxxxxxxxxxxxkkkkkkkkkkkkkOOOOOOOOkkxxdoooll:;.  ..';::clllloodddxxxxkkkkkOOOOOOOOO0000000000KKKKKKKKKKKKKXXXXXXXXXXXXXXKKK0OOkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkdc::::::;;;;;;;;:cccclc;;;;;;;:ldxxkOOkl:loxxxxxxxxdddddddxxxxddddxxxxxxkkkkkkkkkkkkkkkOOkkkkkxxdoollc:;.  ..,;::ccllloooddddxxxxkkkkkkOOOOOOO0000000000KKKKKKKKKKKKKKKXXXXXXXXXXXXKK00OkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkxxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc::::::;;;;;;;;;:::::;;;,,,;:coxkOO0Oo;:lodxddxxxddddddddxxdddddxxxxxxxkkkkkkkkkkkkkkkkkkkkxxddoollc:;.  ..';::cccllloodddddxxxxxkkkkkOOOOOO0000000000000000KKKKKKKKKKKKXXXXXXXXXKKK0OOOOkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxdolc::::;;;;;;;;;;;;;;,'..,;:oxOO00KOl;:codxkOOxdxdddddddddddddxxxxxxxkkkkkkkkkkkkkkkkkkkkxxddoollc:;'....',::cccllllooodddddxxxxxkkkkkkkOOOOO0000000000000KKKKKKKKKKKKKKKKXXXXXKKK00OOOkOOkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkOOkkkkkkkkkkkkkkkkOOkkkxkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxoc:::;;;;;;;;;:::;;'..';cldkOO00Kx:;ccoxkOOkxdddddddddddddddxxxxxxxxxkkkkkkkkkkkkkkxxxxxddoolcc::;'...',;:ccclllllooodddddxxxxxxxxxkkkOOOOO0000000000000KKKKKKKKKKKKXXKKXKKKKKKK0OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkxxkkkkkkkkkkkkkkkkkkkkkkkOOOkkkkkkkkOkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkxdolc:::;;;:::ccc:,...,:codxOO000l,;:codxxdolodddddddddddddddxxxxxxxxkxxxxxkkkkkkkxxxxxddollcc:coc''',,;::cclllllooooodddddxxxxxxxxkkkkOOO00OOOOO0000000KKKKKKKKKKXXXKKXKKKKKKK00OOOOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkOkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxl:::;;::::cc:,....;:cldkkO00x;',,;:c:;:clooooooddddddddddxxxxxxxxxxxkkkkkkkkxxxxxxdoollcc:cxkl,,,,;:::ccccllllooooddddddxxxxxxxkkkkOOOOOOOOO00000000KKKKKKKKKXXKKXXXKKKKK000OOOkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkxkkkOkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxl:::;:::::c:;,'..';:clodkOOOd:;'....';clooooooddddddddddxxxxxxxxxxxkkkkkkkxxxxxxxddoolcc:lkOxl;,;;:::ccccllllllooooddddddxxxxxkkkkOOOOOOO00000000000KKKKKKKKKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxxkkkkkkkkkkkkkkkkkkkkkkkOOOkkkkkkkkOkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOxoc::::::::::;,..',;:clldxkkOOOkdl,',:clooooooooodddddddxxxxxxxxxxxxkkkkxxxxxxxxxddoolc::dOkkxc;;;:::cccccllllloooooodddddxxxxxkkkkOOOOOOOOO000000000KKKKKKKKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkdl:::::;:::;,''.,;;:codxkkxkOO00x:,:cllloooooooooooddddxxxxxxxxxxxkkkxxxxxxxxxdddolcc;cxOkkkxc;;::::cccccclllllloooodddddxxxxxkkkkOOOOOOOOO00000000000KKKKKKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkocc::::::;;;,,;:::clooodooodddl;,;:cllloooooooooddddddddddxxxxxxxkkxxxxxxxxxxddooc::okkkkkkxl::::ccccccccccllllooooodddddxxxkkkOOOOOOOOOO0000000000KKKKKKKKKKKKKKKKKKKK000OkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOkkkkkxkkkkkOkkkkkkkOkkkkkkkkkkOOOkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkOOOkkkkkkkkkkkkkkkOOOkkkkkOkkkkkkkkkkkkkkkkkkkOkkxxdl::::;;;,;cc:;;;::::::::;;,,;::cclllooooooooodddddddddxxxxxxxxxxxxxxxxxxxddoc:cxkkkkkkkxl:::ccccccccccclllloooooddddxxxxkkOOOkkkOOOO00000000000KKKKKKKKKKKKKKKKKKKK00OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkOkkkkkxkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkOkkkkkOkkkkkkkOOkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxl:::::;;;:c::;;;;;;;,'.'',;;::ccllllloollooooooooodddddxxxxxxxxxxxxxxxxxxdoc:okkkkkkkkOxl:ccccccccccccllllllloooooddxxxkkOOOkkOOOOOOOO00000000KKKKKKKKKKKKKKKKKKK000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkOOkkkkkkkkkkkkkkkkkkkOkkkkkkkkkOOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkOkkkkkOOOOkkkkOkkkkkkkkkkOOOkkkkOOOkkkkkkkkkkkkkkkkkkkkkkkkkdl::::::::::;;,,,,,,'...',;;;:ccclllllllllooooooooodddddddxxxxxxxxxxxxkxxdoccdOkkkkkkkkkxlcccccccccccccllllllooooodddxxkkkOOOOOOOOOOOO00000000000KKKKKKKKKKKKKKK0000OOOOkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkOOkkkkkOkkkkkkkkkkkkkkOOkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkOOOOOkkkOOOOkkkkOOOOkkkOOOkkOOkkkkkOOkkkkkkkkOOkkkkOkkkkkkkkkOOOkkkkOkkkxdoc:::::::::;;;;;;,,,,;;;;::ccllllllllllllooooooodddddddddxxxddxxxkkkxxoclkOkkkkkkkkkOkoccccccccccccclllllllloodddxxkkkOOOOOOOO0OO0000000000000KKKKKKKKKKKKKK00000OOOkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkkkkOkkkkkkkkkOOkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nOkkkkkOOOkkkkOOkkkkkkkOOkkkOOOOOkkkkkkkkOkkkkkkOOOOOOOOOOOOOOkkkOkkOOkkkkkkkkkOkkxdolc:::cllllc::;;;::;;:::cccccllllllllooooooooddddddddxxxxxxxxkkkkxocdkkkkkkkOkkOkkkdcccccc::ccccccllllllooooddxxkkkOOOOOOO0000000000000000KKKKKKKKKKKKKK00000OOOkkOOOOOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkOOOkkkkkkkkkkkkkkkkkkkOOOOOOOOkkkkkkOOOOOkkkkkkOOOOkkkkkOOOOkkkkOOkkkkkkkkkkkkkkkxxxxkkkkxoc:::::::;:::ccccccllllllllooooooooooddddddddxxxxkkkkkkdlxOkkkkkkkkkOkkkkxlcccccc:ccccccclllllooooddxxkkkkOOOOO00000000000000000KKKKKKKKKKKK0000000OOkOOkkkkkkkOOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkOOOOOOkkkOOOOOOOkkkkOOOOkkkkkkkOkkkkkOOOkkkkkOOOkkkkkkkOkkOkkkkdlc::c:::;:::::cccclllllllllllllloooooodddddddxxxkkkkkkdoxOkkkkkkkkkkkkkOkxocccccccccccccclllloooooddxxkkkkkOOO0000000000000000KKK00KKKKKKKKK000000OOOOOkkkOkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkOOOkkkkkkkkkkkkkkkkkkkkkkOOkkkkkkkkOOOOOOkkkOOOkkkkkkkkkkOkkkOkkkkkkkkkkkkkkkOkkkOkkkkkxlccc:::::::::cccccclllllllllllllllloooooodddddxxkkkkkkxdkkkkkkkkkkkkkOOOkkkdlccccccccccccccllllloooddxxkkkkkOOOO00000000000KKKKK0KKKKKKKKKKK0000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOkkkkkxkkkkkkkOOkkkkkkkkkkkOOOkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkOOOkkkkkkkkkkkkkkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkdccc:::::::::cccccccclllclllllllllllooooodddddxxxkkkkkxxkkkkkkkkkkkkkkkOkkkkxoccccccccccccccllllloooddxxkkkkOOOOOO00000000K0000K0KKKKKKKK0000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkOOOkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkkkkOkkkkOkkkkkkkkkkkkkkkkkkkkkkOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOOkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxocc::::::::::ccccccccccccllllllllllllooooooddxxxkkkkkkkkkkkkkkkkkkkkkkOkkkkkxolclcccccccccccllllloooddxxxkkkkkOOO0000000000KKKKKKKKKKK000000000000OOOkkkkkkkkkkkkkkkkkkkkkkOOOOOkkkkkkkkkkOOkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkOOOkkkOOkkkkkkkkkkkkkkkkOkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkdlcc::::::::::cccccccccccccccclllllllllooooddxxxkkkkkxxkkkkkkkkkkkkkkkOkkkkkxkxocccccccccccccllllllooddxxxkkkkkOO000000000KKKKKKKKKK000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkOOkkkOkkkkkkkkkkkkkkkkkkkkkkkkkOkkOOOkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOOkkkkkkkkkkkkkkkkkkkkkkkoccc:::::::::cc::ccccccccccccccccllllllloooddxxxxxkkxxkkkOkkkkkkkkOkkOkkkkkxkkxdllccccccc:ccclllllloodddxxkkkkOOO00000000KKKKKKKKK0000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkkkOOkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkOkkkkkkkkkkkkkkkkkkkkkkkkdcccc::::::::ccc:cccccccccccccccccclllllloodddxxxxkkxxxkkkOOkkkOkOOOOOkkkkkxkkkkxolccccccccccccclllloodddxxkkkOOOO000000000KKKKK000000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkxkkkkOkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkkkkkkkkOOOOOOOOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkOkkOkkkkkkkkkkkkkkkkkkkkOkocccc::::::::::::::::::::ccccccccccclllloooddxxxxkkxxxkkkkkkkkkkkkOOOkxkkkxkkxkOkxolcccccccccccclllooodddxxkkkOOOO00000000KKKKKKKK00000000000000OOOOkkkkkkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkOkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkkkOOkkkkkkkOOOOOOOkkkkkkkkkkkkkkkkkOOkkkkkkkkkkkOOOkkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkxlcccc::::::::::::::::::::::::c::ccccllloooddddxxxxxxxkkkkkkkkkkkkkkOkkkkkxkkkkkOOkdlcccccccccccclllooooddxxkkOOOO00000000KKKKKKKK00000000000000OOOkkOkkkkkkkOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkxkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkOOOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\nkkkkkkkkkkkkkOOOkkkkkkkOOOOOOOOOOkkkkkkkkkkkkkkkkkOOOOOkkkkOOOOOkkkOkkkOkkkkkkkkkkkkkkkkkkkkkkkkkOkoccccc::::::::::::::::::::::::::ccccllllooddddxxxxxdxxkkkkkkkkkkkkOOkkkkkxkkkkkOOOOxllcccccccccccllloooddxxkkOOOO0000000000000KKK00000000OOOOOOOOkkkOkkkkkkkOOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOOkkkkkkxkkkkkkkkkkOkkkkkOkkkkkkkkkkkkkkkkkkOkkkkOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk\n*/\n"
  },
  {
    "path": "errors.generated.go",
    "content": "package core\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "features/dns/client.go",
    "content": "package dns\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// IPOption is an object for IP query options.\ntype IPOption struct {\n\tIPv4Enable bool\n\tIPv6Enable bool\n\tFakeEnable bool\n}\n\nfunc (opt IPOption) With(other IPOption) IPOption {\n\treturn IPOption{\n\t\tIPv4Enable: opt.IPv4Enable && other.IPv4Enable,\n\t\tIPv6Enable: opt.IPv6Enable && other.IPv6Enable,\n\t\tFakeEnable: opt.FakeEnable && other.FakeEnable,\n\t}\n}\n\nfunc (opt IPOption) IsValid() bool {\n\treturn opt.IPv4Enable || opt.IPv6Enable\n}\n\n// Client is a V2Ray feature for querying DNS information.\n//\n// v2ray:api:stable\ntype Client interface {\n\tfeatures.Feature\n\n\t// LookupIP returns IP address for the given domain. IPs may contain IPv4 and/or IPv6 addresses.\n\tLookupIP(domain string) ([]net.IP, error)\n}\n\n// IPv4Lookup is an optional feature for querying IPv4 addresses only.\n//\n// v2ray:api:beta\ntype IPv4Lookup interface {\n\tLookupIPv4(domain string) ([]net.IP, error)\n}\n\n// IPv6Lookup is an optional feature for querying IPv6 addresses only.\n//\n// v2ray:api:beta\ntype IPv6Lookup interface {\n\tLookupIPv6(domain string) ([]net.IP, error)\n}\n\n// LookupIPWithOption is a helper function for querying DNS information from a dns.Client with dns.IPOption.\n//\n// v2ray:api:beta\nfunc LookupIPWithOption(client Client, domain string, option IPOption) ([]net.IP, error) {\n\tif option.FakeEnable {\n\t\tif clientWithFakeDNS, ok := client.(ClientWithFakeDNS); ok {\n\t\t\tclient = clientWithFakeDNS.AsFakeDNSClient()\n\t\t}\n\t}\n\tif option.IPv4Enable && !option.IPv6Enable {\n\t\tif ipv4Lookup, ok := client.(IPv4Lookup); ok {\n\t\t\treturn ipv4Lookup.LookupIPv4(domain)\n\t\t} else {\n\t\t\treturn nil, errors.New(\"dns.Client doesn't implement IPv4Lookup\")\n\t\t}\n\t}\n\tif option.IPv6Enable && !option.IPv4Enable {\n\t\tif ipv6Lookup, ok := client.(IPv6Lookup); ok {\n\t\t\treturn ipv6Lookup.LookupIPv6(domain)\n\t\t} else {\n\t\t\treturn nil, errors.New(\"dns.Client doesn't implement IPv6Lookup\")\n\t\t}\n\t}\n\treturn client.LookupIP(domain)\n}\n\n// ClientType returns the type of Client interface. Can be used for implementing common.HasType.\n//\n// v2ray:api:beta\nfunc ClientType() interface{} {\n\treturn (*Client)(nil)\n}\n\n// ErrEmptyResponse indicates that DNS query succeeded but no answer was returned.\nvar ErrEmptyResponse = errors.New(\"empty response\")\n\ntype RCodeError uint16\n\nfunc (e RCodeError) Error() string {\n\treturn serial.Concat(\"rcode: \", uint16(e))\n}\n\nfunc RCodeFromError(err error) uint16 {\n\tif err == nil {\n\t\treturn 0\n\t}\n\tcause := errors.Cause(err)\n\tif r, ok := cause.(RCodeError); ok {\n\t\treturn uint16(r)\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "features/dns/fakedns.go",
    "content": "package dns\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// FakeDNSEngine is a V2Ray feature for converting between domain and fake IPs.\n//\n// v2ray:api:beta\ntype FakeDNSEngine interface {\n\tfeatures.Feature\n\n\t// GetFakeIPForDomain returns fake IP addresses for the given domain, and registers the domain with the returned IPs.\n\tGetFakeIPForDomain(domain string) []net.Address\n\n\t// GetDomainFromFakeDNS returns the bound domain name for the given fake IP.\n\tGetDomainFromFakeDNS(ip net.Address) string\n}\n\n// FakeDNSEngineRev0 adds additional APIs for FakeDNSEngine.\n//\n// v2ray:api:beta\ntype FakeDNSEngineRev0 interface {\n\tFakeDNSEngine\n\n\t// IsIPInIPPool tests whether the given IP address resides in managed fake IP pools.\n\tIsIPInIPPool(ip net.Address) bool\n\n\t// GetFakeIPForDomain3 registers and returns fake IP addresses for the given domain in IPv4 and/or IPv6.\n\tGetFakeIPForDomain3(domain string, IPv4 bool, IPv6 bool) []net.Address\n}\n\n// ClientWithFakeDNS is an optional feature for utilizing FakeDNS feature of DNS client.\n//\n// v2ray:api:beta\ntype ClientWithFakeDNS interface {\n\t// AsFakeDNSClient converts the client to dns.Client that enables FakeDNS querying option.\n\tAsFakeDNSClient() Client\n\n\t// AsFakeDNSEngine converts the client to dns.FakeDNSEngine that could serve FakeDNSEngine feature.\n\tAsFakeDNSEngine() FakeDNSEngine\n}\n\n// FakeDNSEngineType returns the type of FakeDNSEngine interface. Can be used for implementing common.HasType.\n//\n// v2ray:api:beta\nfunc FakeDNSEngineType() interface{} {\n\treturn (*FakeDNSEngine)(nil)\n}\n"
  },
  {
    "path": "features/dns/localdns/client.go",
    "content": "package localdns\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n)\n\n// Client is an implementation of dns.Client, which queries localhost for DNS.\ntype Client struct{}\n\n// Type implements common.HasType.\nfunc (*Client) Type() interface{} {\n\treturn dns.ClientType()\n}\n\n// Start implements common.Runnable.\nfunc (*Client) Start() error { return nil }\n\n// Close implements common.Closable.\nfunc (*Client) Close() error { return nil }\n\n// LookupIP implements Client.\nfunc (*Client) LookupIP(host string) ([]net.IP, error) {\n\tips, err := net.LookupIP(host)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tparsedIPs := make([]net.IP, 0, len(ips))\n\tfor _, ip := range ips {\n\t\tparsed := net.IPAddress(ip)\n\t\tif parsed != nil {\n\t\t\tparsedIPs = append(parsedIPs, parsed.IP())\n\t\t}\n\t}\n\tif len(parsedIPs) == 0 {\n\t\treturn nil, dns.ErrEmptyResponse\n\t}\n\treturn parsedIPs, nil\n}\n\n// LookupIPv4 implements IPv4Lookup.\nfunc (c *Client) LookupIPv4(host string) ([]net.IP, error) {\n\tips, err := c.LookupIP(host)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tipv4 := make([]net.IP, 0, len(ips))\n\tfor _, ip := range ips {\n\t\tif len(ip) == net.IPv4len {\n\t\t\tipv4 = append(ipv4, ip)\n\t\t}\n\t}\n\tif len(ipv4) == 0 {\n\t\treturn nil, dns.ErrEmptyResponse\n\t}\n\treturn ipv4, nil\n}\n\n// LookupIPv6 implements IPv6Lookup.\nfunc (c *Client) LookupIPv6(host string) ([]net.IP, error) {\n\tips, err := c.LookupIP(host)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tipv6 := make([]net.IP, 0, len(ips))\n\tfor _, ip := range ips {\n\t\tif len(ip) == net.IPv6len {\n\t\t\tipv6 = append(ipv6, ip)\n\t\t}\n\t}\n\tif len(ipv6) == 0 {\n\t\treturn nil, dns.ErrEmptyResponse\n\t}\n\treturn ipv6, nil\n}\n\n// New create a new dns.Client that queries localhost for DNS.\nfunc New() *Client {\n\treturn &Client{}\n}\n"
  },
  {
    "path": "features/dns/localdns/errors.generated.go",
    "content": "package localdns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "features/errors.generated.go",
    "content": "package features\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "features/extension/browser.go",
    "content": "package extension\n\nimport (\n\t\"io\"\n\t\"net/http\"\n)\n\ntype BrowserForwarder interface {\n\tDialWebsocket(url string, header http.Header) (io.ReadWriteCloser, error)\n}\n\nfunc BrowserForwarderType() interface{} {\n\treturn (*BrowserForwarder)(nil)\n}\n"
  },
  {
    "path": "features/extension/contextreceiver.go",
    "content": "package extension\n\nimport \"context\"\n\ntype ContextReceiver interface {\n\tInjectContext(ctx context.Context)\n}\n"
  },
  {
    "path": "features/extension/instance.go",
    "content": "package extension\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// InstanceManagement : unstable\ntype InstanceManagement interface {\n\tfeatures.Feature\n\tListInstance(ctx context.Context) ([]string, error)\n\tAddInstance(ctx context.Context, name string, config []byte, configType string) error\n\tStartInstance(ctx context.Context, name string) error\n\tStopInstance(ctx context.Context, name string) error\n\tUntrackInstance(ctx context.Context, name string) error\n}\n\nfunc InstanceManagementType() interface{} {\n\treturn (*InstanceManagement)(nil)\n}\n"
  },
  {
    "path": "features/extension/observatory.go",
    "content": "package extension\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\ntype Observatory interface {\n\tfeatures.Feature\n\tGetObservation(ctx context.Context) (proto.Message, error)\n}\n\nfunc ObservatoryType() interface{} {\n\treturn (*Observatory)(nil)\n}\n"
  },
  {
    "path": "features/extension/storage/storage.go",
    "content": "package storage\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\ntype ScopedPersistentStorage interface {\n\tScopedPersistentStorageEngine()\n\tPut(ctx context.Context, key []byte, value []byte) error\n\tGet(ctx context.Context, key []byte) ([]byte, error)\n\tList(ctx context.Context, keyPrefix []byte) ([][]byte, error)\n\tClear(ctx context.Context)\n\tNarrowScope(ctx context.Context, key []byte) (ScopedPersistentStorage, error)\n\tDropScope(ctx context.Context, key []byte) error\n}\n\ntype ScopedTransientStorage interface {\n\tScopedTransientStorage()\n\tPut(ctx context.Context, key string, value interface{}) error\n\tGet(ctx context.Context, key string) (interface{}, error)\n\tList(ctx context.Context, keyPrefix string) ([]string, error)\n\tClear(ctx context.Context)\n\tNarrowScope(ctx context.Context, key string) (ScopedTransientStorage, error)\n\tDropScope(ctx context.Context, key string) error\n}\n\ntype ScopedPersistentStorageService interface {\n\tScopedPersistentStorage\n\tfeatures.Feature\n}\n\nvar ScopedPersistentStorageServiceType = (*ScopedPersistentStorageService)(nil)\n\ntype TransientStorageLifecycleReceiver interface {\n\tIsTransientStorageLifecycleReceiver()\n\tcommon.Closable\n}\n"
  },
  {
    "path": "features/extension/storage.go",
    "content": "package extension\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\ntype PersistentStorageEngine interface {\n\tfeatures.Feature\n\tPersistentStorageEngine()\n\tPut(ctx context.Context, key []byte, value []byte) error\n\tGet(ctx context.Context, key []byte) ([]byte, error)\n\tList(ctx context.Context, keyPrefix []byte) ([][]byte, error)\n}\n"
  },
  {
    "path": "features/feature.go",
    "content": "package features\n\nimport \"github.com/v2fly/v2ray-core/v5/common\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\n// Feature is the interface for V2Ray features. All features must implement this interface.\n// All existing features have an implementation in app directory. These features can be replaced by third-party ones.\ntype Feature interface {\n\tcommon.HasType\n\tcommon.Runnable\n}\n\n// PrintDeprecatedFeatureWarning prints a warning for deprecated feature.\nfunc PrintDeprecatedFeatureWarning(feature string) {\n\tnewError(\"You are using a deprecated feature: \" + feature + \". Please update your config file with latest configuration format, or update your client software.\").WriteToLog()\n}\n\n// TaggedFeatures unstable\ntype TaggedFeatures interface {\n\tGetFeaturesByTag(tag string) (Feature, error)\n\tcommon.Runnable\n}\n"
  },
  {
    "path": "features/inbound/inbound.go",
    "content": "package inbound\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// Handler is the interface for handlers that process inbound connections.\n//\n// v2ray:api:stable\ntype Handler interface {\n\tcommon.Runnable\n\t// The tag of this handler.\n\tTag() string\n\n\t// Deprecated: Do not use in new code.\n\tGetRandomInboundProxy() (interface{}, net.Port, int)\n}\n\n// Manager is a feature that manages InboundHandlers.\n//\n// v2ray:api:stable\ntype Manager interface {\n\tfeatures.Feature\n\t// GetHandlers returns an InboundHandler for the given tag.\n\tGetHandler(ctx context.Context, tag string) (Handler, error)\n\t// AddHandler adds the given handler into this Manager.\n\tAddHandler(ctx context.Context, handler Handler) error\n\n\t// RemoveHandler removes a handler from Manager.\n\tRemoveHandler(ctx context.Context, tag string) error\n}\n\n// ManagerType returns the type of Manager interface. Can be used for implementing common.HasType.\n//\n// v2ray:api:stable\nfunc ManagerType() interface{} {\n\treturn (*Manager)(nil)\n}\n"
  },
  {
    "path": "features/outbound/outbound.go",
    "content": "package outbound\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\n// Handler is the interface for handlers that process outbound connections.\n//\n// v2ray:api:stable\ntype Handler interface {\n\tcommon.Runnable\n\tTag() string\n\tDispatch(ctx context.Context, link *transport.Link)\n}\n\ntype HandlerSelector interface {\n\tSelect([]string) []string\n}\n\n// Manager is a feature that manages outbound.Handlers.\n//\n// v2ray:api:stable\ntype Manager interface {\n\tfeatures.Feature\n\t// GetHandler returns an outbound.Handler for the given tag.\n\tGetHandler(tag string) Handler\n\t// GetDefaultHandler returns the default outbound.Handler. It is usually the first outbound.Handler specified in the configuration.\n\tGetDefaultHandler() Handler\n\t// AddHandler adds a handler into this outbound.Manager.\n\tAddHandler(ctx context.Context, handler Handler) error\n\n\t// RemoveHandler removes a handler from outbound.Manager.\n\tRemoveHandler(ctx context.Context, tag string) error\n}\n\n// ManagerType returns the type of Manager interface. Can be used to implement common.HasType.\n//\n// v2ray:api:stable\nfunc ManagerType() interface{} {\n\treturn (*Manager)(nil)\n}\n"
  },
  {
    "path": "features/policy/default.go",
    "content": "package policy\n\nimport (\n\t\"time\"\n)\n\n// DefaultManager is the implementation of the Manager.\ntype DefaultManager struct{}\n\n// Type implements common.HasType.\nfunc (DefaultManager) Type() interface{} {\n\treturn ManagerType()\n}\n\n// ForLevel implements Manager.\nfunc (DefaultManager) ForLevel(level uint32) Session {\n\tp := SessionDefault()\n\tif level == 1 {\n\t\tp.Timeouts.ConnectionIdle = time.Second * 600\n\t}\n\treturn p\n}\n\n// ForSystem implements Manager.\nfunc (DefaultManager) ForSystem() System {\n\treturn System{}\n}\n\n// Start implements common.Runnable.\nfunc (DefaultManager) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (DefaultManager) Close() error {\n\treturn nil\n}\n"
  },
  {
    "path": "features/policy/policy.go",
    "content": "package policy\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// Timeout contains limits for connection timeout.\ntype Timeout struct {\n\t// Timeout for handshake phase in a connection.\n\tHandshake time.Duration\n\t// Timeout for connection being idle, i.e., there is no egress or ingress traffic in this connection.\n\tConnectionIdle time.Duration\n\t// Timeout for an uplink only connection, i.e., the downlink of the connection has been closed.\n\tUplinkOnly time.Duration\n\t// Timeout for an downlink only connection, i.e., the uplink of the connection has been closed.\n\tDownlinkOnly time.Duration\n}\n\n// Stats contains settings for stats counters.\ntype Stats struct {\n\t// Whether or not to enable stat counter for user uplink traffic.\n\tUserUplink bool\n\t// Whether or not to enable stat counter for user downlink traffic.\n\tUserDownlink bool\n}\n\n// Buffer contains settings for internal buffer.\ntype Buffer struct {\n\t// Size of buffer per connection, in bytes. -1 for unlimited buffer.\n\tPerConnection int32\n}\n\n// SystemStats contains stat policy settings on system level.\ntype SystemStats struct {\n\t// Whether or not to enable stat counter for uplink traffic in inbound handlers.\n\tInboundUplink bool\n\t// Whether or not to enable stat counter for downlink traffic in inbound handlers.\n\tInboundDownlink bool\n\t// Whether or not to enable stat counter for uplink traffic in outbound handlers.\n\tOutboundUplink bool\n\t// Whether or not to enable stat counter for downlink traffic in outbound handlers.\n\tOutboundDownlink bool\n}\n\n// System contains policy settings at system level.\ntype System struct {\n\tStats                 SystemStats\n\tOverrideAccessLogDest bool\n\tBuffer                Buffer\n}\n\n// Session is session based settings for controlling V2Ray requests. It contains various settings (or limits) that may differ for different users in the context.\ntype Session struct {\n\tTimeouts Timeout // Timeout settings\n\tStats    Stats\n\tBuffer   Buffer\n}\n\n// Manager is a feature that provides Policy for the given user by its id or level.\n//\n// v2ray:api:stable\ntype Manager interface {\n\tfeatures.Feature\n\n\t// ForLevel returns the Session policy for the given user level.\n\tForLevel(level uint32) Session\n\n\t// ForSystem returns the System policy for V2Ray system.\n\tForSystem() System\n}\n\n// ManagerType returns the type of Manager interface. Can be used to implement common.HasType.\n//\n// v2ray:api:stable\nfunc ManagerType() interface{} {\n\treturn (*Manager)(nil)\n}\n\nvar defaultBufferSize int32\n\nfunc init() {\n\tconst key = \"v2ray.ray.buffer.size\"\n\tconst defaultValue = -17\n\tsize := platform.EnvFlag{\n\t\tName:    key,\n\t\tAltName: platform.NormalizeEnvName(key),\n\t}.GetValueAsInt(defaultValue)\n\n\tswitch size {\n\tcase 0:\n\t\tdefaultBufferSize = -1 // For pipe to use unlimited size\n\tcase defaultValue: // Env flag not defined. Use default values per CPU-arch.\n\t\tswitch runtime.GOARCH {\n\t\tcase \"arm\", \"mips\", \"mipsle\":\n\t\t\tdefaultBufferSize = 0\n\t\tcase \"arm64\", \"mips64\", \"mips64le\":\n\t\t\tdefaultBufferSize = 4 * 1024 // 4k cache for low-end devices\n\t\tdefault:\n\t\t\tdefaultBufferSize = 512 * 1024\n\t\t}\n\tdefault:\n\t\tdefaultBufferSize = int32(size) * 1024 * 1024\n\t}\n}\n\nfunc defaultBufferPolicy() Buffer {\n\treturn Buffer{\n\t\tPerConnection: defaultBufferSize,\n\t}\n}\n\n// SessionDefault returns the Policy when user is not specified.\nfunc SessionDefault() Session {\n\treturn Session{\n\t\tTimeouts: Timeout{\n\t\t\t// Align Handshake timeout with nginx client_header_timeout\n\t\t\t// So that this value will not indicate server identity\n\t\t\tHandshake:      time.Second * 60,\n\t\t\tConnectionIdle: time.Second * 300,\n\t\t\tUplinkOnly:     time.Second * 1,\n\t\t\tDownlinkOnly:   time.Second * 1,\n\t\t},\n\t\tStats: Stats{\n\t\t\tUserUplink:   false,\n\t\t\tUserDownlink: false,\n\t\t},\n\t\tBuffer: defaultBufferPolicy(),\n\t}\n}\n\ntype policyKey int32\n\nconst (\n\tbufferPolicyKey policyKey = 0\n)\n\nfunc ContextWithBufferPolicy(ctx context.Context, p Buffer) context.Context {\n\treturn context.WithValue(ctx, bufferPolicyKey, p)\n}\n\nfunc BufferPolicyFromContext(ctx context.Context) Buffer {\n\tpPolicy := ctx.Value(bufferPolicyKey)\n\tif pPolicy == nil {\n\t\treturn defaultBufferPolicy()\n\t}\n\treturn pPolicy.(Buffer)\n}\n"
  },
  {
    "path": "features/routing/balancer.go",
    "content": "package routing\n\ntype BalancerOverrider interface {\n\tSetOverrideTarget(tag, target string) error\n\tGetOverrideTarget(tag string) (string, error)\n}\n\ntype BalancerPrincipleTarget interface {\n\tGetPrincipleTarget(tag string) ([]string, error)\n}\n"
  },
  {
    "path": "features/routing/context.go",
    "content": "package routing\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n// Context is a feature to store connection information for routing.\n//\n// v2ray:api:stable\ntype Context interface {\n\t// GetInboundTag returns the tag of the inbound the connection was from.\n\tGetInboundTag() string\n\n\t// GetSourcesIPs returns the source IPs bound to the connection.\n\tGetSourceIPs() []net.IP\n\n\t// GetSourcePort returns the source port of the connection.\n\tGetSourcePort() net.Port\n\n\t// GetTargetIPs returns the target IP of the connection or resolved IPs of target domain.\n\tGetTargetIPs() []net.IP\n\n\t// GetTargetPort returns the target port of the connection.\n\tGetTargetPort() net.Port\n\n\t// GetTargetDomain returns the target domain of the connection, if exists.\n\tGetTargetDomain() string\n\n\t// GetNetwork returns the network type of the connection.\n\tGetNetwork() net.Network\n\n\t// GetProtocol returns the protocol from the connection content, if sniffed out.\n\tGetProtocol() string\n\n\t// GetUser returns the user email from the connection content, if exists.\n\tGetUser() string\n\n\t// GetAttributes returns extra attributes from the connection content.\n\tGetAttributes() map[string]string\n\n\t// GetSkipDNSResolve returns a flag switch for weather skip dns resolve during route pick.\n\tGetSkipDNSResolve() bool\n}\n"
  },
  {
    "path": "features/routing/dispatcher.go",
    "content": "package routing\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\n// Dispatcher is a feature that dispatches inbound requests to outbound handlers based on rules.\n// Dispatcher is required to be registered in a V2Ray instance to make V2Ray function properly.\n//\n// v2ray:api:stable\ntype Dispatcher interface {\n\tfeatures.Feature\n\n\t// Dispatch returns a Ray for transporting data for the given request.\n\tDispatch(ctx context.Context, dest net.Destination) (*transport.Link, error)\n}\n\n// DispatcherType returns the type of Dispatcher interface. Can be used to implement common.HasType.\n//\n// v2ray:api:stable\nfunc DispatcherType() interface{} {\n\treturn (*Dispatcher)(nil)\n}\n"
  },
  {
    "path": "features/routing/dns/context.go",
    "content": "package dns\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\n// ResolvableContext is an implementation of routing.Context, with domain resolving capability.\ntype ResolvableContext struct {\n\trouting.Context\n\tdnsClient   dns.Client\n\tresolvedIPs []net.IP\n}\n\n// GetTargetIPs overrides original routing.Context's implementation.\nfunc (ctx *ResolvableContext) GetTargetIPs() []net.IP {\n\tif ips := ctx.Context.GetTargetIPs(); len(ips) != 0 {\n\t\treturn ips\n\t}\n\n\tif len(ctx.resolvedIPs) > 0 {\n\t\treturn ctx.resolvedIPs\n\t}\n\n\tif domain := ctx.GetTargetDomain(); len(domain) != 0 {\n\t\tips, err := ctx.dnsClient.LookupIP(domain)\n\t\tif err == nil {\n\t\t\tctx.resolvedIPs = ips\n\t\t\treturn ips\n\t\t}\n\t\tnewError(\"resolve ip for \", domain).Base(err).WriteToLog()\n\t}\n\n\treturn nil\n}\n\n// ContextWithDNSClient creates a new routing context with domain resolving capability.\n// Resolved domain IPs can be retrieved by GetTargetIPs().\nfunc ContextWithDNSClient(ctx routing.Context, client dns.Client) routing.Context {\n\treturn &ResolvableContext{Context: ctx, dnsClient: client}\n}\n"
  },
  {
    "path": "features/routing/dns/errors.generated.go",
    "content": "package dns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "features/routing/router.go",
    "content": "package routing\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// Router is a feature to choose an outbound tag for the given request.\n//\n// v2ray:api:stable\ntype Router interface {\n\tfeatures.Feature\n\n\t// PickRoute returns a route decision based on the given routing context.\n\tPickRoute(ctx Context) (Route, error)\n}\n\n// Route is the routing result of Router feature.\n//\n// v2ray:api:stable\ntype Route interface {\n\t// A Route is also a routing context.\n\tContext\n\n\t// GetOutboundGroupTags returns the detoured outbound group tags in sequence before a final outbound is chosen.\n\tGetOutboundGroupTags() []string\n\n\t// GetOutboundTag returns the tag of the outbound the connection was dispatched to.\n\tGetOutboundTag() string\n}\n\n// RouterType return the type of Router interface. Can be used to implement common.HasType.\n//\n// v2ray:api:stable\nfunc RouterType() interface{} {\n\treturn (*Router)(nil)\n}\n\n// DefaultRouter is an implementation of Router, which always returns ErrNoClue for routing decisions.\ntype DefaultRouter struct{}\n\n// Type implements common.HasType.\nfunc (DefaultRouter) Type() interface{} {\n\treturn RouterType()\n}\n\n// PickRoute implements Router.\nfunc (DefaultRouter) PickRoute(ctx Context) (Route, error) {\n\treturn nil, common.ErrNoClue\n}\n\n// Start implements common.Runnable.\nfunc (DefaultRouter) Start() error {\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (DefaultRouter) Close() error {\n\treturn nil\n}\n"
  },
  {
    "path": "features/routing/session/context.go",
    "content": "package session\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\n// Context is an implementation of routing.Context, which is a wrapper of context.context with session info.\ntype Context struct {\n\tInbound  *session.Inbound\n\tOutbound *session.Outbound\n\tContent  *session.Content\n}\n\n// GetInboundTag implements routing.Context.\nfunc (ctx *Context) GetInboundTag() string {\n\tif ctx.Inbound == nil {\n\t\treturn \"\"\n\t}\n\treturn ctx.Inbound.Tag\n}\n\n// GetSourceIPs implements routing.Context.\nfunc (ctx *Context) GetSourceIPs() []net.IP {\n\tif ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {\n\t\treturn nil\n\t}\n\tdest := ctx.Inbound.Source\n\tif dest.Address.Family().IsDomain() {\n\t\treturn nil\n\t}\n\n\treturn []net.IP{dest.Address.IP()}\n}\n\n// GetSourcePort implements routing.Context.\nfunc (ctx *Context) GetSourcePort() net.Port {\n\tif ctx.Inbound == nil || !ctx.Inbound.Source.IsValid() {\n\t\treturn 0\n\t}\n\treturn ctx.Inbound.Source.Port\n}\n\n// GetTargetIPs implements routing.Context.\nfunc (ctx *Context) GetTargetIPs() []net.IP {\n\tif ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {\n\t\treturn nil\n\t}\n\n\tif ctx.Outbound.Target.Address.Family().IsIP() {\n\t\treturn []net.IP{ctx.Outbound.Target.Address.IP()}\n\t}\n\n\treturn nil\n}\n\n// GetTargetPort implements routing.Context.\nfunc (ctx *Context) GetTargetPort() net.Port {\n\tif ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {\n\t\treturn 0\n\t}\n\treturn ctx.Outbound.Target.Port\n}\n\n// GetTargetDomain implements routing.Context.\nfunc (ctx *Context) GetTargetDomain() string {\n\tif ctx.Outbound == nil || !ctx.Outbound.Target.IsValid() {\n\t\treturn \"\"\n\t}\n\tdest := ctx.Outbound.Target\n\tif !dest.Address.Family().IsDomain() {\n\t\treturn \"\"\n\t}\n\treturn dest.Address.Domain()\n}\n\n// GetNetwork implements routing.Context.\nfunc (ctx *Context) GetNetwork() net.Network {\n\tif ctx.Outbound == nil {\n\t\treturn net.Network_Unknown\n\t}\n\treturn ctx.Outbound.Target.Network\n}\n\n// GetProtocol implements routing.Context.\nfunc (ctx *Context) GetProtocol() string {\n\tif ctx.Content == nil {\n\t\treturn \"\"\n\t}\n\treturn ctx.Content.Protocol\n}\n\n// GetUser implements routing.Context.\nfunc (ctx *Context) GetUser() string {\n\tif ctx.Inbound == nil || ctx.Inbound.User == nil {\n\t\treturn \"\"\n\t}\n\treturn ctx.Inbound.User.Email\n}\n\n// GetAttributes implements routing.Context.\nfunc (ctx *Context) GetAttributes() map[string]string {\n\tif ctx.Content == nil {\n\t\treturn nil\n\t}\n\treturn ctx.Content.Attributes\n}\n\n// GetSkipDNSResolve implements routing.Context.\nfunc (ctx *Context) GetSkipDNSResolve() bool {\n\tif ctx.Content == nil {\n\t\treturn false\n\t}\n\treturn ctx.Content.SkipDNSResolve\n}\n\n// AsRoutingContext creates a context from context.context with session info.\nfunc AsRoutingContext(ctx context.Context) routing.Context {\n\treturn &Context{\n\t\tInbound:  session.InboundFromContext(ctx),\n\t\tOutbound: session.OutboundFromContext(ctx),\n\t\tContent:  session.ContentFromContext(ctx),\n\t}\n}\n"
  },
  {
    "path": "features/stats/errors.generated.go",
    "content": "package stats\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "features/stats/stats.go",
    "content": "package stats\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\n// Counter is the interface for stats counters.\n//\n// v2ray:api:stable\ntype Counter interface {\n\t// Value is the current value of the counter.\n\tValue() int64\n\t// Set sets a new value to the counter, and returns the previous one.\n\tSet(int64) int64\n\t// Add adds a value to the current counter value, and returns the previous value.\n\tAdd(int64) int64\n}\n\n// Channel is the interface for stats channel.\n//\n// v2ray:api:stable\ntype Channel interface {\n\t// Channel is a runnable unit.\n\tcommon.Runnable\n\t// Publish broadcasts a message through the channel with a controlling context.\n\tPublish(context.Context, interface{})\n\t// SubscriberCount returns the number of the subscribers.\n\tSubscribers() []chan interface{}\n\t// Subscribe registers for listening to channel stream and returns a new listener channel.\n\tSubscribe() (chan interface{}, error)\n\t// Unsubscribe unregisters a listener channel from current Channel object.\n\tUnsubscribe(chan interface{}) error\n}\n\n// SubscribeRunnableChannel subscribes the channel and starts it if there is first subscriber coming.\nfunc SubscribeRunnableChannel(c Channel) (chan interface{}, error) {\n\tif len(c.Subscribers()) == 0 {\n\t\tif err := c.Start(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn c.Subscribe()\n}\n\n// UnsubscribeClosableChannel unsubscribes the channel and close it if there is no more subscriber.\nfunc UnsubscribeClosableChannel(c Channel, sub chan interface{}) error {\n\tif err := c.Unsubscribe(sub); err != nil {\n\t\treturn err\n\t}\n\tif len(c.Subscribers()) == 0 {\n\t\treturn c.Close()\n\t}\n\treturn nil\n}\n\n// Manager is the interface for stats manager.\n//\n// v2ray:api:stable\ntype Manager interface {\n\tfeatures.Feature\n\n\t// RegisterCounter registers a new counter to the manager. The identifier string must not be empty, and unique among other counters.\n\tRegisterCounter(string) (Counter, error)\n\t// UnregisterCounter unregisters a counter from the manager by its identifier.\n\tUnregisterCounter(string) error\n\t// GetCounter returns a counter by its identifier.\n\tGetCounter(string) Counter\n\n\t// RegisterChannel registers a new channel to the manager. The identifier string must not be empty, and unique among other channels.\n\tRegisterChannel(string) (Channel, error)\n\t// UnregisterCounter unregisters a channel from the manager by its identifier.\n\tUnregisterChannel(string) error\n\t// GetChannel returns a channel by its identifier.\n\tGetChannel(string) Channel\n}\n\n// GetOrRegisterCounter tries to get the StatCounter first. If not exist, it then tries to create a new counter.\nfunc GetOrRegisterCounter(m Manager, name string) (Counter, error) {\n\tcounter := m.GetCounter(name)\n\tif counter != nil {\n\t\treturn counter, nil\n\t}\n\n\treturn m.RegisterCounter(name)\n}\n\n// GetOrRegisterChannel tries to get the StatChannel first. If not exist, it then tries to create a new channel.\nfunc GetOrRegisterChannel(m Manager, name string) (Channel, error) {\n\tchannel := m.GetChannel(name)\n\tif channel != nil {\n\t\treturn channel, nil\n\t}\n\n\treturn m.RegisterChannel(name)\n}\n\n// ManagerType returns the type of Manager interface. Can be used to implement common.HasType.\n//\n// v2ray:api:stable\nfunc ManagerType() interface{} {\n\treturn (*Manager)(nil)\n}\n\n// NoopManager is an implementation of Manager, which doesn't has actual functionalities.\ntype NoopManager struct{}\n\n// Type implements common.HasType.\nfunc (NoopManager) Type() interface{} {\n\treturn ManagerType()\n}\n\n// RegisterCounter implements Manager.\nfunc (NoopManager) RegisterCounter(string) (Counter, error) {\n\treturn nil, newError(\"not implemented\")\n}\n\n// UnregisterCounter implements Manager.\nfunc (NoopManager) UnregisterCounter(string) error {\n\treturn nil\n}\n\n// GetCounter implements Manager.\nfunc (NoopManager) GetCounter(string) Counter {\n\treturn nil\n}\n\n// RegisterChannel implements Manager.\nfunc (NoopManager) RegisterChannel(string) (Channel, error) {\n\treturn nil, newError(\"not implemented\")\n}\n\n// UnregisterChannel implements Manager.\nfunc (NoopManager) UnregisterChannel(string) error {\n\treturn nil\n}\n\n// GetChannel implements Manager.\nfunc (NoopManager) GetChannel(string) Channel {\n\treturn nil\n}\n\n// Start implements common.Runnable.\nfunc (NoopManager) Start() error { return nil }\n\n// Close implements common.Closable.\nfunc (NoopManager) Close() error { return nil }\n"
  },
  {
    "path": "format.go",
    "content": "package core\n\n//go:generate go install -v github.com/daixiang0/gci@latest\n//go:generate go run ./infra/vformat/\n"
  },
  {
    "path": "functions.go",
    "content": "package core\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// CreateObject creates a new object based on the given V2Ray instance and config. The V2Ray instance may be nil.\nfunc CreateObject(v *Instance, config interface{}) (interface{}, error) {\n\treturn CreateObjectWithEnvironment(v, config, nil)\n}\n\nfunc CreateObjectWithEnvironment(v *Instance, config, environment interface{}) (interface{}, error) {\n\tvar ctx context.Context\n\tif v != nil {\n\t\tctx = toContext(v.ctx, v)\n\t}\n\tctx = envctx.ContextWithEnvironment(ctx, environment)\n\treturn common.CreateObject(ctx, config)\n}\n\n// StartInstance starts a new V2Ray instance with given serialized config.\n// By default V2Ray only support config in protobuf format, i.e., configFormat = \"protobuf\". Caller need to load other packages to add JSON support.\n//\n// v2ray:api:stable\nfunc StartInstance(configFormat string, configBytes []byte) (*Instance, error) {\n\tconfig, err := LoadConfig(configFormat, bytes.NewReader(configBytes))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinstance, err := New(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := instance.Start(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn instance, nil\n}\n\n// Dial provides an easy way for upstream caller to create net.Conn through V2Ray.\n// It dispatches the request to the given destination by the given V2Ray instance.\n// Since it is under a proxy context, the LocalAddr() and RemoteAddr() in returned net.Conn\n// will not show real addresses being used for communication.\n//\n// v2ray:api:stable\nfunc Dial(ctx context.Context, v *Instance, dest net.Destination) (net.Conn, error) {\n\tctx = toContext(ctx, v)\n\n\tdispatcher := v.GetFeature(routing.DispatcherType())\n\tif dispatcher == nil {\n\t\treturn nil, newError(\"routing.Dispatcher is not registered in V2Ray core\")\n\t}\n\n\tr, err := dispatcher.(routing.Dispatcher).Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar readerOpt net.ConnectionOption\n\tif dest.Network == net.Network_TCP {\n\t\treaderOpt = net.ConnectionOutputMulti(r.Reader)\n\t} else {\n\t\treaderOpt = net.ConnectionOutputMultiUDP(r.Reader)\n\t}\n\treturn net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil\n}\n\n// DialUDP provides a way to exchange UDP packets through V2Ray instance to remote servers.\n// Since it is under a proxy context, the LocalAddr() in returned PacketConn will not show the real address.\n//\n// TODO: SetDeadline() / SetReadDeadline() / SetWriteDeadline() are not implemented.\n//\n// v2ray:api:beta\nfunc DialUDP(ctx context.Context, v *Instance) (net.PacketConn, error) {\n\tctx = toContext(ctx, v)\n\n\tdispatcher := v.GetFeature(routing.DispatcherType())\n\tif dispatcher == nil {\n\t\treturn nil, newError(\"routing.Dispatcher is not registered in V2Ray core\")\n\t}\n\treturn udp.DialDispatcher(ctx, dispatcher.(routing.Dispatcher))\n}\n"
  },
  {
    "path": "functions_test.go",
    "content": "package core_test\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\nfunc xor(b []byte) []byte {\n\tr := make([]byte, len(b))\n\tfor i, v := range b {\n\t\tr[i] = v ^ 'c'\n\t}\n\treturn r\n}\n\nfunc xor2(b []byte) []byte {\n\tr := make([]byte, len(b))\n\tfor i, v := range b {\n\t\tr[i] = v ^ 'd'\n\t}\n\treturn r\n}\n\nfunc TestV2RayDial(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tcfgBytes, err := proto.Marshal(config)\n\tcommon.Must(err)\n\n\tserver, err := core.StartInstance(core.FormatProtobuf, cfgBytes)\n\tcommon.Must(err)\n\tdefer server.Close()\n\n\tconn, err := core.Dial(context.Background(), server, dest)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst size = 10240 * 1024\n\tpayload := make([]byte, size)\n\tcommon.Must2(rand.Read(payload))\n\n\tif _, err := conn.Write(payload); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\treceive := make([]byte, size)\n\tif _, err := io.ReadFull(conn, receive); err != nil {\n\t\tt.Fatal(\"failed to read all response: \", err)\n\t}\n\n\tif r := cmp.Diff(xor(receive), payload); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestV2RayDialUDPConn(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tcfgBytes, err := proto.Marshal(config)\n\tcommon.Must(err)\n\n\tserver, err := core.StartInstance(core.FormatProtobuf, cfgBytes)\n\tcommon.Must(err)\n\tdefer server.Close()\n\n\tconn, err := core.Dial(context.Background(), server, dest)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst size = 1024\n\tpayload := make([]byte, size)\n\tcommon.Must2(rand.Read(payload))\n\n\tfor i := 0; i < 2; i++ {\n\t\tif _, err := conn.Write(payload); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t}\n\n\ttime.Sleep(time.Millisecond * 500)\n\n\treceive := make([]byte, size*2)\n\tfor i := 0; i < 2; i++ {\n\t\tn, err := conn.Read(receive)\n\t\tif err != nil {\n\t\t\tt.Fatal(\"expect no error, but got \", err)\n\t\t}\n\t\tif n != size {\n\t\t\tt.Fatal(\"expect read size \", size, \" but got \", n)\n\t\t}\n\n\t\tif r := cmp.Diff(xor(receive[:n]), payload); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n}\n\nfunc TestV2RayDialUDP(t *testing.T) {\n\tudpServer1 := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest1, err := udpServer1.Start()\n\tcommon.Must(err)\n\tdefer udpServer1.Close()\n\n\tudpServer2 := udp.Server{\n\t\tMsgProcessor: xor2,\n\t}\n\tdest2, err := udpServer2.Start()\n\tcommon.Must(err)\n\tdefer udpServer2.Close()\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tcfgBytes, err := proto.Marshal(config)\n\tcommon.Must(err)\n\n\tserver, err := core.StartInstance(core.FormatProtobuf, cfgBytes)\n\tcommon.Must(err)\n\tdefer server.Close()\n\n\tconn, err := core.DialUDP(context.Background(), server)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst size = 1024\n\t{\n\t\tpayload := make([]byte, size)\n\t\tcommon.Must2(rand.Read(payload))\n\n\t\tif _, err := conn.WriteTo(payload, &net.UDPAddr{\n\t\t\tIP:   dest1.Address.IP(),\n\t\t\tPort: int(dest1.Port),\n\t\t}); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\treceive := make([]byte, size)\n\t\tif _, _, err := conn.ReadFrom(receive); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif r := cmp.Diff(xor(receive), payload); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t}\n\n\t{\n\t\tpayload := make([]byte, size)\n\t\tcommon.Must2(rand.Read(payload))\n\n\t\tif _, err := conn.WriteTo(payload, &net.UDPAddr{\n\t\t\tIP:   dest2.Address.IP(),\n\t\t\tPort: int(dest2.Port),\n\t\t}); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\treceive := make([]byte, size)\n\t\tif _, _, err := conn.ReadFrom(receive); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif r := cmp.Diff(xor2(receive), payload); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/v2fly/v2ray-core/v5\n\ngo 1.25.5\n\ntoolchain go1.26.1\n\nrequire (\n\tgithub.com/adrg/xdg v0.5.3\n\tgithub.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22\n\tgithub.com/go-chi/chi/v5 v5.2.5\n\tgithub.com/go-chi/render v1.0.3\n\tgithub.com/go-playground/validator/v10 v10.30.1\n\tgithub.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259\n\tgithub.com/golang/mock v1.6.0\n\tgithub.com/golang/protobuf v1.5.4\n\tgithub.com/google/go-cmp v0.7.0\n\tgithub.com/google/gopacket v1.1.19\n\tgithub.com/gorilla/websocket v1.5.3\n\tgithub.com/improbable-eng/grpc-web v0.15.0\n\tgithub.com/jhump/protoreflect v1.18.0\n\tgithub.com/miekg/dns v1.1.72\n\tgithub.com/mustafaturan/bus v1.0.2\n\tgithub.com/pelletier/go-toml v1.9.5\n\tgithub.com/pion/dtls/v2 v2.2.12\n\tgithub.com/pion/stun/v3 v3.1.1\n\tgithub.com/pion/transport/v2 v2.2.10\n\tgithub.com/pires/go-proxyproto v0.11.0\n\tgithub.com/quic-go/quic-go v0.59.0\n\tgithub.com/refraction-networking/utls v1.8.2\n\tgithub.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb\n\tgithub.com/stretchr/testify v1.11.1\n\tgithub.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08\n\tgithub.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848\n\tgithub.com/v2fly/hysteria/core/v2 v2.0.0-20260220231229-39018a43855e\n\tgithub.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e\n\tgithub.com/v2fly/struc v0.0.0-20241227015403-8e8fa1badfd6\n\tgithub.com/vincent-petithory/dataurl v1.0.0\n\tgithub.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432\n\tgo.starlark.net v0.0.0-20230612165344-9532f5667272\n\tgo4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35\n\tgolang.org/x/crypto v0.49.0\n\tgolang.org/x/net v0.52.0\n\tgolang.org/x/sync v0.20.0\n\tgolang.org/x/sys v0.42.0\n\tgolang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb\n\tgoogle.golang.org/grpc v1.79.2\n\tgoogle.golang.org/protobuf v1.36.11\n\tgopkg.in/yaml.v3 v3.0.1\n\tgvisor.dev/gvisor v0.0.0-20260218152508-eed1cebf761e\n\th12.io/socks v1.0.3\n\tlukechampine.com/blake3 v1.4.1\n)\n\nrequire (\n\tgithub.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 // indirect\n\tgithub.com/ajg/form v1.5.1 // indirect\n\tgithub.com/andybalholm/brotli v1.0.6 // indirect\n\tgithub.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d // indirect\n\tgithub.com/cenkalti/backoff/v4 v4.1.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect\n\tgithub.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect\n\tgithub.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.12 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/gobwas/ws v1.2.1 // indirect\n\tgithub.com/google/btree v1.1.2 // indirect\n\tgithub.com/jhump/protoreflect/v2 v2.0.0-beta.1 // indirect\n\tgithub.com/klauspost/compress v1.17.4 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.2.5 // indirect\n\tgithub.com/klauspost/reedsolomon v1.11.7 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect\n\tgithub.com/mustafaturan/monoton v1.0.0 // indirect\n\tgithub.com/patrickmn/go-cache v2.1.0+incompatible // indirect\n\tgithub.com/pion/dtls/v3 v3.0.11 // indirect\n\tgithub.com/pion/logging v0.2.4 // indirect\n\tgithub.com/pion/randutil v0.1.0 // indirect\n\tgithub.com/pion/sctp v1.8.7 // indirect\n\tgithub.com/pion/transport/v3 v3.0.7 // indirect\n\tgithub.com/pion/transport/v4 v4.0.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/quic-go/qpack v0.6.0 // indirect\n\tgithub.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect\n\tgithub.com/rs/cors v1.7.0 // indirect\n\tgithub.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgithub.com/wlynxg/anet v0.0.5 // indirect\n\tgithub.com/xtaci/smux v1.5.24 // indirect\n\tgolang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect\n\tgolang.org/x/mod v0.33.0 // indirect\n\tgolang.org/x/text v0.35.0 // indirect\n\tgolang.org/x/time v0.12.0 // indirect\n\tgolang.org/x/tools v0.42.0 // indirect\n\tgolang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect\n\tnhooyr.io/websocket v1.8.6 // indirect\n)\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=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w=\ngithub.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=\ngithub.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=\ngithub.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=\ngithub.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=\ngithub.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=\ngithub.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1 h1:+JkXLHME8vLJafGhOH4aoV2Iu8bR55nU6iKMVfYVLjY=\ngithub.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg=\ngithub.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=\ngithub.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=\ngithub.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=\ngithub.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=\ngithub.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=\ngithub.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=\ngithub.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22 h1:00ziBGnLWQEcR9LThDwvxOznJJquJ9bYUdmBFnawLMU=\ngithub.com/apernet/quic-go v0.59.1-0.20260217092621-db4786c77a22/go.mod h1:Npbg8qBtAZlsAB3FWmqwlVh5jtVG6a4DlYsOylUpvzA=\ngithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=\ngithub.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=\ngithub.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=\ngithub.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=\ngithub.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=\ngithub.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=\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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=\ngithub.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d h1:zsO4lp+bjv5XvPTF58Vq+qgmZEYZttJK+CWtSZhKenI=\ngithub.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d/go.mod h1:f1iKL6ZhUWvbk7PdWVmOaak10o86cqMUYEmn1CZNGEI=\ngithub.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=\ngithub.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=\ngithub.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=\ngithub.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=\ngithub.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=\ngithub.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/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/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=\ngithub.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=\ngithub.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=\ngithub.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=\ngithub.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=\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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=\ngithub.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=\ngithub.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=\ngithub.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=\ngithub.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=\ngithub.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=\ngithub.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=\ngithub.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=\ngithub.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=\ngithub.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=\ngithub.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a h1:YtdtTUN1iH97s+6PUjLnaiKSQj4oG1/EZ3N9bx6g4kU=\ngithub.com/ebfe/bcrypt_pbkdf v0.0.0-20140212075826-3c8d2dcb253a/go.mod h1:/CZpbhAusDOobpcb9yubw46kdYjq0zRC0Wpg9a9zFQM=\ngithub.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=\ngithub.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=\ngithub.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=\ngithub.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=\ngithub.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=\ngithub.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=\ngithub.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=\ngithub.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=\ngithub.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=\ngithub.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=\ngithub.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=\ngithub.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=\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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=\ngithub.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=\ngithub.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=\ngithub.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=\ngithub.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=\ngithub.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=\ngithub.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=\ngithub.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=\ngithub.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk=\ngithub.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=\ngithub.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=\ngithub.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259 h1:ZHJ7+IGpuOXtVf6Zk/a3WuHQgkC+vXwaqfUBDFwahtI=\ngithub.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259/go.mod h1:9Qcha0gTWLw//0VNka1Cbnjvg3pNKGFdAm7E9sBabxE=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\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.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\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.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=\ngithub.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=\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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/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.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=\ngithub.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=\ngithub.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=\ngithub.com/gopherjs/gopherjs v0.0.0-20210420193930-a4630ec28c79/go.mod h1:Opf9rtYVq0eTyX+aRVmRO9hE8ERAozcdrBxWG9Q6mkQ=\ngithub.com/gopherjs/websocket v0.0.0-20191103002815-9a42957e2b3a/go.mod h1:jd+zY81Fx2lC4bfw58+Rflg1srqmedQjbBUejKOjYNY=\ngithub.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=\ngithub.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=\ngithub.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=\ngithub.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=\ngithub.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=\ngithub.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI=\ngithub.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c=\ngithub.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=\ngithub.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=\ngithub.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=\ngithub.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=\ngithub.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=\ngithub.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=\ngithub.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ=\ngithub.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=\ngithub.com/jhump/protoreflect v1.18.0 h1:TOz0MSR/0JOZ5kECB/0ufGnC2jdsgZ123Rd/k4Z5/2w=\ngithub.com/jhump/protoreflect v1.18.0/go.mod h1:ezWcltJIVF4zYdIFM+D/sHV4Oh5LNU08ORzCGfwvTz8=\ngithub.com/jhump/protoreflect/v2 v2.0.0-beta.1 h1:Dw1rslK/VotaUGYsv53XVWITr+5RCPXfvvlGrM/+B6w=\ngithub.com/jhump/protoreflect/v2 v2.0.0-beta.1/go.mod h1:D9LBEowZyv8/iSu97FU2zmXG3JxVTmNw21mu63niFzU=\ngithub.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=\ngithub.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\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.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.10/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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=\ngithub.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=\ngithub.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=\ngithub.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=\ngithub.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=\ngithub.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=\ngithub.com/klauspost/reedsolomon v1.11.7 h1:9uaHU0slncktTEEg4+7Vl7q7XUNMBUOK4R9gnKhMjAU=\ngithub.com/klauspost/reedsolomon v1.11.7/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A=\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.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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=\ngithub.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=\ngithub.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=\ngithub.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=\ngithub.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=\ngithub.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=\ngithub.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=\ngithub.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=\ngithub.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=\ngithub.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=\ngithub.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=\ngithub.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=\ngithub.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=\ngithub.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\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/mustafaturan/bus v1.0.2 h1:2x3ErwZ0uUPwwZ5ZZoknEQprdaxr68Yl3mY8jDye1Ws=\ngithub.com/mustafaturan/bus v1.0.2/go.mod h1:h7gfehm8TThv4Dcaa+wDQG7r7j6p74v+7ftr0Rq9i1Q=\ngithub.com/mustafaturan/monoton v0.3.1/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV0Lz8p1dc+vy8=\ngithub.com/mustafaturan/monoton v1.0.0 h1:8SCej+JiNn0lyps7V+Jzc1CRAkDR4EZPWrTupQ61YCQ=\ngithub.com/mustafaturan/monoton v1.0.0/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV0Lz8p1dc+vy8=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo=\ngithub.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=\ngithub.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=\ngithub.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=\ngithub.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=\ngithub.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=\ngithub.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=\ngithub.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=\ngithub.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=\ngithub.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=\ngithub.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=\ngithub.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=\ngithub.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=\ngithub.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=\ngithub.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=\ngithub.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=\ngithub.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=\ngithub.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=\ngithub.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=\ngithub.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=\ngithub.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=\ngithub.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=\ngithub.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=\ngithub.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=\ngithub.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=\ngithub.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 h1:KPpdlQLZcHfTMQRi6bFQ7ogNO0ltFT4PmtwTLW4W+14=\ngithub.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=\ngithub.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=\ngithub.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=\ngithub.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=\ngithub.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=\ngithub.com/pion/dtls/v2 v2.0.0-rc.7/go.mod h1:U199DvHpRBN0muE9+tVN4TMy1jvEhZIZ63lk4xkvVSk=\ngithub.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=\ngithub.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=\ngithub.com/pion/dtls/v3 v3.0.11 h1:zqn8YhoAU7d9whsWLhNiQlbB8QdpJj8XQVSc5ImUons=\ngithub.com/pion/dtls/v3 v3.0.11/go.mod h1:YEmmBYIoBsY3jmG56dsziTv/Lca9y4Om83370CXfqJ8=\ngithub.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=\ngithub.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=\ngithub.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so=\ngithub.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=\ngithub.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=\ngithub.com/pion/sctp v1.7.6/go.mod h1:ichkYQ5tlgCQwEwvgfdcAolqx1nHbYCxo4D7zK/K0X8=\ngithub.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw=\ngithub.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU=\ngithub.com/pion/stun/v3 v3.1.1 h1:CkQxveJ4xGQjulGSROXbXq94TAWu8gIX2dT+ePhUkqw=\ngithub.com/pion/stun/v3 v3.1.1/go.mod h1:qC1DfmcCTQjl9PBaMa5wSn3x9IPmKxSdcCsxBcDBndM=\ngithub.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=\ngithub.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ=\ngithub.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=\ngithub.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q=\ngithub.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=\ngithub.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=\ngithub.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=\ngithub.com/pion/transport/v4 v4.0.1 h1:sdROELU6BZ63Ab7FrOLn13M6YdJLY20wldXW2Cu2k8o=\ngithub.com/pion/transport/v4 v4.0.1/go.mod h1:nEuEA4AD5lPdcIegQDpVLgNoDGreqM/YqmEx3ovP4jM=\ngithub.com/pires/go-proxyproto v0.11.0 h1:gUQpS85X/VJMdUsYyEgyn59uLJvGqPhJV5YvG68wXH4=\ngithub.com/pires/go-proxyproto v0.11.0/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=\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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=\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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=\ngithub.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/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/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=\ngithub.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=\ngithub.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=\ngithub.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=\ngithub.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=\ngithub.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=\ngithub.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo=\ngithub.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=\ngithub.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=\ngithub.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=\ngithub.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=\ngithub.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=\ngithub.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=\ngithub.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 h1:zOjq+1/uLzn/Xo40stbvjIY/yehG0+mfmlsiEmc0xmQ=\ngithub.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4/go.mod h1:aI+8yClBW+1uovkHw6HM01YXnYB8vohtB9C83wzx34E=\ngithub.com/seiflotfy/cuckoofilter v0.0.0-20200416141329-862a88987de7/go.mod h1:ET5mVvNjwaGXRgZxO9UZr7X+8eAf87AfIYNwRSp9s4Y=\ngithub.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=\ngithub.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=\ngithub.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=\ngithub.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=\ngithub.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=\ngithub.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=\ngithub.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=\ngithub.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=\ngithub.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=\ngithub.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=\ngithub.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=\ngithub.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=\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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=\ngithub.com/txthinking/runnergroup v0.0.0-20200327135940-540a793bb997/go.mod h1:CLUSJbazqETbaR+i0YAhXBICV9TrKH93pziccMhmhpM=\ngithub.com/txthinking/socks5 v0.0.0-20200327133705-caf148ab5e9d/go.mod h1:d3n8NJ6QMRb6I/WAlp4z5ZPAoaeqDmX5NgVZA0mhe+I=\ngithub.com/txthinking/x v0.0.0-20200330144832-5ad2416896a9/go.mod h1:WgqbSEmUYSjEV3B1qmee/PpP2NYEz4bL9/+mF1ma+s4=\ngithub.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=\ngithub.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=\ngithub.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=\ngithub.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=\ngithub.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=\ngithub.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=\ngithub.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08 h1:4Yh46CVE3k/lPq6hUbEdbB1u1anRBXLewm3k+L0iOMc=\ngithub.com/v2fly/BrowserBridge v0.0.0-20210430233438-0570fc1d7d08/go.mod h1:KAuQNm+LWQCOFqdBcUgihPzRpVXRKzGbTNhfEfRZ4wY=\ngithub.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848 h1:p1UzXK6VAutXFFQMnre66h7g1BjRKUnLv0HfmmRoz7w=\ngithub.com/v2fly/VSign v0.0.0-20201108000810-e2adc24bf848/go.mod h1:p80Bv154ZtrGpXMN15slDCqc9UGmfBuUzheDFBYaW/M=\ngithub.com/v2fly/hysteria/core/v2 v2.0.0-20260220231229-39018a43855e h1:0vxrC4Rn4t421ecsY7nlMG5L7/1LJzcWUuyB3q7nnuc=\ngithub.com/v2fly/hysteria/core/v2 v2.0.0-20260220231229-39018a43855e/go.mod h1:onOGso2sRgruR/bUD1Vl39o+B4HVOdv+v7mS6E7pbn4=\ngithub.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=\ngithub.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=\ngithub.com/v2fly/struc v0.0.0-20241227015403-8e8fa1badfd6 h1:Qea2jW7g1hvQ9TkYq3aT2h0NDWjPQHtvDfmKXoWgJ9E=\ngithub.com/v2fly/struc v0.0.0-20241227015403-8e8fa1badfd6/go.mod h1:a/FYYQz8bW7wh2jmI+DVsbVYwLkgmgpml+GrJwV+eIo=\ngithub.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI=\ngithub.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=\ngithub.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=\ngithub.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=\ngithub.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=\ngithub.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432 h1:I/ATawgO2RerCq9ACwL0wBB8xNXZdE3J+93MCEHReRs=\ngithub.com/xiaokangwang/VLite v0.0.0-20220418190619-cff95160a432/go.mod h1:QN7Go2ftTVfx0aCTh9RXHV8pkpi0FtmbwQw40dy61wQ=\ngithub.com/xtaci/smux v1.5.12/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=\ngithub.com/xtaci/smux v1.5.15/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=\ngithub.com/xtaci/smux v1.5.24 h1:77emW9dtnOxxOQ5ltR+8BbsX1kzcOxQ5gB+aaV9hXOY=\ngithub.com/xtaci/smux v1.5.24/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngo.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=\ngo.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=\ngo.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=\ngo.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=\ngo.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=\ngo.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=\ngo.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=\ngo.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=\ngo.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=\ngo.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=\ngo.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=\ngo.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8=\ngo.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=\ngo.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=\ngo.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=\ngo.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=\ngo.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=\ngo.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=\ngo.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=\ngo.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=\ngo.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=\ngo.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=\ngo.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=\ngo.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=\ngo4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35 h1:nJAwRlGWZZDOD+6wni9KVUNHMpHko/OnRwsrCYeAzPo=\ngo4.org/netipx v0.0.0-20230303233057-f1b76eb4bb35/go.mod h1:TQvodOM+hJTioNQJilmLXu08JNb8i+ccq418+KWu1/Y=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/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-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/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-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=\ngolang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=\ngolang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=\ngolang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=\ngolang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=\ngolang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/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.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=\ngolang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=\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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/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-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190125091013-d26f9f9a57f3/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=\ngolang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=\ngolang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=\ngolang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\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-20190227155943-e225da77a7e6/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.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=\ngolang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=\ngolang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/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-20181122145206-62eef0e2fa9b/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\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-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/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-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=\ngolang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=\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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=\ngolang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=\ngolang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=\ngolang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=\ngolang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=\ngolang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=\ngolang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\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-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\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.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=\ngolang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=\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=\ngolang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=\ngolang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=\ngolang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A=\ngolang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=\ngoogle.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=\ngoogle.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=\ngoogle.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=\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.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\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-20180628173108-788fd7840127/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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=\ngopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=\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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/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-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=\ngvisor.dev/gvisor v0.0.0-20260218152508-eed1cebf761e h1:OaBM9m99p7sXzsj1A7lrwLAdWZKCwlA8jBn3BXFO+dE=\ngvisor.dev/gvisor v0.0.0-20260218152508-eed1cebf761e/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q=\nh12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo=\nh12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=\nhonnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nlukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=\nlukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=\nnhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=\nnhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nsigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=\nsourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=\n"
  },
  {
    "path": "infra/conf/cfgcommon/buildable.go",
    "content": "package cfgcommon\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/proto\"\n)\n\ntype Buildable interface {\n\tBuild() (proto.Message, error)\n}\n\ntype BuildableV5 interface {\n\tBuildV5(ctx context.Context) (proto.Message, error)\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/common.go",
    "content": "package cfgcommon\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype StringList []string\n\nfunc NewStringList(raw []string) *StringList {\n\tlist := StringList(raw)\n\treturn &list\n}\n\nfunc (v StringList) Len() int {\n\treturn len(v)\n}\n\nfunc (v *StringList) UnmarshalJSON(data []byte) error {\n\tvar strarray []string\n\tif err := json.Unmarshal(data, &strarray); err == nil {\n\t\t*v = *NewStringList(strarray)\n\t\treturn nil\n\t}\n\n\tvar rawstr string\n\tif err := json.Unmarshal(data, &rawstr); err == nil {\n\t\tstrlist := strings.Split(rawstr, \",\")\n\t\t*v = *NewStringList(strlist)\n\t\treturn nil\n\t}\n\treturn newError(\"unknown format of a string list: \" + string(data))\n}\n\ntype Address struct {\n\tnet.Address\n}\n\nfunc (v *Address) UnmarshalJSON(data []byte) error {\n\tvar rawStr string\n\tif err := json.Unmarshal(data, &rawStr); err != nil {\n\t\treturn newError(\"invalid address: \", string(data)).Base(err)\n\t}\n\tv.Address = net.ParseAddress(rawStr)\n\n\treturn nil\n}\n\nfunc (v *Address) Build() *net.IPOrDomain {\n\treturn net.NewIPOrDomain(v.Address)\n}\n\ntype Network string\n\nfunc (v Network) Build() net.Network {\n\treturn net.ParseNetwork(string(v))\n}\n\ntype NetworkList []Network\n\nfunc (v *NetworkList) UnmarshalJSON(data []byte) error {\n\tvar strarray []Network\n\tif err := json.Unmarshal(data, &strarray); err == nil {\n\t\tnl := NetworkList(strarray)\n\t\t*v = nl\n\t\treturn nil\n\t}\n\n\tvar rawstr Network\n\tif err := json.Unmarshal(data, &rawstr); err == nil {\n\t\tstrlist := strings.Split(string(rawstr), \",\")\n\t\tnl := make([]Network, len(strlist))\n\t\tfor idx, network := range strlist {\n\t\t\tnl[idx] = Network(network)\n\t\t}\n\t\t*v = nl\n\t\treturn nil\n\t}\n\treturn newError(\"unknown format of a string list: \" + string(data))\n}\n\nfunc (v *NetworkList) Build() []net.Network {\n\tif v == nil {\n\t\treturn []net.Network{net.Network_TCP}\n\t}\n\n\tlist := make([]net.Network, 0, len(*v))\n\tfor _, network := range *v {\n\t\tlist = append(list, network.Build())\n\t}\n\treturn list\n}\n\nfunc parseIntPort(data []byte) (net.Port, error) {\n\tvar intPort uint32\n\terr := json.Unmarshal(data, &intPort)\n\tif err != nil {\n\t\treturn net.Port(0), err\n\t}\n\treturn net.PortFromInt(intPort)\n}\n\nfunc parseStringPort(s string) (net.Port, net.Port, error) {\n\tif strings.HasPrefix(s, \"env:\") {\n\t\ts = s[4:]\n\t\ts = os.Getenv(s)\n\t}\n\n\tpair := strings.SplitN(s, \"-\", 2)\n\tif len(pair) == 0 {\n\t\treturn net.Port(0), net.Port(0), newError(\"invalid port range: \", s)\n\t}\n\tif len(pair) == 1 {\n\t\tport, err := net.PortFromString(pair[0])\n\t\treturn port, port, err\n\t}\n\n\tfromPort, err := net.PortFromString(pair[0])\n\tif err != nil {\n\t\treturn net.Port(0), net.Port(0), err\n\t}\n\ttoPort, err := net.PortFromString(pair[1])\n\tif err != nil {\n\t\treturn net.Port(0), net.Port(0), err\n\t}\n\treturn fromPort, toPort, nil\n}\n\nfunc parseJSONStringPort(data []byte) (net.Port, net.Port, error) {\n\tvar s string\n\terr := json.Unmarshal(data, &s)\n\tif err != nil {\n\t\treturn net.Port(0), net.Port(0), err\n\t}\n\treturn parseStringPort(s)\n}\n\ntype PortRange struct {\n\tFrom uint32\n\tTo   uint32\n}\n\nfunc (v *PortRange) Build() *net.PortRange {\n\treturn &net.PortRange{\n\t\tFrom: v.From,\n\t\tTo:   v.To,\n\t}\n}\n\n// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON\nfunc (v *PortRange) UnmarshalJSON(data []byte) error {\n\tport, err := parseIntPort(data)\n\tif err == nil {\n\t\tv.From = uint32(port)\n\t\tv.To = uint32(port)\n\t\treturn nil\n\t}\n\n\tfrom, to, err := parseJSONStringPort(data)\n\tif err == nil {\n\t\tv.From = uint32(from)\n\t\tv.To = uint32(to)\n\t\tif v.From > v.To {\n\t\t\treturn newError(\"invalid port range \", v.From, \" -> \", v.To)\n\t\t}\n\t\treturn nil\n\t}\n\n\treturn newError(\"invalid port range: \", string(data))\n}\n\ntype PortList struct {\n\tRange []PortRange\n}\n\nfunc (list *PortList) Build() *net.PortList {\n\tportList := new(net.PortList)\n\tfor _, r := range list.Range {\n\t\tportList.Range = append(portList.Range, r.Build())\n\t}\n\treturn portList\n}\n\n// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON\nfunc (list *PortList) UnmarshalJSON(data []byte) error {\n\tvar listStr string\n\tvar number uint32\n\tif err := json.Unmarshal(data, &listStr); err != nil {\n\t\tif err2 := json.Unmarshal(data, &number); err2 != nil {\n\t\t\treturn newError(\"invalid port: \", string(data)).Base(err2)\n\t\t}\n\t}\n\terr := list.UnmarshalText(listStr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif number != 0 {\n\t\tlist.Range = append(list.Range, PortRange{From: number, To: number})\n\t}\n\treturn nil\n}\n\nfunc (list *PortList) UnmarshalText(listStr string) error {\n\trangelist := strings.Split(listStr, \",\")\n\tfor _, rangeStr := range rangelist {\n\t\ttrimmed := strings.TrimSpace(rangeStr)\n\t\tif len(trimmed) > 0 {\n\t\t\tif strings.Contains(trimmed, \"-\") {\n\t\t\t\tfrom, to, err := parseStringPort(trimmed)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn newError(\"invalid port range: \", trimmed).Base(err)\n\t\t\t\t}\n\t\t\t\tlist.Range = append(list.Range, PortRange{From: uint32(from), To: uint32(to)})\n\t\t\t} else {\n\t\t\t\tport, err := parseIntPort([]byte(trimmed))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn newError(\"invalid port: \", trimmed).Base(err)\n\t\t\t\t}\n\t\t\t\tlist.Range = append(list.Range, PortRange{From: uint32(port), To: uint32(port)})\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\ntype User struct {\n\tEmailString string `json:\"email\"`\n\tLevelByte   byte   `json:\"level\"`\n}\n\nfunc (v *User) Build() *protocol.User {\n\treturn &protocol.User{\n\t\tEmail: v.EmailString,\n\t\tLevel: uint32(v.LevelByte),\n\t}\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/common_test.go",
    "content": "package cfgcommon_test\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n)\n\nfunc TestStringListUnmarshalError(t *testing.T) {\n\trawJSON := `1234`\n\tlist := new(cfgcommon.StringList)\n\terr := json.Unmarshal([]byte(rawJSON), list)\n\tif err == nil {\n\t\tt.Error(\"expected error, but got nil\")\n\t}\n}\n\nfunc TestStringListLen(t *testing.T) {\n\trawJSON := `\"a, b, c, d\"`\n\tvar list cfgcommon.StringList\n\terr := json.Unmarshal([]byte(rawJSON), &list)\n\tcommon.Must(err)\n\tif r := cmp.Diff([]string(list), []string{\"a\", \" b\", \" c\", \" d\"}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestIPParsing(t *testing.T) {\n\trawJSON := \"\\\"8.8.8.8\\\"\"\n\tvar address cfgcommon.Address\n\terr := json.Unmarshal([]byte(rawJSON), &address)\n\tcommon.Must(err)\n\tif r := cmp.Diff(address.IP(), net.IP{8, 8, 8, 8}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestDomainParsing(t *testing.T) {\n\trawJSON := \"\\\"v2fly.org\\\"\"\n\tvar address cfgcommon.Address\n\tcommon.Must(json.Unmarshal([]byte(rawJSON), &address))\n\tif address.Domain() != \"v2fly.org\" {\n\t\tt.Error(\"domain: \", address.Domain())\n\t}\n}\n\nfunc TestURLParsing(t *testing.T) {\n\t{\n\t\trawJSON := \"\\\"https://dns.google/dns-query\\\"\"\n\t\tvar address cfgcommon.Address\n\t\tcommon.Must(json.Unmarshal([]byte(rawJSON), &address))\n\t\tif address.Domain() != \"https://dns.google/dns-query\" {\n\t\t\tt.Error(\"URL: \", address.Domain())\n\t\t}\n\t}\n\t{\n\t\trawJSON := \"\\\"https+local://dns.google/dns-query\\\"\"\n\t\tvar address cfgcommon.Address\n\t\tcommon.Must(json.Unmarshal([]byte(rawJSON), &address))\n\t\tif address.Domain() != \"https+local://dns.google/dns-query\" {\n\t\t\tt.Error(\"URL: \", address.Domain())\n\t\t}\n\t}\n}\n\nfunc TestInvalidAddressJson(t *testing.T) {\n\trawJSON := \"1234\"\n\tvar address cfgcommon.Address\n\terr := json.Unmarshal([]byte(rawJSON), &address)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestStringNetwork(t *testing.T) {\n\tvar network cfgcommon.Network\n\tcommon.Must(json.Unmarshal([]byte(`\"tcp\"`), &network))\n\tif v := network.Build(); v != net.Network_TCP {\n\t\tt.Error(\"network: \", v)\n\t}\n}\n\nfunc TestArrayNetworkList(t *testing.T) {\n\tvar list cfgcommon.NetworkList\n\tcommon.Must(json.Unmarshal([]byte(\"[\\\"Tcp\\\"]\"), &list))\n\n\tnlist := list.Build()\n\tif !net.HasNetwork(nlist, net.Network_TCP) {\n\t\tt.Error(\"no tcp network\")\n\t}\n\tif net.HasNetwork(nlist, net.Network_UDP) {\n\t\tt.Error(\"has udp network\")\n\t}\n}\n\nfunc TestStringNetworkList(t *testing.T) {\n\tvar list cfgcommon.NetworkList\n\tcommon.Must(json.Unmarshal([]byte(\"\\\"TCP, ip\\\"\"), &list))\n\n\tnlist := list.Build()\n\tif !net.HasNetwork(nlist, net.Network_TCP) {\n\t\tt.Error(\"no tcp network\")\n\t}\n\tif net.HasNetwork(nlist, net.Network_UDP) {\n\t\tt.Error(\"has udp network\")\n\t}\n}\n\nfunc TestInvalidNetworkJson(t *testing.T) {\n\tvar list cfgcommon.NetworkList\n\terr := json.Unmarshal([]byte(\"0\"), &list)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestIntPort(t *testing.T) {\n\tvar portRange cfgcommon.PortRange\n\tcommon.Must(json.Unmarshal([]byte(\"1234\"), &portRange))\n\n\tif r := cmp.Diff(portRange, cfgcommon.PortRange{\n\t\tFrom: 1234, To: 1234,\n\t}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestOverRangeIntPort(t *testing.T) {\n\tvar portRange cfgcommon.PortRange\n\terr := json.Unmarshal([]byte(\"70000\"), &portRange)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n\n\terr = json.Unmarshal([]byte(\"-1\"), &portRange)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestEnvPort(t *testing.T) {\n\tcommon.Must(os.Setenv(\"PORT\", \"1234\"))\n\n\tvar portRange cfgcommon.PortRange\n\tcommon.Must(json.Unmarshal([]byte(\"\\\"env:PORT\\\"\"), &portRange))\n\n\tif r := cmp.Diff(portRange, cfgcommon.PortRange{\n\t\tFrom: 1234, To: 1234,\n\t}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestSingleStringPort(t *testing.T) {\n\tvar portRange cfgcommon.PortRange\n\tcommon.Must(json.Unmarshal([]byte(\"\\\"1234\\\"\"), &portRange))\n\n\tif r := cmp.Diff(portRange, cfgcommon.PortRange{\n\t\tFrom: 1234, To: 1234,\n\t}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestStringPairPort(t *testing.T) {\n\tvar portRange cfgcommon.PortRange\n\tcommon.Must(json.Unmarshal([]byte(\"\\\"1234-5678\\\"\"), &portRange))\n\n\tif r := cmp.Diff(portRange, cfgcommon.PortRange{\n\t\tFrom: 1234, To: 5678,\n\t}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestOverRangeStringPort(t *testing.T) {\n\tvar portRange cfgcommon.PortRange\n\terr := json.Unmarshal([]byte(\"\\\"65536\\\"\"), &portRange)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n\n\terr = json.Unmarshal([]byte(\"\\\"70000-80000\\\"\"), &portRange)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n\n\terr = json.Unmarshal([]byte(\"\\\"1-90000\\\"\"), &portRange)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n\n\terr = json.Unmarshal([]byte(\"\\\"700-600\\\"\"), &portRange)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestUserParsing(t *testing.T) {\n\tuser := new(cfgcommon.User)\n\tcommon.Must(json.Unmarshal([]byte(`{\n    \"id\": \"96edb838-6d68-42ef-a933-25f7ac3a9d09\",\n    \"email\": \"love@v2fly.org\",\n    \"level\": 1,\n    \"alterId\": 100\n  }`), user))\n\n\tnUser := user.Build()\n\tif r := cmp.Diff(nUser, &protocol.User{\n\t\tLevel: 1,\n\t\tEmail: \"love@v2fly.org\",\n\t}, cmpopts.IgnoreUnexported(protocol.User{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestInvalidUserJson(t *testing.T) {\n\tuser := new(cfgcommon.User)\n\terr := json.Unmarshal([]byte(`{\"email\": 1234}`), user)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/duration/duration.go",
    "content": "package duration\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n)\n\ntype Duration int64\n\nfunc (d *Duration) MarshalJSON() ([]byte, error) {\n\tdr := time.Duration(*d)\n\treturn json.Marshal(dr.String())\n}\n\nfunc (d *Duration) UnmarshalJSON(b []byte) error {\n\tvar v interface{}\n\tif err := json.Unmarshal(b, &v); err != nil {\n\t\treturn err\n\t}\n\tswitch value := v.(type) {\n\tcase string:\n\t\tvar err error\n\t\tdr, err := time.ParseDuration(value)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*d = Duration(dr)\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid duration: %v\", v)\n\t}\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/duration/duration_test.go",
    "content": "package duration_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/duration\"\n)\n\ntype testWithDuration struct {\n\tDuration duration.Duration\n}\n\nfunc TestDurationJSON(t *testing.T) {\n\texpected := &testWithDuration{\n\t\tDuration: duration.Duration(time.Hour),\n\t}\n\tdata, err := json.Marshal(expected)\n\tif err != nil {\n\t\tt.Error(err)\n\t\treturn\n\t}\n\tactual := &testWithDuration{}\n\terr = json.Unmarshal(data, &actual)\n\tif err != nil {\n\t\tt.Error(err)\n\t\treturn\n\t}\n\tif actual.Duration != expected.Duration {\n\t\tt.Errorf(\"expected: %s, actual: %s\", time.Duration(expected.Duration), time.Duration(actual.Duration))\n\t}\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/errors.generated.go",
    "content": "package cfgcommon\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/loader/errors.generated.go",
    "content": "package loader\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/loader/loader.go",
    "content": "package loader\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype ConfigCreator func() interface{}\n\ntype ConfigCreatorCache map[string]ConfigCreator\n\nfunc (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {\n\tif _, found := v[id]; found {\n\t\treturn newError(id, \" already registered.\").AtError()\n\t}\n\n\tv[id] = creator\n\treturn nil\n}\n\nfunc (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {\n\tcreator, found := v[id]\n\tif !found {\n\t\treturn nil, newError(\"unknown config id: \", id)\n\t}\n\treturn creator(), nil\n}\n\ntype JSONConfigLoader struct {\n\tcache     ConfigCreatorCache\n\tidKey     string\n\tconfigKey string\n}\n\nfunc NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey string) *JSONConfigLoader {\n\treturn &JSONConfigLoader{\n\t\tidKey:     idKey,\n\t\tconfigKey: configKey,\n\t\tcache:     cache,\n\t}\n}\n\nfunc (v *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {\n\tid = strings.ToLower(id)\n\tconfig, err := v.cache.CreateConfig(id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := json.Unmarshal(raw, config); err != nil {\n\t\treturn nil, err\n\t}\n\treturn config, nil\n}\n\nfunc (v *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {\n\tvar obj map[string]json.RawMessage\n\tif err := json.Unmarshal(raw, &obj); err != nil {\n\t\treturn nil, \"\", err\n\t}\n\trawID, found := obj[v.idKey]\n\tif !found {\n\t\treturn nil, \"\", newError(v.idKey, \" not found in JSON context\").AtError()\n\t}\n\tvar id string\n\tif err := json.Unmarshal(rawID, &id); err != nil {\n\t\treturn nil, \"\", err\n\t}\n\trawConfig := json.RawMessage(raw)\n\tif len(v.configKey) > 0 {\n\t\tconfigValue, found := obj[v.configKey]\n\t\tif found {\n\t\t\trawConfig = configValue\n\t\t} else {\n\t\t\t// Default to empty json object.\n\t\t\trawConfig = json.RawMessage([]byte(\"{}\"))\n\t\t}\n\t}\n\tconfig, err := v.LoadWithID([]byte(rawConfig), id)\n\tif err != nil {\n\t\treturn nil, id, err\n\t}\n\treturn config, id, nil\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/muxcfg/mux.go",
    "content": "package muxcfg\n\nimport \"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\ntype MuxConfig struct {\n\tEnabled     bool  `json:\"enabled\"`\n\tConcurrency int16 `json:\"concurrency\"`\n}\n\n// Build creates MultiplexingConfig, Concurrency < 0 completely disables mux.\nfunc (m *MuxConfig) Build() *proxyman.MultiplexingConfig {\n\tif m.Concurrency < 0 {\n\t\treturn nil\n\t}\n\n\tvar con uint32 = 8\n\tif m.Concurrency > 0 {\n\t\tcon = uint32(m.Concurrency)\n\t}\n\n\treturn &proxyman.MultiplexingConfig{\n\t\tEnabled:     m.Enabled,\n\t\tConcurrency: con,\n\t}\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/proxycfg/errors.generated.go",
    "content": "package proxycfg\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/proxycfg/proxy.go",
    "content": "package proxycfg\n\nimport \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\ntype ProxyConfig struct {\n\tTag                 string `json:\"tag\"`\n\tTransportLayerProxy bool   `json:\"transportLayer\"`\n}\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\n// Build implements Buildable.\nfunc (v *ProxyConfig) Build() (*internet.ProxyConfig, error) {\n\tif v.Tag == \"\" {\n\t\treturn nil, newError(\"Proxy tag is not set.\")\n\t}\n\treturn &internet.ProxyConfig{\n\t\tTag:                 v.Tag,\n\t\tTransportLayerProxy: v.TransportLayerProxy,\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/session.go",
    "content": "package cfgcommon\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n)\n\ntype configureLoadingContext int\n\nconst confContextKey = configureLoadingContext(1)\n\ntype configureLoadingEnvironment struct {\n\tgeoLoader geodata.Loader\n}\n\nfunc (c *configureLoadingEnvironment) GetGeoLoader() geodata.Loader {\n\tif c.geoLoader == nil {\n\t\tvar err error\n\t\tc.geoLoader, err = geodata.GetGeoDataLoader(\"standard\")\n\t\tcommon.Must(err)\n\t}\n\treturn c.geoLoader\n}\n\nfunc (c *configureLoadingEnvironment) doNotImpl() {}\n\ntype ConfigureLoadingEnvironmentCapabilitySet interface {\n\tGetGeoLoader() geodata.Loader\n}\n\ntype ConfigureLoadingEnvironment interface {\n\tConfigureLoadingEnvironmentCapabilitySet\n\tdoNotImpl()\n\n\t// TODO environment.BaseEnvironmentCapabilitySet\n\t// TODO environment.FileSystemCapabilitySet\n}\n\nfunc NewConfigureLoadingContext(ctx context.Context) context.Context {\n\tenvironment := &configureLoadingEnvironment{}\n\treturn context.WithValue(ctx, confContextKey, environment)\n}\n\nfunc GetConfigureLoadingEnvironment(ctx context.Context) ConfigureLoadingEnvironment {\n\treturn ctx.Value(confContextKey).(ConfigureLoadingEnvironment)\n}\n\nfunc SetGeoDataLoader(ctx context.Context, loader geodata.Loader) {\n\tGetConfigureLoadingEnvironment(ctx).(*configureLoadingEnvironment).geoLoader = loader\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/sniffer/errors.generated.go",
    "content": "package sniffer\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/sniffer/sniffer.go",
    "content": "package sniffer\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype SniffingConfig struct {\n\tEnabled      bool                  `json:\"enabled\"`\n\tDestOverride *cfgcommon.StringList `json:\"destOverride\"`\n\tMetadataOnly bool                  `json:\"metadataOnly\"`\n}\n\n// Build implements Buildable.\nfunc (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) {\n\tvar p []string\n\tif c.DestOverride != nil {\n\t\tfor _, domainOverride := range *c.DestOverride {\n\t\t\tswitch strings.ToLower(domainOverride) {\n\t\t\tcase \"http\":\n\t\t\t\tp = append(p, \"http\")\n\t\t\tcase \"tls\", \"https\", \"ssl\":\n\t\t\t\tp = append(p, \"tls\")\n\t\t\tcase \"quic\":\n\t\t\t\tp = append(p, \"quic\")\n\t\t\tcase \"fakedns\":\n\t\t\t\tp = append(p, \"fakedns\")\n\t\t\tcase \"fakedns+others\":\n\t\t\t\tp = append(p, \"fakedns+others\")\n\t\t\tdefault:\n\t\t\t\treturn nil, newError(\"unknown protocol: \", domainOverride)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &proxyman.SniffingConfig{\n\t\tEnabled:             c.Enabled,\n\t\tDestinationOverride: p,\n\t\tMetadataOnly:        c.MetadataOnly,\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/socketcfg/socket.go",
    "content": "package socketcfg\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype SocketConfig struct {\n\tMark                 uint32 `json:\"mark\"`\n\tTFO                  *bool  `json:\"tcpFastOpen\"`\n\tTProxy               string `json:\"tproxy\"`\n\tAcceptProxyProtocol  bool   `json:\"acceptProxyProtocol\"`\n\tTCPKeepAliveInterval int32  `json:\"tcpKeepAliveInterval\"`\n\tTCPKeepAliveIdle     int32  `json:\"tcpKeepAliveIdle\"`\n\tTFOQueueLength       uint32 `json:\"tcpFastOpenQueueLength\"`\n\tBindToDevice         string `json:\"bindToDevice\"`\n\tRxBufSize            uint64 `json:\"rxBufSize\"`\n\tTxBufSize            uint64 `json:\"txBufSize\"`\n\tForceBufSize         bool   `json:\"forceBufSize\"`\n\tMPTCP                *bool  `json:\"mptcp\"`\n}\n\n// Build implements Buildable.\nfunc (c *SocketConfig) Build() (*internet.SocketConfig, error) {\n\tvar tfoSettings internet.SocketConfig_TCPFastOpenState\n\tif c.TFO != nil {\n\t\tif *c.TFO {\n\t\t\ttfoSettings = internet.SocketConfig_Enable\n\t\t} else {\n\t\t\ttfoSettings = internet.SocketConfig_Disable\n\t\t}\n\t}\n\n\ttfoQueueLength := c.TFOQueueLength\n\tif tfoQueueLength == 0 {\n\t\ttfoQueueLength = 4096\n\t}\n\n\tvar tproxy internet.SocketConfig_TProxyMode\n\tswitch strings.ToLower(c.TProxy) {\n\tcase \"tproxy\":\n\t\ttproxy = internet.SocketConfig_TProxy\n\tcase \"redirect\":\n\t\ttproxy = internet.SocketConfig_Redirect\n\tdefault:\n\t\ttproxy = internet.SocketConfig_Off\n\t}\n\n\tvar mptcpSettings internet.MPTCPState\n\tif c.MPTCP != nil {\n\t\tif *c.MPTCP {\n\t\t\tmptcpSettings = internet.MPTCPState_Enable\n\t\t} else {\n\t\t\tmptcpSettings = internet.MPTCPState_Disable\n\t\t}\n\t}\n\n\treturn &internet.SocketConfig{\n\t\tMark:                 c.Mark,\n\t\tTfo:                  tfoSettings,\n\t\tTfoQueueLength:       tfoQueueLength,\n\t\tTproxy:               tproxy,\n\t\tAcceptProxyProtocol:  c.AcceptProxyProtocol,\n\t\tTcpKeepAliveInterval: c.TCPKeepAliveInterval,\n\t\tTcpKeepAliveIdle:     c.TCPKeepAliveIdle,\n\t\tRxBufSize:            int64(c.RxBufSize),\n\t\tTxBufSize:            int64(c.TxBufSize),\n\t\tForceBufSize:         c.ForceBufSize,\n\t\tBindToDevice:         c.BindToDevice,\n\t\tMptcp:                mptcpSettings,\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/testassist/general.go",
    "content": "package testassist\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n)\n\nfunc LoadJSON(creator func() cfgcommon.Buildable) func(string) (proto.Message, error) {\n\treturn func(s string) (proto.Message, error) {\n\t\tinstance := creator()\n\t\tif err := json.Unmarshal([]byte(s), instance); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn instance.Build()\n\t}\n}\n\ntype TestCase struct {\n\tInput  string\n\tParser func(string) (proto.Message, error)\n\tOutput proto.Message\n}\n\nfunc RunMultiTestCase(t *testing.T, testCases []TestCase) {\n\tfor _, testCase := range testCases {\n\t\tactual, err := testCase.Parser(testCase.Input)\n\t\tcommon.Must(err)\n\t\tif !proto.Equal(actual, testCase.Output) {\n\t\t\tt.Fatalf(\"Failed in test case:\\n%s\\nActual:\\n%v\\nExpected:\\n%v\", testCase.Input, actual, testCase.Output)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/tlscfg/errors.generated.go",
    "content": "package tlscfg\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/cfgcommon/tlscfg/tls.go",
    "content": "package tlscfg\n\nimport (\n\t\"encoding/base64\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype TLSConfig struct {\n\tInsecure                         bool                  `json:\"allowInsecure\"`\n\tCerts                            []*TLSCertConfig      `json:\"certificates\"`\n\tServerName                       string                `json:\"serverName\"`\n\tALPN                             *cfgcommon.StringList `json:\"alpn\"`\n\tEnableSessionResumption          bool                  `json:\"enableSessionResumption\"`\n\tDisableSystemRoot                bool                  `json:\"disableSystemRoot\"`\n\tPinnedPeerCertificateChainSha256 *[]string             `json:\"pinnedPeerCertificateChainSha256\"`\n\tVerifyClientCertificate          bool                  `json:\"verifyClientCertificate\"`\n\tECHConfig                        string                `json:\"echConfig\"`\n\tECHDOHServer                     string                `json:\"echDohServer\"`\n}\n\n// Build implements Buildable.\nfunc (c *TLSConfig) Build() (proto.Message, error) {\n\tconfig := new(tls.Config)\n\tconfig.Certificate = make([]*tls.Certificate, len(c.Certs))\n\tfor idx, certConf := range c.Certs {\n\t\tcert, err := certConf.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Certificate[idx] = cert\n\t}\n\tserverName := c.ServerName\n\tconfig.AllowInsecure = c.Insecure\n\tconfig.VerifyClientCertificate = c.VerifyClientCertificate\n\tif len(c.ServerName) > 0 {\n\t\tconfig.ServerName = serverName\n\t}\n\tif c.ALPN != nil && len(*c.ALPN) > 0 {\n\t\tconfig.NextProtocol = []string(*c.ALPN)\n\t}\n\tconfig.EnableSessionResumption = c.EnableSessionResumption\n\tconfig.DisableSystemRoot = c.DisableSystemRoot\n\n\tif c.PinnedPeerCertificateChainSha256 != nil {\n\t\tconfig.PinnedPeerCertificateChainSha256 = [][]byte{}\n\t\tfor _, v := range *c.PinnedPeerCertificateChainSha256 {\n\t\t\thashValue, err := base64.StdEncoding.DecodeString(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconfig.PinnedPeerCertificateChainSha256 = append(config.PinnedPeerCertificateChainSha256, hashValue)\n\t\t}\n\t}\n\n\tif c.ECHConfig != \"\" {\n\t\tECHConfig, err := base64.StdEncoding.DecodeString(c.ECHConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid ECH Config\", c.ECHConfig)\n\t\t}\n\t\tconfig.EchConfig = ECHConfig\n\t}\n\n\tconfig.Ech_DOHserver = c.ECHDOHServer\n\n\treturn config, nil\n}\n\ntype TLSCertConfig struct {\n\tCertFile string   `json:\"certificateFile\"`\n\tCertStr  []string `json:\"certificate\"`\n\tKeyFile  string   `json:\"keyFile\"`\n\tKeyStr   []string `json:\"key\"`\n\tUsage    string   `json:\"usage\"`\n}\n\n// Build implements Buildable.\nfunc (c *TLSCertConfig) Build() (*tls.Certificate, error) {\n\tcertificate := new(tls.Certificate)\n\n\tcert, err := readFileOrString(c.CertFile, c.CertStr)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse certificate\").Base(err)\n\t}\n\tcertificate.Certificate = cert\n\n\tif len(c.KeyFile) > 0 || len(c.KeyStr) > 0 {\n\t\tkey, err := readFileOrString(c.KeyFile, c.KeyStr)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse key\").Base(err)\n\t\t}\n\t\tcertificate.Key = key\n\t}\n\n\tswitch strings.ToLower(c.Usage) {\n\tcase \"encipherment\":\n\t\tcertificate.Usage = tls.Certificate_ENCIPHERMENT\n\tcase \"verify\":\n\t\tcertificate.Usage = tls.Certificate_AUTHORITY_VERIFY\n\tcase \"verifyclient\":\n\t\tcertificate.Usage = tls.Certificate_AUTHORITY_VERIFY_CLIENT\n\tcase \"issue\":\n\t\tcertificate.Usage = tls.Certificate_AUTHORITY_ISSUE\n\tdefault:\n\t\tcertificate.Usage = tls.Certificate_ENCIPHERMENT\n\t}\n\n\treturn certificate, nil\n}\n\nfunc readFileOrString(f string, s []string) ([]byte, error) {\n\tif len(f) > 0 {\n\t\treturn filesystem.ReadFile(f)\n\t}\n\tif len(s) > 0 {\n\t\treturn []byte(strings.Join(s, \"\\n\")), nil\n\t}\n\treturn nil, newError(\"both file and bytes are empty.\")\n}\n"
  },
  {
    "path": "infra/conf/geodata/attr.go",
    "content": "package geodata\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n)\n\ntype AttributeList struct {\n\tmatcher []AttributeMatcher\n}\n\nfunc (al *AttributeList) Match(domain *routercommon.Domain) bool {\n\tfor _, matcher := range al.matcher {\n\t\tif !matcher.Match(domain) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (al *AttributeList) IsEmpty() bool {\n\treturn len(al.matcher) == 0\n}\n\nfunc parseAttrs(attrs []string) *AttributeList {\n\tal := new(AttributeList)\n\tfor _, attr := range attrs {\n\t\ttrimmedAttr := strings.ToLower(strings.TrimSpace(attr))\n\t\tif len(trimmedAttr) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tal.matcher = append(al.matcher, BooleanMatcher(trimmedAttr))\n\t}\n\treturn al\n}\n\ntype AttributeMatcher interface {\n\tMatch(*routercommon.Domain) bool\n}\n\ntype BooleanMatcher string\n\nfunc (m BooleanMatcher) Match(domain *routercommon.Domain) bool {\n\tfor _, attr := range domain.Attribute {\n\t\tif strings.EqualFold(attr.GetKey(), string(m)) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "infra/conf/geodata/errors.generated.go",
    "content": "package geodata\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/geodata/geodata.go",
    "content": "package geodata\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n)\n\ntype loader struct {\n\tLoaderImplementation\n}\n\nfunc (l *loader) LoadGeoSite(list string) ([]*routercommon.Domain, error) {\n\treturn l.LoadGeoSiteWithAttr(\"geosite.dat\", list)\n}\n\nfunc (l *loader) LoadGeoSiteWithAttr(file string, siteWithAttr string) ([]*routercommon.Domain, error) {\n\tparts := strings.Split(siteWithAttr, \"@\")\n\tif len(parts) == 0 {\n\t\treturn nil, newError(\"empty rule\")\n\t}\n\tlist := strings.TrimSpace(parts[0])\n\tattrVal := parts[1:]\n\n\tif len(list) == 0 {\n\t\treturn nil, newError(\"empty listname in rule: \", siteWithAttr)\n\t}\n\n\tdomains, err := l.LoadSite(file, list)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tattrs := parseAttrs(attrVal)\n\tif attrs.IsEmpty() {\n\t\tif strings.Contains(siteWithAttr, \"@\") {\n\t\t\tnewError(\"empty attribute list: \", siteWithAttr)\n\t\t}\n\t\treturn domains, nil\n\t}\n\n\tfilteredDomains := make([]*routercommon.Domain, 0, len(domains))\n\thasAttrMatched := false\n\tfor _, domain := range domains {\n\t\tif attrs.Match(domain) {\n\t\t\thasAttrMatched = true\n\t\t\tfilteredDomains = append(filteredDomains, domain)\n\t\t}\n\t}\n\tif !hasAttrMatched {\n\t\tnewError(\"attribute match no rule: geosite:\", siteWithAttr)\n\t}\n\n\treturn filteredDomains, nil\n}\n\nfunc (l *loader) LoadGeoIP(country string) ([]*routercommon.CIDR, error) {\n\treturn l.LoadIP(\"geoip.dat\", country)\n}\n\nvar loaders map[string]func() LoaderImplementation\n\nfunc RegisterGeoDataLoaderImplementationCreator(name string, loader func() LoaderImplementation) {\n\tif loaders == nil {\n\t\tloaders = map[string]func() LoaderImplementation{}\n\t}\n\tloaders[name] = loader\n}\n\nfunc getGeoDataLoaderImplementation(name string) (LoaderImplementation, error) {\n\tif geoLoader, ok := loaders[name]; ok {\n\t\treturn geoLoader(), nil\n\t}\n\treturn nil, newError(\"unable to locate GeoData loader \", name)\n}\n\nfunc GetGeoDataLoader(name string) (Loader, error) {\n\tloadImpl, err := getGeoDataLoaderImplementation(name)\n\tif err == nil {\n\t\treturn &loader{loadImpl}, nil\n\t}\n\treturn nil, err\n}\n"
  },
  {
    "path": "infra/conf/geodata/geodata_test.go",
    "content": "package geodata_test\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/memconservative\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard\"\n)\n\nfunc init() {\n\tconst (\n\t\tgeoipURL   = \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat\"\n\t\tgeositeURL = \"https://raw.githubusercontent.com/v2fly/domain-list-community/release/dlc.dat\"\n\t)\n\n\twd, err := os.Getwd()\n\tcommon.Must(err)\n\n\ttempPath := filepath.Join(wd, \"..\", \"..\", \"..\", \"testing\", \"temp\")\n\tgeoipPath := filepath.Join(tempPath, \"geoip.dat\")\n\tgeositePath := filepath.Join(tempPath, \"geosite.dat\")\n\n\tos.Setenv(\"v2ray.location.asset\", tempPath)\n\n\tif _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeoipBytes, err := common.FetchHTTPContent(geoipURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geoipPath, geoipBytes))\n\t}\n\tif _, err := os.Stat(geositePath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeositeBytes, err := common.FetchHTTPContent(geositeURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geositePath, geositeBytes))\n\t}\n}\n\nfunc BenchmarkStandardLoaderGeoIP(b *testing.B) {\n\tstandardLoader, err := geodata.GetGeoDataLoader(\"standard\")\n\tcommon.Must(err)\n\n\tm1 := runtime.MemStats{}\n\tm2 := runtime.MemStats{}\n\truntime.ReadMemStats(&m1)\n\tstandardLoader.LoadGeoIP(\"cn\")\n\tstandardLoader.LoadGeoIP(\"us\")\n\tstandardLoader.LoadGeoIP(\"private\")\n\truntime.ReadMemStats(&m2)\n\n\tb.ReportMetric(float64(m2.Alloc-m1.Alloc)/1024/1024, \"MiB(GeoIP-Alloc)\")\n\tb.ReportMetric(float64(m2.TotalAlloc-m1.TotalAlloc)/1024/1024, \"MiB(GeoIP-TotalAlloc)\")\n}\n\nfunc BenchmarkStandardLoaderGeoSite(b *testing.B) {\n\tstandardLoader, err := geodata.GetGeoDataLoader(\"standard\")\n\tcommon.Must(err)\n\n\tm3 := runtime.MemStats{}\n\tm4 := runtime.MemStats{}\n\truntime.ReadMemStats(&m3)\n\tstandardLoader.LoadGeoSite(\"cn\")\n\tstandardLoader.LoadGeoSite(\"geolocation-!cn\")\n\tstandardLoader.LoadGeoSite(\"private\")\n\truntime.ReadMemStats(&m4)\n\n\tb.ReportMetric(float64(m4.Alloc-m3.Alloc)/1024/1024, \"MiB(GeoSite-Alloc)\")\n\tb.ReportMetric(float64(m4.TotalAlloc-m3.TotalAlloc)/1024/1024, \"MiB(GeoSite-TotalAlloc)\")\n}\n\nfunc BenchmarkMemconservativeLoaderGeoIP(b *testing.B) {\n\tstandardLoader, err := geodata.GetGeoDataLoader(\"memconservative\")\n\tcommon.Must(err)\n\n\tm1 := runtime.MemStats{}\n\tm2 := runtime.MemStats{}\n\truntime.ReadMemStats(&m1)\n\tstandardLoader.LoadGeoIP(\"cn\")\n\tstandardLoader.LoadGeoIP(\"us\")\n\tstandardLoader.LoadGeoIP(\"private\")\n\truntime.ReadMemStats(&m2)\n\n\tb.ReportMetric(float64(m2.Alloc-m1.Alloc)/1024, \"KiB(GeoIP-Alloc)\")\n\tb.ReportMetric(float64(m2.TotalAlloc-m1.TotalAlloc)/1024/1024, \"MiB(GeoIP-TotalAlloc)\")\n}\n\nfunc BenchmarkMemconservativeLoaderGeoSite(b *testing.B) {\n\tstandardLoader, err := geodata.GetGeoDataLoader(\"memconservative\")\n\tcommon.Must(err)\n\n\tm3 := runtime.MemStats{}\n\tm4 := runtime.MemStats{}\n\truntime.ReadMemStats(&m3)\n\tstandardLoader.LoadGeoSite(\"cn\")\n\tstandardLoader.LoadGeoSite(\"geolocation-!cn\")\n\tstandardLoader.LoadGeoSite(\"private\")\n\truntime.ReadMemStats(&m4)\n\n\tb.ReportMetric(float64(m4.Alloc-m3.Alloc)/1024, \"KiB(GeoSite-Alloc)\")\n\tb.ReportMetric(float64(m4.TotalAlloc-m3.TotalAlloc)/1024/1024, \"MiB(GeoSite-TotalAlloc)\")\n}\n\nfunc BenchmarkAllLoader(b *testing.B) {\n\ttype testingProfileForLoader struct {\n\t\tname string\n\t}\n\ttestCase := []testingProfileForLoader{\n\t\t{\"standard\"},\n\t\t{\"memconservative\"},\n\t}\n\tfor _, v := range testCase {\n\t\tb.Run(v.name, func(b *testing.B) {\n\t\t\tb.Run(\"Geosite\", func(b *testing.B) {\n\t\t\t\tloader, err := geodata.GetGeoDataLoader(v.name)\n\t\t\t\tif err != nil {\n\t\t\t\t\tb.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tm3 := runtime.MemStats{}\n\t\t\t\tm4 := runtime.MemStats{}\n\t\t\t\truntime.ReadMemStats(&m3)\n\t\t\t\tloader.LoadGeoSite(\"cn\")\n\t\t\t\tloader.LoadGeoSite(\"geolocation-!cn\")\n\t\t\t\tloader.LoadGeoSite(\"private\")\n\t\t\t\truntime.ReadMemStats(&m4)\n\n\t\t\t\tb.ReportMetric(float64(m4.Alloc-m3.Alloc)/1024, \"KiB(GeoSite-Alloc)\")\n\t\t\t\tb.ReportMetric(float64(m4.TotalAlloc-m3.TotalAlloc)/1024/1024, \"MiB(GeoSite-TotalAlloc)\")\n\t\t\t})\n\n\t\t\tb.Run(\"GeoIP\", func(b *testing.B) {\n\t\t\t\tloader, err := geodata.GetGeoDataLoader(v.name)\n\t\t\t\tif err != nil {\n\t\t\t\t\tb.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tm1 := runtime.MemStats{}\n\t\t\t\tm2 := runtime.MemStats{}\n\t\t\t\truntime.ReadMemStats(&m1)\n\t\t\t\tloader.LoadGeoIP(\"cn\")\n\t\t\t\tloader.LoadGeoIP(\"us\")\n\t\t\t\tloader.LoadGeoIP(\"private\")\n\t\t\t\truntime.ReadMemStats(&m2)\n\n\t\t\t\tb.ReportMetric(float64(m2.Alloc-m1.Alloc)/1024/1024, \"MiB(GeoIP-Alloc)\")\n\t\t\t\tb.ReportMetric(float64(m2.TotalAlloc-m1.TotalAlloc)/1024/1024, \"MiB(GeoIP-TotalAlloc)\")\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "infra/conf/geodata/geodataproto.go",
    "content": "package geodata\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype LoaderImplementation interface {\n\tLoadSite(filename, list string) ([]*routercommon.Domain, error)\n\tLoadIP(filename, country string) ([]*routercommon.CIDR, error)\n}\n\ntype Loader interface {\n\tLoaderImplementation\n\tLoadGeoSite(list string) ([]*routercommon.Domain, error)\n\tLoadGeoSiteWithAttr(file string, siteWithAttr string) ([]*routercommon.Domain, error)\n\tLoadGeoIP(country string) ([]*routercommon.CIDR, error)\n}\n"
  },
  {
    "path": "infra/conf/geodata/memconservative/cache.go",
    "content": "package memconservative\n\nimport (\n\t\"os\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n)\n\ntype GeoIPCache map[string]*routercommon.GeoIP\n\nfunc (g GeoIPCache) Has(key string) bool {\n\treturn !(g.Get(key) == nil)\n}\n\nfunc (g GeoIPCache) Get(key string) *routercommon.GeoIP {\n\tif g == nil {\n\t\treturn nil\n\t}\n\treturn g[key]\n}\n\nfunc (g GeoIPCache) Set(key string, value *routercommon.GeoIP) {\n\tif g == nil {\n\t\tg = make(map[string]*routercommon.GeoIP)\n\t}\n\tg[key] = value\n}\n\nfunc (g GeoIPCache) Unmarshal(filename, code string) (*routercommon.GeoIP, error) {\n\tasset := platform.GetAssetLocation(filename)\n\tidx := strings.ToLower(asset + \":\" + code)\n\tif g.Has(idx) {\n\t\treturn g.Get(idx), nil\n\t}\n\n\tgeoipBytes, err := Decode(asset, code)\n\tswitch err {\n\tcase nil:\n\t\tvar geoip routercommon.GeoIP\n\t\tif err := proto.Unmarshal(geoipBytes, &geoip); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tg.Set(idx, &geoip)\n\t\treturn &geoip, nil\n\n\tcase errCodeNotFound:\n\t\treturn nil, newError(\"country code \", code, \" not found in \", filename)\n\n\tcase errFailedToReadBytes, errFailedToReadExpectedLenBytes,\n\t\terrInvalidGeodataFile, errInvalidGeodataVarintLength:\n\t\tnewError(\"failed to decode geoip file: \", filename, \", fallback to the original ReadFile method\")\n\t\tgeoipBytes, err = os.ReadFile(asset)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar geoipList routercommon.GeoIPList\n\t\tif err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, geoip := range geoipList.GetEntry() {\n\t\t\tif strings.EqualFold(code, geoip.GetCountryCode()) {\n\t\t\t\tg.Set(idx, geoip)\n\t\t\t\treturn geoip, nil\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\treturn nil, err\n\t}\n\n\treturn nil, newError(\"country code \", code, \" not found in \", filename)\n}\n\ntype GeoSiteCache map[string]*routercommon.GeoSite\n\nfunc (g GeoSiteCache) Has(key string) bool {\n\treturn !(g.Get(key) == nil)\n}\n\nfunc (g GeoSiteCache) Get(key string) *routercommon.GeoSite {\n\tif g == nil {\n\t\treturn nil\n\t}\n\treturn g[key]\n}\n\nfunc (g GeoSiteCache) Set(key string, value *routercommon.GeoSite) {\n\tif g == nil {\n\t\tg = make(map[string]*routercommon.GeoSite)\n\t}\n\tg[key] = value\n}\n\nfunc (g GeoSiteCache) Unmarshal(filename, code string) (*routercommon.GeoSite, error) {\n\tasset := platform.GetAssetLocation(filename)\n\tidx := strings.ToLower(asset + \":\" + code)\n\tif g.Has(idx) {\n\t\treturn g.Get(idx), nil\n\t}\n\n\tgeositeBytes, err := Decode(asset, code)\n\tswitch err {\n\tcase nil:\n\t\tvar geosite routercommon.GeoSite\n\t\tif err := proto.Unmarshal(geositeBytes, &geosite); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tg.Set(idx, &geosite)\n\t\treturn &geosite, nil\n\n\tcase errCodeNotFound:\n\t\treturn nil, newError(\"list \", code, \" not found in \", filename)\n\n\tcase errFailedToReadBytes, errFailedToReadExpectedLenBytes,\n\t\terrInvalidGeodataFile, errInvalidGeodataVarintLength:\n\t\tnewError(\"failed to decode geoip file: \", filename, \", fallback to the original ReadFile method\")\n\t\tgeositeBytes, err = os.ReadFile(asset)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar geositeList routercommon.GeoSiteList\n\t\tif err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, geosite := range geositeList.GetEntry() {\n\t\t\tif strings.EqualFold(code, geosite.GetCountryCode()) {\n\t\t\t\tg.Set(idx, geosite)\n\t\t\t\treturn geosite, nil\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\treturn nil, err\n\t}\n\n\treturn nil, newError(\"list \", code, \" not found in \", filename)\n}\n"
  },
  {
    "path": "infra/conf/geodata/memconservative/decode.go",
    "content": "package memconservative\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/encoding/protowire\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n)\n\nvar (\n\terrFailedToReadBytes            = errors.New(\"failed to read bytes\")\n\terrFailedToReadExpectedLenBytes = errors.New(\"failed to read expected length of bytes\")\n\terrInvalidGeodataFile           = errors.New(\"invalid geodata file\")\n\terrInvalidGeodataVarintLength   = errors.New(\"invalid geodata varint length\")\n\terrCodeNotFound                 = errors.New(\"code not found\")\n)\n\nfunc emitBytes(f io.ReadSeeker, code string) ([]byte, error) {\n\tcount := 1\n\tisInner := false\n\ttempContainer := make([]byte, 0, 5)\n\n\tvar result []byte\n\tvar advancedN uint64 = 1\n\tvar geoDataVarintLength, codeVarintLength, varintLenByteLen uint64 = 0, 0, 0\n\nLoop:\n\tfor {\n\t\tcontainer := make([]byte, advancedN)\n\t\tbytesRead, err := f.Read(container)\n\t\tif err == io.EOF {\n\t\t\treturn nil, errCodeNotFound\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, errFailedToReadBytes\n\t\t}\n\t\tif bytesRead != len(container) {\n\t\t\treturn nil, errFailedToReadExpectedLenBytes\n\t\t}\n\n\t\tswitch count {\n\t\tcase 1, 3: // data type ((field_number << 3) | wire_type)\n\t\t\tif container[0] != 10 { // byte `0A` equals to `10` in decimal\n\t\t\t\treturn nil, errInvalidGeodataFile\n\t\t\t}\n\t\t\tadvancedN = 1\n\t\t\tcount++\n\t\tcase 2, 4: // data length\n\t\t\ttempContainer = append(tempContainer, container...)\n\t\t\tif container[0] > 127 { // max one-byte-length byte `7F`(0FFF FFFF) equals to `127` in decimal\n\t\t\t\tadvancedN = 1\n\t\t\t\tgoto Loop\n\t\t\t}\n\t\t\tlenVarint, n := protowire.ConsumeVarint(tempContainer)\n\t\t\tif n < 0 {\n\t\t\t\treturn nil, errInvalidGeodataVarintLength\n\t\t\t}\n\t\t\ttempContainer = nil\n\t\t\tif !isInner {\n\t\t\t\tisInner = true\n\t\t\t\tgeoDataVarintLength = lenVarint\n\t\t\t\tadvancedN = 1\n\t\t\t} else {\n\t\t\t\tisInner = false\n\t\t\t\tcodeVarintLength = lenVarint\n\t\t\t\tvarintLenByteLen = uint64(n)\n\t\t\t\tadvancedN = codeVarintLength\n\t\t\t}\n\t\t\tcount++\n\t\tcase 5: // data value\n\t\t\tif strings.EqualFold(string(container), code) {\n\t\t\t\tcount++\n\t\t\t\toffset := -(1 + int64(varintLenByteLen) + int64(codeVarintLength))\n\t\t\t\tf.Seek(offset, 1)               // back to the start of GeoIP or GeoSite varint\n\t\t\t\tadvancedN = geoDataVarintLength // the number of bytes to be read in next round\n\t\t\t} else {\n\t\t\t\tcount = 1\n\t\t\t\toffset := int64(geoDataVarintLength) - int64(codeVarintLength) - int64(varintLenByteLen) - 1\n\t\t\t\tf.Seek(offset, 1) // skip the unmatched GeoIP or GeoSite varint\n\t\t\t\tadvancedN = 1     // the next round will be the start of another GeoIPList or GeoSiteList\n\t\t\t}\n\t\tcase 6: // matched GeoIP or GeoSite varint\n\t\t\tresult = container\n\t\t\tbreak Loop\n\t\t}\n\t}\n\treturn result, nil\n}\n\nfunc Decode(filename, code string) ([]byte, error) {\n\tf, err := filesystem.NewFileSeeker(filename)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to open file: \", filename).Base(err)\n\t}\n\tdefer f.Close()\n\n\tgeoBytes, err := emitBytes(f, code)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn geoBytes, nil\n}\n"
  },
  {
    "path": "infra/conf/geodata/memconservative/decode_test.go",
    "content": "package memconservative\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n)\n\nfunc init() {\n\tconst (\n\t\tgeoipURL   = \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat\"\n\t\tgeositeURL = \"https://raw.githubusercontent.com/v2fly/domain-list-community/release/dlc.dat\"\n\t)\n\n\twd, err := os.Getwd()\n\tcommon.Must(err)\n\n\ttempPath := filepath.Join(wd, \"..\", \"..\", \"..\", \"..\", \"testing\", \"temp\")\n\tgeoipPath := filepath.Join(tempPath, \"geoip.dat\")\n\tgeositePath := filepath.Join(tempPath, \"geosite.dat\")\n\n\tos.Setenv(\"v2ray.location.asset\", tempPath)\n\n\tif _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeoipBytes, err := common.FetchHTTPContent(geoipURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geoipPath, geoipBytes))\n\t}\n\tif _, err := os.Stat(geositePath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeositeBytes, err := common.FetchHTTPContent(geositeURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geositePath, geositeBytes))\n\t}\n}\n\nfunc TestDecodeGeoIP(t *testing.T) {\n\tfilename := platform.GetAssetLocation(\"geoip.dat\")\n\tresult, err := Decode(filename, \"test\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\texpected := []byte{10, 4, 84, 69, 83, 84, 18, 8, 10, 4, 127, 0, 0, 0, 16, 8}\n\tif !bytes.Equal(result, expected) {\n\t\tt.Errorf(\"failed to load geoip:test, expected: %v, got: %v\", expected, result)\n\t}\n}\n\nfunc TestDecodeGeoSite(t *testing.T) {\n\tfilename := platform.GetAssetLocation(\"geosite.dat\")\n\tresult, err := Decode(filename, \"test\")\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\texpected := []byte{10, 4, 84, 69, 83, 84, 18, 20, 8, 3, 18, 16, 116, 101, 115, 116, 46, 101, 120, 97, 109, 112, 108, 101, 46, 99, 111, 109}\n\tif !bytes.Equal(result, expected) {\n\t\tt.Errorf(\"failed to load geosite:test, expected: %v, got: %v\", expected, result)\n\t}\n}\n"
  },
  {
    "path": "infra/conf/geodata/memconservative/errors.generated.go",
    "content": "package memconservative\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/geodata/memconservative/memc.go",
    "content": "package memconservative\n\nimport (\n\t\"runtime\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype memConservativeLoader struct {\n\tgeoipcache   GeoIPCache\n\tgeositecache GeoSiteCache\n}\n\nfunc (m *memConservativeLoader) LoadIP(filename, country string) ([]*routercommon.CIDR, error) {\n\tdefer runtime.GC()\n\tgeoip, err := m.geoipcache.Unmarshal(filename, country)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to decode geodata file: \", filename).Base(err)\n\t}\n\treturn geoip.Cidr, nil\n}\n\nfunc (m *memConservativeLoader) LoadSite(filename, list string) ([]*routercommon.Domain, error) {\n\tdefer runtime.GC()\n\tgeosite, err := m.geositecache.Unmarshal(filename, list)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to decode geodata file: \", filename).Base(err)\n\t}\n\treturn geosite.Domain, nil\n}\n\nfunc newMemConservativeLoader() geodata.LoaderImplementation {\n\treturn &memConservativeLoader{make(map[string]*routercommon.GeoIP), make(map[string]*routercommon.GeoSite)}\n}\n\nfunc init() {\n\tgeodata.RegisterGeoDataLoaderImplementationCreator(\"memconservative\", newMemConservativeLoader)\n}\n"
  },
  {
    "path": "infra/conf/geodata/standard/errors.generated.go",
    "content": "package standard\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/geodata/standard/standard.go",
    "content": "package standard\n\nimport (\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc loadIP(filename, country string) ([]*routercommon.CIDR, error) {\n\tgeoipBytes, err := filesystem.ReadAsset(filename)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to open file: \", filename).Base(err)\n\t}\n\tvar geoipList routercommon.GeoIPList\n\tif err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, geoip := range geoipList.Entry {\n\t\tif strings.EqualFold(geoip.CountryCode, country) {\n\t\t\treturn geoip.Cidr, nil\n\t\t}\n\t}\n\n\treturn nil, newError(\"country not found in \", filename, \": \", country)\n}\n\nfunc loadSite(filename, list string) ([]*routercommon.Domain, error) {\n\tgeositeBytes, err := filesystem.ReadAsset(filename)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to open file: \", filename).Base(err)\n\t}\n\tvar geositeList routercommon.GeoSiteList\n\tif err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, site := range geositeList.Entry {\n\t\tif strings.EqualFold(site.CountryCode, list) {\n\t\t\treturn site.Domain, nil\n\t\t}\n\t}\n\n\treturn nil, newError(\"list not found in \", filename, \": \", list)\n}\n\ntype standardLoader struct{}\n\nfunc (d standardLoader) LoadSite(filename, list string) ([]*routercommon.Domain, error) {\n\treturn loadSite(filename, list)\n}\n\nfunc (d standardLoader) LoadIP(filename, country string) ([]*routercommon.CIDR, error) {\n\treturn loadIP(filename, country)\n}\n\nfunc init() {\n\tgeodata.RegisterGeoDataLoaderImplementationCreator(\"standard\", func() geodata.LoaderImplementation {\n\t\treturn standardLoader{}\n\t})\n}\n"
  },
  {
    "path": "infra/conf/json/json_test.go",
    "content": "package json_test\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc assertResult(t *testing.T, value map[string]interface{}, expected string) {\n\te := make(map[string]interface{})\n\terr := json.Unmarshal([]byte(expected), &e)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif !reflect.DeepEqual(value, e) {\n\t\tbs, _ := json.Marshal(value)\n\t\tt.Fatalf(\"expected:\\n%s\\n\\nactual:\\n%s\", expected, string(bs))\n\t}\n}\n"
  },
  {
    "path": "infra/conf/json/reader.go",
    "content": "package json\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\n// State is the internal state of parser.\ntype State byte\n\nconst (\n\tStateContent State = iota\n\tStateEscape\n\tStateDoubleQuote\n\tStateDoubleQuoteEscape\n\tStateSingleQuote\n\tStateSingleQuoteEscape\n\tStateComment\n\tStateSlash\n\tStateMultilineComment\n\tStateMultilineCommentStar\n)\n\n// Reader is a reader for filtering comments.\n// It supports Java style single and multi line comment syntax, and Python style single line comment syntax.\ntype Reader struct {\n\tio.Reader\n\n\tstate   State\n\tpending []byte\n\tbr      *buf.BufferedReader\n}\n\n// Read implements io.Reader.Read().\nfunc (v *Reader) Read(b []byte) (int, error) {\n\tif v.br == nil {\n\t\tv.br = &buf.BufferedReader{Reader: buf.NewReader(v.Reader)}\n\t}\n\n\tp := b[:0]\n\tfor len(p) < len(b) {\n\t\tif len(v.pending) > 0 {\n\t\t\tmax := len(b) - len(p)\n\t\t\tif max > len(v.pending) {\n\t\t\t\tmax = len(v.pending)\n\t\t\t}\n\t\t\tp = append(p, v.pending[:max]...)\n\t\t\tv.pending = v.pending[max:]\n\t\t\tcontinue\n\t\t}\n\n\t\tx, err := v.br.ReadByte()\n\t\tif err != nil {\n\t\t\tif len(p) == 0 {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\treturn len(p), nil\n\t\t}\n\t\tswitch v.state {\n\t\tcase StateContent:\n\t\t\tswitch x {\n\t\t\tcase '\"':\n\t\t\t\tv.state = StateDoubleQuote\n\t\t\t\tp = append(p, x)\n\t\t\tcase '\\'':\n\t\t\t\tv.state = StateSingleQuote\n\t\t\t\tp = append(p, x)\n\t\t\tcase '\\\\':\n\t\t\t\tv.state = StateEscape\n\t\t\t\tp = append(p, x)\n\t\t\tcase '#':\n\t\t\t\tv.state = StateComment\n\t\t\tcase '/':\n\t\t\t\tv.state = StateSlash\n\t\t\tdefault:\n\t\t\t\tp = append(p, x)\n\t\t\t}\n\t\tcase StateEscape:\n\t\t\tp = append(p, x)\n\t\t\tv.state = StateContent\n\t\tcase StateDoubleQuote:\n\t\t\tswitch x {\n\t\t\tcase '\"':\n\t\t\t\tv.state = StateContent\n\t\t\t\tp = append(p, x)\n\t\t\tcase '\\\\':\n\t\t\t\tv.state = StateDoubleQuoteEscape\n\t\t\t\tp = append(p, x)\n\t\t\tdefault:\n\t\t\t\tp = append(p, x)\n\t\t\t}\n\t\tcase StateDoubleQuoteEscape:\n\t\t\tp = append(p, x)\n\t\t\tv.state = StateDoubleQuote\n\t\tcase StateSingleQuote:\n\t\t\tswitch x {\n\t\t\tcase '\\'':\n\t\t\t\tv.state = StateContent\n\t\t\t\tp = append(p, x)\n\t\t\tcase '\\\\':\n\t\t\t\tv.state = StateSingleQuoteEscape\n\t\t\t\tp = append(p, x)\n\t\t\tdefault:\n\t\t\t\tp = append(p, x)\n\t\t\t}\n\t\tcase StateSingleQuoteEscape:\n\t\t\tp = append(p, x)\n\t\t\tv.state = StateSingleQuote\n\t\tcase StateComment:\n\t\t\tif x == '\\n' {\n\t\t\t\tv.state = StateContent\n\t\t\t\tp = append(p, x)\n\t\t\t}\n\t\tcase StateSlash:\n\t\t\tswitch x {\n\t\t\tcase '/':\n\t\t\t\tv.state = StateComment\n\t\t\tcase '*':\n\t\t\t\tv.state = StateMultilineComment\n\t\t\tdefault:\n\t\t\t\tv.state = StateContent\n\t\t\t\tv.pending = append(v.pending, x)\n\t\t\t\tp = append(p, '/')\n\t\t\t}\n\t\tcase StateMultilineComment:\n\t\t\tswitch x {\n\t\t\tcase '*':\n\t\t\t\tv.state = StateMultilineCommentStar\n\t\t\tcase '\\n':\n\t\t\t\tp = append(p, x)\n\t\t\t}\n\t\tcase StateMultilineCommentStar:\n\t\t\tswitch x {\n\t\t\tcase '/':\n\t\t\t\tv.state = StateContent\n\t\t\tcase '*':\n\t\t\t\t// Stay\n\t\t\tcase '\\n':\n\t\t\t\tp = append(p, x)\n\t\t\tdefault:\n\t\t\t\tv.state = StateMultilineComment\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"Unknown state.\")\n\t\t}\n\t}\n\treturn len(p), nil\n}\n"
  },
  {
    "path": "infra/conf/json/reader_test.go",
    "content": "package json_test\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n)\n\nfunc TestReader(t *testing.T) {\n\tdata := []struct {\n\t\tinput  string\n\t\toutput string\n\t}{\n\t\t{\n\t\t\t`\ncontent #comment 1\n#comment 2\ncontent 2`,\n\t\t\t`\ncontent \n\ncontent 2`,\n\t\t},\n\t\t{`content`, `content`},\n\t\t{\" \", \" \"},\n\t\t{`con/*abcd*/tent`, \"content\"},\n\t\t{`\ntext // adlkhdf /*\n//comment adfkj\ntext 2*/`, `\ntext \n\ntext 2*`},\n\t\t{`\"//\"content`, `\"//\"content`},\n\t\t{`abcd'//'abcd`, `abcd'//'abcd`},\n\t\t{`\"\\\"\"`, `\"\\\"\"`},\n\t\t{`\\\"/*abcd*/\\\"`, `\\\"\\\"`},\n\t}\n\n\tfor _, testCase := range data {\n\t\treader := &Reader{\n\t\t\tReader: bytes.NewReader([]byte(testCase.input)),\n\t\t}\n\n\t\tactual := make([]byte, 1024)\n\t\tn, err := reader.Read(actual)\n\t\tcommon.Must(err)\n\t\tif r := cmp.Diff(string(actual[:n]), testCase.output); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t}\n}\n\nfunc TestReader1(t *testing.T) {\n\ttype dataStruct struct {\n\t\tinput  string\n\t\toutput string\n\t}\n\n\tbufLen := 1\n\n\tdata := []dataStruct{\n\t\t{\"loooooooooooooooooooooooooooooooooooooooog\", \"loooooooooooooooooooooooooooooooooooooooog\"},\n\t\t{`{\"t\": \"\\/testlooooooooooooooooooooooooooooong\"}`, `{\"t\": \"\\/testlooooooooooooooooooooooooooooong\"}`},\n\t\t{`{\"t\": \"\\/test\"}`, `{\"t\": \"\\/test\"}`},\n\t\t{`\"\\// fake comment\"`, `\"\\// fake comment\"`},\n\t\t{`\"\\/\\/\\/\\/\\/\"`, `\"\\/\\/\\/\\/\\/\"`},\n\t\t{`/test/test`, `/test/test`},\n\t}\n\n\tfor _, testCase := range data {\n\t\treader := &Reader{\n\t\t\tReader: bytes.NewReader([]byte(testCase.input)),\n\t\t}\n\t\ttarget := make([]byte, 0)\n\t\tbuf := make([]byte, bufLen)\n\t\tvar n int\n\t\tvar err error\n\t\tfor n, err = reader.Read(buf); err == nil; n, err = reader.Read(buf) {\n\t\t\tif n > len(buf) {\n\t\t\t\tt.Error(\"n: \", n)\n\t\t\t}\n\t\t\ttarget = append(target, buf[:n]...)\n\t\t\tbuf = make([]byte, bufLen)\n\t\t}\n\t\tif err != nil && err != io.EOF {\n\t\t\tt.Error(\"error: \", err)\n\t\t}\n\t\tif string(target) != testCase.output {\n\t\t\tt.Error(\"got \", string(target), \" want \", testCase.output)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "infra/conf/json/toml.go",
    "content": "package json\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/pelletier/go-toml\"\n)\n\n// FromTOML convert toml to json\nfunc FromTOML(v []byte) ([]byte, error) {\n\ttomlReader := bytes.NewReader(v)\n\tjsonStr, err := jsonFromTomlReader(tomlReader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn []byte(jsonStr), nil\n}\n\nfunc jsonFromTomlReader(r io.Reader) (string, error) {\n\ttree, err := toml.LoadReader(r)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn mapToJSON(tree)\n}\n\nfunc mapToJSON(tree *toml.Tree) (string, error) {\n\ttreeMap := tree.ToMap()\n\tbytes, err := json.MarshalIndent(treeMap, \"\", \"  \")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(bytes), nil\n}\n"
  },
  {
    "path": "infra/conf/json/toml_test.go",
    "content": "package json_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n)\n\nfunc TestTOMLToJSON_V2Style(t *testing.T) {\n\tinput := `\n[log]\nloglevel = 'debug'\n\n[[inbounds]]\nport = 10800\nlisten = '127.0.0.1'\nprotocol = 'socks'\n\n[inbounds.settings]\nudp = true\n\n[[outbounds]]\nprotocol = 'vmess'\n[[outbounds.settings.vnext]]\nport = 443\naddress = 'example.com'\n\n[[outbounds.settings.vnext.users]]\nid = '98a15fa6-2eb1-edd5-50ea-cfc428aaab78'\n\n[outbounds.streamSettings]\nnetwork = 'tcp'\nsecurity = 'tls'\n`\n\texpected := `\n{\n    \"log\": {\n        \"loglevel\": \"debug\"\n    },\n    \"inbounds\": [{\n        \"port\": 10800,\n        \"listen\": \"127.0.0.1\",\n        \"protocol\": \"socks\",\n        \"settings\": {\n            \"udp\": true\n        }\n    }],\n    \"outbounds\": [{\n        \"protocol\": \"vmess\",\n        \"settings\": {\n            \"vnext\": [{\n                \"port\": 443,\n                \"address\": \"example.com\",\n                \"users\": [{\n                    \"id\": \"98a15fa6-2eb1-edd5-50ea-cfc428aaab78\"\n                }]\n            }]\n        },\n        \"streamSettings\": {\n            \"network\": \"tcp\",\n            \"security\": \"tls\"\n        }\n    }]\n}\n`\n\tbs, err := FromTOML([]byte(input))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tm := make(map[string]interface{})\n\tjson.Unmarshal(bs, &m)\n\tassertResult(t, m, expected)\n}\n\nfunc TestTOMLToJSON_ValueTypes(t *testing.T) {\n\tinput := `\nboolean = [ true, false, true, false ]\nfloat = [ 3.14, 685_230.15 ]\nint = [ 123, 685_230 ]\nstring = [ \"哈哈\", \"Hello world\", \"newline newline2\" ]\ndate = [ \"2018-02-17\" ]\ndatetime = [ \"2018-02-17T15:02:31+08:00\" ]\n1 = 0\ntrue = true\nstr = \"hello\"\n\n[null]\nnodeName = \"node\"\n`\n\texpected := `\n{\n    \"boolean\": [true, false, true, false],\n    \"float\": [3.14, 685230.15],\n    \"int\": [123, 685230],\n    \"null\": {\n        \"nodeName\": \"node\"\n    },\n    \"string\": [\"哈哈\", \"Hello world\",  \"newline newline2\"],\n    \"date\": [\"2018-02-17\"],\n    \"datetime\": [\"2018-02-17T15:02:31+08:00\"],\n    \"1\": 0,\n    \"true\": true,\n    \"str\": \"hello\"\n}\n`\n\tbs, err := FromTOML([]byte(input))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tm := make(map[string]interface{})\n\tjson.Unmarshal(bs, &m)\n\tassertResult(t, m, expected)\n}\n"
  },
  {
    "path": "infra/conf/json/yaml.go",
    "content": "package json\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"gopkg.in/yaml.v3\"\n)\n\n// FromYAML convert yaml to json\nfunc FromYAML(v []byte) ([]byte, error) {\n\tm1 := make(map[interface{}]interface{})\n\terr := yaml.Unmarshal(v, &m1)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tm2 := convert(m1)\n\tj, err := json.Marshal(m2)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn j, nil\n}\n\nfunc convert(m map[interface{}]interface{}) map[string]interface{} {\n\tres := map[string]interface{}{}\n\tfor k, v := range m {\n\t\tvar value interface{}\n\t\tswitch v2 := v.(type) {\n\t\tcase map[interface{}]interface{}:\n\t\t\tvalue = convert(v2)\n\t\tcase []interface{}:\n\t\t\tfor i, el := range v2 {\n\t\t\t\tif m, ok := el.(map[interface{}]interface{}); ok {\n\t\t\t\t\tv2[i] = convert(m)\n\t\t\t\t}\n\t\t\t}\n\t\t\tvalue = v2\n\t\tdefault:\n\t\t\tvalue = v\n\t\t}\n\t\tkey := \"null\"\n\t\tif k != nil {\n\t\t\tkey = fmt.Sprint(k)\n\t\t}\n\t\tres[key] = value\n\t}\n\treturn res\n}\n"
  },
  {
    "path": "infra/conf/json/yaml_test.go",
    "content": "package json_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n)\n\nfunc TestYMLToJSON_V2Style(t *testing.T) {\n\tinput := `\nlog:\n  loglevel: debug\ninbounds:\n- port: 10800\n  listen: 127.0.0.1\n  protocol: socks\n  settings:\n    udp: true\noutbounds:\n- protocol: vmess\n  settings:\n    vnext:\n    - address: example.com\n      port: 443\n      users:\n      - id: '98a15fa6-2eb1-edd5-50ea-cfc428aaab78'\n  streamSettings:\n    network: tcp\n    security: tls\n`\n\texpected := `\n{\n    \"log\": {\n        \"loglevel\": \"debug\"\n    },\n    \"inbounds\": [{\n        \"port\": 10800,\n        \"listen\": \"127.0.0.1\",\n        \"protocol\": \"socks\",\n        \"settings\": {\n            \"udp\": true\n        }\n    }],\n    \"outbounds\": [{\n        \"protocol\": \"vmess\",\n        \"settings\": {\n            \"vnext\": [{\n                \"port\": 443,\n                \"address\": \"example.com\",\n                \"users\": [{\n                    \"id\": \"98a15fa6-2eb1-edd5-50ea-cfc428aaab78\"\n                }]\n            }]\n        },\n        \"streamSettings\": {\n            \"network\": \"tcp\",\n            \"security\": \"tls\"\n        }\n    }]\n}\n`\n\tbs, err := FromYAML([]byte(input))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tm := make(map[string]interface{})\n\tjson.Unmarshal(bs, &m)\n\tassertResult(t, m, expected)\n}\n\nfunc TestYMLToJSON_ValueTypes(t *testing.T) {\n\tinput := `\nboolean: \n    - TRUE\n    - FALSE\n    - true\n    - false\nfloat:\n    - 3.14\n    - 6.8523015e+5\nint:\n    - 123\n    - 0b1010_0111_0100_1010_1110\nnull:\n    nodeName: 'node'\n    parent: ~  # ~ for null\nstring:\n    - 哈哈\n    - 'Hello world'\n    - newline\n      newline2    # multi-line string\ndate:\n    - 2018-02-17    # yyyy-MM-dd\ndatetime: \n    -  2018-02-17T15:02:31+08:00    # ISO 8601 time\nmixed:\n    - true\n    - false\n    - 1\n    - 0\n    - null\n    - hello\n# arbitrary keys\n1: 0\ntrue: false\nTRUE: TRUE\n\"str\": \"hello\"\n`\n\texpected := `\n{\n    \"boolean\": [true, false, true, false],\n    \"float\": [3.14, 685230.15],\n    \"int\": [123, 685230],\n    \"null\": {\n        \"nodeName\": \"node\",\n        \"parent\": null\n    },\n    \"string\": [\"哈哈\", \"Hello world\",  \"newline newline2\"],\n    \"date\": [\"2018-02-17T00:00:00Z\"],\n    \"datetime\": [\"2018-02-17T15:02:31+08:00\"],\n    \"mixed\": [true,false,1,0,null,\"hello\"],\n    \"1\": 0,\n    \"true\": true,\n    \"str\": \"hello\"\n}\n`\n\tbs, err := FromYAML([]byte(input))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tm := make(map[string]interface{})\n\tjson.Unmarshal(bs, &m)\n\tassertResult(t, m, expected)\n}\n"
  },
  {
    "path": "infra/conf/jsonpb/errors.generated.go",
    "content": "package jsonpb\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/jsonpb/jsonpb.go",
    "content": "package jsonpb\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc loadJSONPB(data io.Reader) (*core.Config, error) {\n\tcoreconf := &core.Config{}\n\tjsonpbloader := &jsonpb.Unmarshaler{AnyResolver: serial.GetResolver()}\n\terr := jsonpbloader.Unmarshal(data, coreconf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn coreconf, nil\n}\n\nfunc dumpJSONPb(config proto.Message, w io.Writer) error {\n\tjsonpbdumper := &jsonpb.Marshaler{AnyResolver: serial.GetResolver()}\n\terr := jsonpbdumper.Marshal(w, config)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc DumpJSONPb(config proto.Message, w io.Writer) error {\n\treturn dumpJSONPb(config, w)\n}\n\nconst FormatProtobufJSONPB = \"jsonpb\"\n\nfunc init() {\n\tcommon.Must(core.RegisterConfigLoader(&core.ConfigFormat{\n\t\tName:      []string{FormatProtobufJSONPB},\n\t\tExtension: []string{\".pb.json\", \".pbjson\"},\n\t\tLoader: func(input interface{}) (*core.Config, error) {\n\t\t\tswitch v := input.(type) {\n\t\t\tcase string:\n\t\t\t\tr, err := cmdarg.LoadArg(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\tdata, err := buf.ReadAllToBytes(r)\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 loadJSONPB(bytes.NewReader(data))\n\t\t\tcase []byte:\n\t\t\t\treturn loadJSONPB(bytes.NewReader(v))\n\t\t\tcase io.Reader:\n\t\t\t\tdata, err := buf.ReadAllToBytes(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\treturn loadJSONPB(bytes.NewReader(data))\n\t\t\tdefault:\n\t\t\t\treturn nil, newError(\"unknown type\")\n\t\t\t}\n\t\t},\n\t}))\n}\n"
  },
  {
    "path": "infra/conf/merge/errors.generated.go",
    "content": "package merge\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/merge/map.go",
    "content": "// Copyright 2020 Jebbs. All rights reserved.\n// Use of this source code is governed by MIT\n// license that can be found in the LICENSE file.\n\npackage merge\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// mergeMaps merges source map into target\n// it supports only map[string]interface{} type for any children of the map tree\nfunc mergeMaps(target map[string]interface{}, source map[string]interface{}) (err error) {\n\tfor key, value := range source {\n\t\ttarget[key], err = mergeField(target[key], value)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\nfunc mergeField(target interface{}, source interface{}) (interface{}, error) {\n\tif source == nil {\n\t\treturn target, nil\n\t}\n\tif target == nil {\n\t\treturn source, nil\n\t}\n\tif reflect.TypeOf(source) != reflect.TypeOf(target) {\n\t\treturn nil, fmt.Errorf(\"type mismatch, expect %T, incoming %T\", target, source)\n\t}\n\tif slice, ok := source.([]interface{}); ok {\n\t\ttslice, _ := target.([]interface{})\n\t\ttslice = append(tslice, slice...)\n\t\treturn tslice, nil\n\t} else if smap, ok := source.(map[string]interface{}); ok {\n\t\ttmap, _ := target.(map[string]interface{})\n\t\terr := mergeMaps(tmap, smap)\n\t\treturn tmap, err\n\t}\n\treturn source, nil\n}\n"
  },
  {
    "path": "infra/conf/merge/merge.go",
    "content": "// Copyright 2020 Jebbs. All rights reserved.\n// Use of this source code is governed by MIT\n// license that can be found in the LICENSE file.\n\n/*\nPackage merge provides the capability to merge multiple\nJSON files or contents into one output.\n\nMerge Rules:\n\n- Simple values (string, number, boolean) are overwritten, others are merged\n- Elements with same \"tag\" (or \"_tag\") in an array will be merged\n- Add \"_priority\" property to array elements will help sort the\n*/\npackage merge\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/serial\"\n)\n\n// JSONs merges multiple json contents into one json.\nfunc JSONs(args [][]byte) ([]byte, error) {\n\tm := make(map[string]interface{})\n\tfor _, arg := range args {\n\t\tif _, err := ToMap(arg, m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn FromMap(m)\n}\n\n// ToMap merges json content to target map and returns it\nfunc ToMap(content []byte, target map[string]interface{}) (map[string]interface{}, error) {\n\tif target == nil {\n\t\ttarget = make(map[string]interface{})\n\t}\n\tr := bytes.NewReader(content)\n\tn := make(map[string]interface{})\n\terr := serial.DecodeJSON(r, &n)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = mergeMaps(target, n); err != nil {\n\t\treturn nil, err\n\t}\n\treturn target, nil\n}\n\n// FromMap apply merge rules to map and convert it to json\nfunc FromMap(target map[string]interface{}) ([]byte, error) {\n\tif target == nil {\n\t\ttarget = make(map[string]interface{})\n\t}\n\terr := ApplyRules(target)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(target)\n}\n"
  },
  {
    "path": "infra/conf/merge/merge_test.go",
    "content": "// Copyright 2020 Jebbs. All rights reserved.\n// Use of this source code is governed by MIT\n// license that can be found in the LICENSE file.\n\npackage merge_test\n\nimport (\n\t\"bytes\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/merge\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/serial\"\n)\n\nfunc TestMergeV2Style(t *testing.T) {\n\tjson1 := `\n\t  {\n\t\t\"log\": {\"access\": \"some_value\", \"loglevel\": \"debug\"},\n\t\t\"inbounds\": [{\"tag\": \"in-1\"}],\n\t\t\"outbounds\": [{\"_priority\": 100, \"tag\": \"out-1\"}],\n\t\t\"routing\": {\"rules\": [\n\t\t  {\"_tag\":\"default_route\",\"inboundTag\":[\"in-1\"],\"outboundTag\":\"out-1\"}\n\t\t]}\n\t  }\n`\n\tjson2 := `\n\t  {\n\t\t\"log\": {\"loglevel\": \"error\"},\n\t\t\"inbounds\": [{\"tag\": \"in-2\"}],\n\t\t\"outbounds\": [{\"_priority\": -100, \"tag\": \"out-2\"}],\n\t\t\"routing\": {\"rules\": [\n\t\t  {\"inboundTag\":[\"in-2\"],\"outboundTag\":\"out-2\"},\n\t\t  {\"_tag\":\"default_route\",\"inboundTag\":[\"in-1.1\"],\"outboundTag\":\"out-1.1\"}\n\t\t]}\n\t  }\n`\n\texpected := `\n\t{\n\t  \"log\": {\"access\": \"some_value\", \"loglevel\": \"error\"},\n\t  \"inbounds\": [{\"tag\": \"in-1\"},{\"tag\": \"in-2\"}],\n\t  \"outbounds\": [\n\t\t   {\"tag\": \"out-2\"},\n\t\t   {\"tag\": \"out-1\"}\n\t  ],\n\t  \"routing\": {\"rules\": [\n\t\t   {\"inboundTag\":[\"in-1\",\"in-1.1\"],\"outboundTag\":\"out-1.1\"},\n\t\t   {\"inboundTag\":[\"in-2\"],\"outboundTag\":\"out-2\"}\n\t  ]}\n\t}\n\t`\n\tm, err := merge.JSONs([][]byte{[]byte(json1), []byte(json2)})\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tassertResult(t, m, expected)\n}\n\nfunc TestMergeTag(t *testing.T) {\n\tjson1 := `\n\t{\n\t  \t\"routing\": {\n\t\t  \t\"rules\": [{\n\t\t\t\t\"tag\":\"1\",\n\t\t\t\t\"inboundTag\": [\"in-1\"],\n\t\t\t\t\"outboundTag\": \"out-1\"\n\t\t\t}]\n\t\t}\n\t}\n`\n\tjson2 := `\n\t{\n\t  \t\"routing\": {\n\t\t  \t\"rules\": [{\n\t\t\t\t\"_tag\":\"1\",\n\t\t\t\t\"inboundTag\": [\"in-2\"],\n\t\t\t\t\"outboundTag\": \"out-2\"\n\t\t\t}]\n\t\t}\n\t}\n`\n\texpected := `\n\t{\n\t  \t\"routing\": {\n\t\t\t\"rules\": [{\n\t\t\t\t\"tag\":\"1\",\n\t\t\t\t\"inboundTag\": [\"in-1\", \"in-2\"],\n\t\t\t\t\"outboundTag\": \"out-2\"\n\t\t\t}]\n\t  \t}\n\t}\n\t`\n\tm, err := merge.JSONs([][]byte{[]byte(json1), []byte(json2)})\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tassertResult(t, m, expected)\n}\n\nfunc TestMergeTagValueTypes(t *testing.T) {\n\tjson1 := `\n\t{\n\t  \t\"array_1\": [{\n\t\t\t\"_tag\":\"1\",\n\t\t\t\"array_2\": [{\n\t\t\t\t\"_tag\":\"2\",\n\t\t\t\t\"array_3.1\": [\"string\",true,false],\n\t\t\t\t\"array_3.2\": [1,2,3],\n\t\t\t\t\"number_1\": 1,\n\t\t\t\t\"number_2\": 1,\n\t\t\t\t\"bool_1\": true,\n\t\t\t\t\"bool_2\": true\n\t\t\t}]\n\t\t}]\n\t}\n`\n\tjson2 := `\n\t{\n\t\t\"array_1\": [{\n\t\t\t\"_tag\":\"1\",\n\t\t\t\"array_2\": [{\n\t\t\t\t\"_tag\":\"2\",\n\t\t\t\t\"array_3.1\": [0,1,null],\n\t\t\t\t\"array_3.2\": null,\n\t\t\t\t\"number_1\": 0,\n\t\t\t\t\"number_2\": 1,\n\t\t\t\t\"bool_1\": true,\n\t\t\t\t\"bool_2\": false,\n\t\t\t\t\"null_1\": null\n\t\t\t}]\n\t\t}]\n\t}\n`\n\texpected := `\n\t{\n\t  \"array_1\": [{\n\t\t\"array_2\": [{\n\t\t\t\"array_3.1\": [\"string\",true,false,0,1,null],\n\t\t\t\"array_3.2\": [1,2,3],\n\t\t\t\"number_1\": 0,\n\t\t\t\"number_2\": 1,\n\t\t\t\"bool_1\": true,\n\t\t\t\"bool_2\": false,\n\t\t\t\"null_1\": null\n\t\t}]\n\t  }]\n\t}\n\t`\n\tm, err := merge.JSONs([][]byte{[]byte(json1), []byte(json2)})\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tassertResult(t, m, expected)\n}\n\nfunc TestMergeTagDeep(t *testing.T) {\n\tjson1 := `\n\t{\n\t  \t\"array_1\": [{\n\t\t\t\"_tag\":\"1\",\n\t\t\t\"array_2\": [{\n\t\t\t\t\"_tag\":\"2\",\n\t\t\t\t\"array_3\": [true,false,\"string\"]\n\t\t\t}]\n\t\t}]\n\t}\n`\n\tjson2 := `\n\t{\n\t  \t\"array_1\": [{\n\t\t\t\"_tag\":\"1\",\n\t\t\t\"array_2\": [{\n\t\t\t\t\"_tag\":\"2\",\n\t\t\t\t\"_priority\":-100,\n\t\t\t\t\"array_3\": [0,1,null]\n\t\t\t}]\n\t\t}]\n\t}\n`\n\texpected := `\n\t{\n\t  \t\"array_1\": [{\n\t\t\t\"array_2\": [{\n\t\t\t\t\"array_3\": [0,1,null,true,false,\"string\"]\n\t\t\t}]\n\t\t}]\n\t}\n\t`\n\tm, err := merge.JSONs([][]byte{[]byte(json1), []byte(json2)})\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tassertResult(t, m, expected)\n}\n\nfunc TestNoMergeDnsServers(t *testing.T) {\n\tjson1 := `\n\t{\n\t\t\"dns\": {\n\t\t\t\"queryStrategy\": \"UseIPv4\",\n\t\t\t\"fallbackStrategy\": \"disabled-if-any-match\",\n\t\t\t\"domainMatcher\": \"mph\",\n\t\t\t\"servers\": [\n\t\t\t\t{\n\t\t\t\t\t\"address\": \"aaa.bbb.ccc.ddd\",\n\t\t\t\t\t\"port\": 53,\n\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\"geosite:cn\"\n\t\t\t\t\t],\n\t\t\t\t\t\"tag\": \"dns-domestic\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"address\": \"114.114.114.114\",\n\t\t\t\t\t\"port\": 53,\n\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\"geosite:cn\"\n\t\t\t\t\t],\n\t\t\t\t\t\"tag\": \"dns-domestic\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"address\": \"https://1.1.1.1/dns-query\",\n\t\t\t\t\t\"tag\": \"dns-international\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"routing\": {\n\t\t\t\"domainStrategy\": \"IPIfNonMatch\",\n\t\t\t\"domainMatcher\": \"mph\",\n\t\t\t\"rules\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\"inboundTag\": \"dns-domestic\",\n\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\"inboundTag\": \"dns-international\",\n\t\t\t\t\t\"outboundTag\": \"proxy\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n`\n\texpected := `\n\t{\n\t\t\"dns\": {\n\t\t\t\"queryStrategy\": \"UseIPv4\",\n\t\t\t\"fallbackStrategy\": \"disabled-if-any-match\",\n\t\t\t\"domainMatcher\": \"mph\",\n\t\t\t\"servers\": [\n\t\t\t\t{\n\t\t\t\t\t\"address\": \"aaa.bbb.ccc.ddd\",\n\t\t\t\t\t\"port\": 53,\n\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\"geosite:cn\"\n\t\t\t\t\t],\n\t\t\t\t\t\"tag\": \"dns-domestic\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"address\": \"114.114.114.114\",\n\t\t\t\t\t\"port\": 53,\n\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\"geosite:cn\"\n\t\t\t\t\t],\n\t\t\t\t\t\"tag\": \"dns-domestic\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"address\": \"https://1.1.1.1/dns-query\",\n\t\t\t\t\t\"tag\": \"dns-international\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"routing\": {\n\t\t\t\"domainStrategy\": \"IPIfNonMatch\",\n\t\t\t\"domainMatcher\": \"mph\",\n\t\t\t\"rules\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\"inboundTag\": \"dns-domestic\",\n\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\"inboundTag\": \"dns-international\",\n\t\t\t\t\t\"outboundTag\": \"proxy\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n`\n\tm, err := merge.JSONs([][]byte{[]byte(json1)})\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tassertResult(t, m, expected)\n}\n\nfunc assertResult(t *testing.T, value []byte, expected string) {\n\tv := make(map[string]interface{})\n\terr := serial.DecodeJSON(bytes.NewReader(value), &v)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\te := make(map[string]interface{})\n\terr = serial.DecodeJSON(strings.NewReader(expected), &e)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif !reflect.DeepEqual(v, e) {\n\t\tt.Fatalf(\"expected:\\n%s\\n\\nactual:\\n%s\", expected, string(value))\n\t}\n}\n"
  },
  {
    "path": "infra/conf/merge/priority.go",
    "content": "// Copyright 2020 Jebbs. All rights reserved.\n// Use of this source code is governed by MIT\n// license that can be found in the LICENSE file.\n\npackage merge\n\nimport \"sort\"\n\nfunc getPriority(v interface{}) float64 {\n\tvar m map[string]interface{}\n\tvar ok bool\n\tif m, ok = v.(map[string]interface{}); !ok {\n\t\treturn 0\n\t}\n\tif i, ok := m[priorityKey]; ok {\n\t\tif p, ok := i.(float64); ok {\n\t\t\treturn p\n\t\t}\n\t}\n\treturn 0\n}\n\n// sortByPriority sort slice by priority fields of their elements\nfunc sortByPriority(slice []interface{}) {\n\tsort.Slice(\n\t\tslice,\n\t\tfunc(i, j int) bool {\n\t\t\treturn getPriority(slice[i]) < getPriority(slice[j])\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "infra/conf/merge/rules.go",
    "content": "// Copyright 2020 Jebbs. All rights reserved.\n// Use of this source code is governed by MIT\n// license that can be found in the LICENSE file.\n\npackage merge\n\nimport \"fmt\"\n\nconst (\n\tpriorityKey string = \"_priority\"\n\ttagKey      string = \"_tag\"\n)\n\n// ApplyRules applies merge rules according to _tag, _priority fields, and remove them\nfunc ApplyRules(m map[string]interface{}) error {\n\terr := sortMergeSlices(m, \"\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tremoveHelperFields(m)\n\treturn nil\n}\n\n// sortMergeSlices enumerates all slices in a map, to sort by priority and merge by tag\nfunc sortMergeSlices(target map[string]interface{}, path string) error {\n\tfor key, value := range target {\n\t\tif slice, ok := value.([]interface{}); ok {\n\t\t\tsortByPriority(slice)\n\t\t\ts, err := mergeSameTag(slice, fmt.Sprintf(\"%s.%s\", path, key))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\ttarget[key] = s\n\t\t\tfor _, item := range s {\n\t\t\t\tif m, ok := item.(map[string]interface{}); ok {\n\t\t\t\t\tsortMergeSlices(m, fmt.Sprintf(\"%s.%s[]\", path, key))\n\t\t\t\t}\n\t\t\t}\n\t\t} else if field, ok := value.(map[string]interface{}); ok {\n\t\t\tsortMergeSlices(field, fmt.Sprintf(\"%s.%s\", path, key))\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc removeHelperFields(target map[string]interface{}) {\n\tfor key, value := range target {\n\t\tif key == priorityKey || key == tagKey {\n\t\t\tdelete(target, key)\n\t\t} else if slice, ok := value.([]interface{}); ok {\n\t\t\tfor _, e := range slice {\n\t\t\t\tif el, ok := e.(map[string]interface{}); ok {\n\t\t\t\t\tremoveHelperFields(el)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if field, ok := value.(map[string]interface{}); ok {\n\t\t\tremoveHelperFields(field)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "infra/conf/merge/tag.go",
    "content": "// Copyright 2020 Jebbs. All rights reserved.\n// Use of this source code is governed by MIT\n// license that can be found in the LICENSE file.\n\npackage merge\n\nimport (\n\t\"strings\"\n)\n\nfunc getTag(v map[string]interface{}, tagKeyOnly bool) string {\n\tif !tagKeyOnly {\n\t\tif field, ok := v[\"tag\"]; ok {\n\t\t\tif t, ok := field.(string); ok {\n\t\t\t\treturn t\n\t\t\t}\n\t\t}\n\t}\n\tif field, ok := v[tagKey]; ok {\n\t\tif t, ok := field.(string); ok {\n\t\t\treturn t\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc mergeSameTag(s []interface{}, path string) ([]interface{}, error) {\n\t// from: [a,\"\",b,\"\",a,\"\",b,\"\"]\n\t// to: [a,\"\",b,\"\",merged,\"\",merged,\"\"]\n\tmerged := &struct{}{}\n\ttagKeyOnly := false\n\t// See https://github.com/v2fly/v2ray-core/issues/2981\n\tif strings.HasPrefix(path, \".dns.servers\") {\n\t\ttagKeyOnly = true\n\t}\n\tfor i, item1 := range s {\n\t\tmap1, ok := item1.(map[string]interface{})\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\ttag1 := getTag(map1, tagKeyOnly)\n\t\tif tag1 == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tfor j := i + 1; j < len(s); j++ {\n\t\t\tmap2, ok := s[j].(map[string]interface{})\n\t\t\tif !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttag2 := getTag(map2, tagKeyOnly)\n\t\t\tif tag1 == tag2 {\n\t\t\t\ts[j] = merged\n\t\t\t\terr := mergeMaps(map1, map2)\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}\n\t}\n\t// remove merged\n\tns := make([]interface{}, 0)\n\tfor _, item := range s {\n\t\tif item == merged {\n\t\t\tcontinue\n\t\t}\n\t\tns = append(ns, item)\n\t}\n\treturn ns, nil\n}\n"
  },
  {
    "path": "infra/conf/mergers/errors.generated.go",
    "content": "package mergers\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/mergers/extensions.go",
    "content": "package mergers\n\nimport \"strings\"\n\n// GetExtensions get extensions of given format\nfunc GetExtensions(formatName string) ([]string, error) {\n\tlowerName := strings.ToLower(formatName)\n\tif lowerName == \"auto\" {\n\t\treturn GetAllExtensions(), nil\n\t}\n\tf, found := mergersByName[lowerName]\n\tif !found {\n\t\treturn nil, newError(formatName+\" not found\", formatName).AtWarning()\n\t}\n\treturn f.Extensions, nil\n}\n\n// GetAllExtensions get all extensions supported\nfunc GetAllExtensions() []string {\n\textensions := make([]string, 0)\n\tfor _, f := range mergersByName {\n\t\textensions = append(extensions, f.Extensions...)\n\t}\n\treturn extensions\n}\n"
  },
  {
    "path": "infra/conf/mergers/merge.go",
    "content": "package mergers\n\nimport (\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n)\n\n// MergeAs load input and merge as specified format into m\nfunc MergeAs(formatName string, input interface{}, m map[string]interface{}) error {\n\tf, found := mergersByName[formatName]\n\tif !found {\n\t\treturn newError(\"format merger not found for: \", formatName)\n\t}\n\treturn f.Merge(input, m)\n}\n\n// Merge loads inputs and merges them into m\n// it detects extension for merger selecting, or try all mergers\n// if no extension found\nfunc Merge(input interface{}, m map[string]interface{}) error {\n\tif input == nil {\n\t\treturn nil\n\t}\n\tswitch v := input.(type) {\n\tcase string:\n\t\terr := mergeSingleFile(v, m)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\tcase []string:\n\t\tfor _, file := range v {\n\t\t\terr := mergeSingleFile(file, m)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase cmdarg.Arg:\n\t\tfor _, file := range v {\n\t\t\terr := mergeSingleFile(file, m)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase []byte:\n\t\terr := mergeSingleFile(v, m)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\tcase io.Reader:\n\t\t// read to []byte incase it tries different mergers\n\t\tbs, err := io.ReadAll(v)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = mergeSingleFile(bs, m)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn newError(\"unknown merge input type\")\n\t}\n\treturn nil\n}\n\nfunc mergeSingleFile(input interface{}, m map[string]interface{}) error {\n\tif file, ok := input.(string); ok {\n\t\text := getExtension(file)\n\t\tif ext != \"\" {\n\t\t\tlext := strings.ToLower(ext)\n\t\t\tf, found := mergersByExt[lext]\n\t\t\tif !found {\n\t\t\t\treturn newError(\"unmergeable format extension: \", ext)\n\t\t\t}\n\t\t\treturn f.Merge(file, m)\n\t\t}\n\t}\n\t// no extension, try all mergers\n\tfor _, f := range mergersByName {\n\t\tif f.Name == core.FormatAuto {\n\t\t\tcontinue\n\t\t}\n\t\terr := f.Merge(input, m)\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn newError(\"tried all mergers but failed for: \", input).AtWarning()\n}\n\nfunc getExtension(filename string) string {\n\text := filepath.Ext(filename)\n\treturn strings.ToLower(ext)\n}\n"
  },
  {
    "path": "infra/conf/mergers/merger_base.go",
    "content": "package mergers\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/merge\"\n)\n\ntype jsonConverter func(v []byte) ([]byte, error)\n\n// makeMerger makes a merger who merge the format by converting it to JSON\nfunc makeMerger(name string, extensions []string, converter jsonConverter) *Merger {\n\treturn &Merger{\n\t\tName:       name,\n\t\tExtensions: extensions,\n\t\tMerge:      makeToJSONMergeFunc(converter),\n\t}\n}\n\n// makeToJSONMergeFunc makes a merge func who merge the format by converting it to JSON\nfunc makeToJSONMergeFunc(converter func(v []byte) ([]byte, error)) MergeFunc {\n\treturn func(input interface{}, target map[string]interface{}) error {\n\t\tif input == nil {\n\t\t\treturn nil\n\t\t}\n\t\tif target == nil {\n\t\t\treturn errors.New(\"merge target is nil\")\n\t\t}\n\t\tswitch v := input.(type) {\n\t\tcase string:\n\t\t\terr := loadFile(v, target, converter)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase []string:\n\t\t\terr := loadFiles(v, target, converter)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase cmdarg.Arg:\n\t\t\terr := loadFiles(v, target, converter)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase []byte:\n\t\t\terr := loadBytes(v, target, converter)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase io.Reader:\n\t\t\terr := loadReader(v, target, converter)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tdefault:\n\t\t\treturn newError(\"unknown merge input type\")\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc loadFiles(files []string, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error {\n\tfor _, file := range files {\n\t\terr := loadFile(file, target, converter)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc loadFile(file string, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error {\n\tbs, err := cmdarg.LoadArgToBytes(file)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fail to load %s: %s\", file, err)\n\t}\n\tif converter != nil {\n\t\tbs, err = converter(bs)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error convert to json '%s': %s\", file, err)\n\t\t}\n\t}\n\t_, err = merge.ToMap(bs, target)\n\treturn err\n}\n\nfunc loadReader(reader io.Reader, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error {\n\tbs, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn loadBytes(bs, target, converter)\n}\n\nfunc loadBytes(bs []byte, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error {\n\tvar err error\n\tif converter != nil {\n\t\tbs, err = converter(bs)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"fail to convert to json: %s\", err)\n\t\t}\n\t}\n\t_, err = merge.ToMap(bs, target)\n\treturn err\n}\n"
  },
  {
    "path": "infra/conf/mergers/mergers.go",
    "content": "package mergers\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"strings\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n)\n\nfunc init() {\n\tcommon.Must(RegisterMerger(makeMerger(\n\t\tcore.FormatJSON,\n\t\t[]string{\".json\", \".jsonc\"},\n\t\tnil,\n\t)))\n\tcommon.Must(RegisterMerger(makeMerger(\n\t\tcore.FormatTOML,\n\t\t[]string{\".toml\"},\n\t\tjson.FromTOML,\n\t)))\n\tcommon.Must(RegisterMerger(makeMerger(\n\t\tcore.FormatYAML,\n\t\t[]string{\".yml\", \".yaml\"},\n\t\tjson.FromYAML,\n\t)))\n\tcommon.Must(RegisterMerger(\n\t\t&Merger{\n\t\t\tName:       core.FormatAuto,\n\t\t\tExtensions: nil,\n\t\t\tMerge:      Merge,\n\t\t}),\n\t)\n}\n\n// Merger is a configurable format merger for V2Ray config files.\ntype Merger struct {\n\tName       string\n\tExtensions []string\n\tMerge      MergeFunc\n}\n\n// MergeFunc is a utility to merge V2Ray config from external source into a map and returns it.\ntype MergeFunc func(input interface{}, m map[string]interface{}) error\n\nvar (\n\tmergersByName = make(map[string]*Merger)\n\tmergersByExt  = make(map[string]*Merger)\n)\n\n// RegisterMerger add a new Merger.\nfunc RegisterMerger(format *Merger) error {\n\tif _, found := mergersByName[format.Name]; found {\n\t\treturn newError(format.Name, \" already registered.\")\n\t}\n\tmergersByName[format.Name] = format\n\n\tfor _, ext := range format.Extensions {\n\t\tlext := strings.ToLower(ext)\n\t\tif f, found := mergersByExt[lext]; found {\n\t\t\treturn newError(ext, \" already registered to \", f.Name)\n\t\t}\n\t\tmergersByExt[lext] = format\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "infra/conf/mergers/names.go",
    "content": "package mergers\n\n// GetAllNames get names of all formats\nfunc GetAllNames() []string {\n\tnames := make([]string, 0)\n\tfor _, f := range mergersByName {\n\t\tnames = append(names, f.Name)\n\t}\n\treturn names\n}\n"
  },
  {
    "path": "infra/conf/rule/errors.generated.go",
    "content": "package rule\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/rule/rule.go",
    "content": "package rule\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc parseDomainRule(ctx context.Context, domain string) ([]*routercommon.Domain, error) {\n\tcfgEnv := cfgcommon.GetConfigureLoadingEnvironment(ctx)\n\tgeoLoader := cfgEnv.GetGeoLoader()\n\n\tif strings.HasPrefix(domain, \"geosite:\") {\n\t\tlist := domain[8:]\n\t\tif len(list) == 0 {\n\t\t\treturn nil, newError(\"empty listname in rule: \", domain)\n\t\t}\n\t\tdomains, err := geoLoader.LoadGeoSite(list)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to load geosite: \", list).Base(err)\n\t\t}\n\n\t\treturn domains, nil\n\t}\n\n\tisExtDatFile := 0\n\t{\n\t\tconst prefix = \"ext:\"\n\t\tif strings.HasPrefix(domain, prefix) {\n\t\t\tisExtDatFile = len(prefix)\n\t\t}\n\t\tconst prefixQualified = \"ext-domain:\"\n\t\tif strings.HasPrefix(domain, prefixQualified) {\n\t\t\tisExtDatFile = len(prefixQualified)\n\t\t}\n\t}\n\n\tif isExtDatFile != 0 {\n\t\tkv := strings.Split(domain[isExtDatFile:], \":\")\n\t\tif len(kv) != 2 {\n\t\t\treturn nil, newError(\"invalid external resource: \", domain)\n\t\t}\n\t\tfilename := kv[0]\n\t\tlist := kv[1]\n\t\tdomains, err := geoLoader.LoadGeoSiteWithAttr(filename, list)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to load external geosite: \", list, \" from \", filename).Base(err)\n\t\t}\n\n\t\treturn domains, nil\n\t}\n\n\tdomainRule := new(routercommon.Domain)\n\tswitch {\n\tcase strings.HasPrefix(domain, \"regexp:\"):\n\t\tregexpVal := domain[7:]\n\t\tif len(regexpVal) == 0 {\n\t\t\treturn nil, newError(\"empty regexp type of rule: \", domain)\n\t\t}\n\t\tdomainRule.Type = routercommon.Domain_Regex\n\t\tdomainRule.Value = regexpVal\n\n\tcase strings.HasPrefix(domain, \"domain:\"):\n\t\tdomainName := domain[7:]\n\t\tif len(domainName) == 0 {\n\t\t\treturn nil, newError(\"empty domain type of rule: \", domain)\n\t\t}\n\t\tdomainRule.Type = routercommon.Domain_RootDomain\n\t\tdomainRule.Value = domainName\n\n\tcase strings.HasPrefix(domain, \"full:\"):\n\t\tfullVal := domain[5:]\n\t\tif len(fullVal) == 0 {\n\t\t\treturn nil, newError(\"empty full domain type of rule: \", domain)\n\t\t}\n\t\tdomainRule.Type = routercommon.Domain_Full\n\t\tdomainRule.Value = fullVal\n\n\tcase strings.HasPrefix(domain, \"keyword:\"):\n\t\tkeywordVal := domain[8:]\n\t\tif len(keywordVal) == 0 {\n\t\t\treturn nil, newError(\"empty keyword type of rule: \", domain)\n\t\t}\n\t\tdomainRule.Type = routercommon.Domain_Plain\n\t\tdomainRule.Value = keywordVal\n\n\tcase strings.HasPrefix(domain, \"dotless:\"):\n\t\tdomainRule.Type = routercommon.Domain_Regex\n\t\tswitch substr := domain[8:]; {\n\t\tcase substr == \"\":\n\t\t\tdomainRule.Value = \"^[^.]*$\"\n\t\tcase !strings.Contains(substr, \".\"):\n\t\t\tdomainRule.Value = \"^[^.]*\" + substr + \"[^.]*$\"\n\t\tdefault:\n\t\t\treturn nil, newError(\"substr in dotless rule should not contain a dot: \", substr)\n\t\t}\n\n\tdefault:\n\t\tdomainRule.Type = routercommon.Domain_Plain\n\t\tdomainRule.Value = domain\n\t}\n\treturn []*routercommon.Domain{domainRule}, nil\n}\n\nfunc toCidrList(ctx context.Context, ips cfgcommon.StringList) ([]*routercommon.GeoIP, error) {\n\tcfgEnv := cfgcommon.GetConfigureLoadingEnvironment(ctx)\n\tgeoLoader := cfgEnv.GetGeoLoader()\n\n\tvar geoipList []*routercommon.GeoIP\n\tvar customCidrs []*routercommon.CIDR\n\n\tfor _, ip := range ips {\n\t\tif strings.HasPrefix(ip, \"geoip:\") {\n\t\t\tcountry := ip[6:]\n\t\t\tisReverseMatch := false\n\t\t\tif strings.HasPrefix(ip, \"geoip:!\") {\n\t\t\t\tcountry = ip[7:]\n\t\t\t\tisReverseMatch = true\n\t\t\t}\n\t\t\tif len(country) == 0 {\n\t\t\t\treturn nil, newError(\"empty country name in rule\")\n\t\t\t}\n\t\t\tgeoip, err := geoLoader.LoadGeoIP(country)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to load geoip: \", country).Base(err)\n\t\t\t}\n\n\t\t\tgeoipList = append(geoipList, &routercommon.GeoIP{\n\t\t\t\tCountryCode:  strings.ToUpper(country),\n\t\t\t\tCidr:         geoip,\n\t\t\t\tInverseMatch: isReverseMatch,\n\t\t\t})\n\n\t\t\tcontinue\n\t\t}\n\n\t\tisExtDatFile := 0\n\t\t{\n\t\t\tconst prefix = \"ext:\"\n\t\t\tif strings.HasPrefix(ip, prefix) {\n\t\t\t\tisExtDatFile = len(prefix)\n\t\t\t}\n\t\t\tconst prefixQualified = \"ext-ip:\"\n\t\t\tif strings.HasPrefix(ip, prefixQualified) {\n\t\t\t\tisExtDatFile = len(prefixQualified)\n\t\t\t}\n\t\t}\n\n\t\tif isExtDatFile != 0 {\n\t\t\tkv := strings.Split(ip[isExtDatFile:], \":\")\n\t\t\tif len(kv) != 2 {\n\t\t\t\treturn nil, newError(\"invalid external resource: \", ip)\n\t\t\t}\n\n\t\t\tfilename := kv[0]\n\t\t\tcountry := kv[1]\n\t\t\tif len(filename) == 0 || len(country) == 0 {\n\t\t\t\treturn nil, newError(\"empty filename or empty country in rule\")\n\t\t\t}\n\n\t\t\tisInverseMatch := false\n\t\t\tif strings.HasPrefix(country, \"!\") {\n\t\t\t\tcountry = country[1:]\n\t\t\t\tisInverseMatch = true\n\t\t\t}\n\t\t\tgeoip, err := geoLoader.LoadIP(filename, country)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to load geoip: \", country, \" from \", filename).Base(err)\n\t\t\t}\n\n\t\t\tgeoipList = append(geoipList, &routercommon.GeoIP{\n\t\t\t\tCountryCode:  strings.ToUpper(filename + \"_\" + country),\n\t\t\t\tCidr:         geoip,\n\t\t\t\tInverseMatch: isInverseMatch,\n\t\t\t})\n\n\t\t\tcontinue\n\t\t}\n\n\t\tipRule, err := ParseIP(ip)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid IP: \", ip).Base(err)\n\t\t}\n\t\tcustomCidrs = append(customCidrs, ipRule)\n\t}\n\n\tif len(customCidrs) > 0 {\n\t\tgeoipList = append(geoipList, &routercommon.GeoIP{\n\t\t\tCidr: customCidrs,\n\t\t})\n\t}\n\n\treturn geoipList, nil\n}\n\nfunc parseFieldRule(ctx context.Context, msg json.RawMessage) (*router.RoutingRule, error) {\n\ttype RawFieldRule struct {\n\t\tRouterRule\n\t\tDomain     *cfgcommon.StringList  `json:\"domain\"`\n\t\tDomains    *cfgcommon.StringList  `json:\"domains\"`\n\t\tIP         *cfgcommon.StringList  `json:\"ip\"`\n\t\tPort       *cfgcommon.PortList    `json:\"port\"`\n\t\tNetwork    *cfgcommon.NetworkList `json:\"network\"`\n\t\tSourceIP   *cfgcommon.StringList  `json:\"source\"`\n\t\tSourcePort *cfgcommon.PortList    `json:\"sourcePort\"`\n\t\tUser       *cfgcommon.StringList  `json:\"user\"`\n\t\tInboundTag *cfgcommon.StringList  `json:\"inboundTag\"`\n\t\tProtocols  *cfgcommon.StringList  `json:\"protocol\"`\n\t\tAttributes string                 `json:\"attrs\"`\n\t}\n\trawFieldRule := new(RawFieldRule)\n\terr := json.Unmarshal(msg, rawFieldRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trule := new(router.RoutingRule)\n\tswitch {\n\tcase len(rawFieldRule.OutboundTag) > 0:\n\t\trule.TargetTag = &router.RoutingRule_Tag{\n\t\t\tTag: rawFieldRule.OutboundTag,\n\t\t}\n\tcase len(rawFieldRule.BalancerTag) > 0:\n\t\trule.TargetTag = &router.RoutingRule_BalancingTag{\n\t\t\tBalancingTag: rawFieldRule.BalancerTag,\n\t\t}\n\tdefault:\n\t\treturn nil, newError(\"neither outboundTag nor balancerTag is specified in routing rule\")\n\t}\n\n\tif rawFieldRule.DomainMatcher != \"\" {\n\t\trule.DomainMatcher = rawFieldRule.DomainMatcher\n\t}\n\n\tif rawFieldRule.Domain != nil {\n\t\tfor _, domain := range *rawFieldRule.Domain {\n\t\t\trules, err := parseDomainRule(ctx, domain)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse domain rule: \", domain).Base(err)\n\t\t\t}\n\t\t\trule.Domain = append(rule.Domain, rules...)\n\t\t}\n\t}\n\n\tif rawFieldRule.Domains != nil {\n\t\tfor _, domain := range *rawFieldRule.Domains {\n\t\t\trules, err := parseDomainRule(ctx, domain)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse domain rule: \", domain).Base(err)\n\t\t\t}\n\t\t\trule.Domain = append(rule.Domain, rules...)\n\t\t}\n\t}\n\n\tif rawFieldRule.IP != nil {\n\t\tgeoipList, err := toCidrList(ctx, *rawFieldRule.IP)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trule.Geoip = geoipList\n\t}\n\n\tif rawFieldRule.Port != nil {\n\t\trule.PortList = rawFieldRule.Port.Build()\n\t}\n\n\tif rawFieldRule.Network != nil {\n\t\trule.Networks = rawFieldRule.Network.Build()\n\t}\n\n\tif rawFieldRule.SourceIP != nil {\n\t\tgeoipList, err := toCidrList(ctx, *rawFieldRule.SourceIP)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trule.SourceGeoip = geoipList\n\t}\n\n\tif rawFieldRule.SourcePort != nil {\n\t\trule.SourcePortList = rawFieldRule.SourcePort.Build()\n\t}\n\n\tif rawFieldRule.User != nil {\n\t\tfor _, s := range *rawFieldRule.User {\n\t\t\trule.UserEmail = append(rule.UserEmail, s)\n\t\t}\n\t}\n\n\tif rawFieldRule.InboundTag != nil {\n\t\tfor _, s := range *rawFieldRule.InboundTag {\n\t\t\trule.InboundTag = append(rule.InboundTag, s)\n\t\t}\n\t}\n\n\tif rawFieldRule.Protocols != nil {\n\t\tfor _, s := range *rawFieldRule.Protocols {\n\t\t\trule.Protocol = append(rule.Protocol, s)\n\t\t}\n\t}\n\n\tif len(rawFieldRule.Attributes) > 0 {\n\t\trule.Attributes = rawFieldRule.Attributes\n\t}\n\n\treturn rule, nil\n}\n\nfunc ParseRule(ctx context.Context, msg json.RawMessage) (*router.RoutingRule, error) {\n\trawRule := new(RouterRule)\n\terr := json.Unmarshal(msg, rawRule)\n\tif err != nil {\n\t\treturn nil, newError(\"invalid router rule\").Base(err)\n\t}\n\tif strings.EqualFold(rawRule.Type, \"field\") {\n\t\tfieldrule, err := parseFieldRule(ctx, msg)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid field rule\").Base(err)\n\t\t}\n\t\treturn fieldrule, nil\n\t}\n\n\treturn nil, newError(\"unknown router rule type: \", rawRule.Type)\n}\n\nfunc ParseIP(s string) (*routercommon.CIDR, error) {\n\tvar addr, mask string\n\ti := strings.Index(s, \"/\")\n\tif i < 0 {\n\t\taddr = s\n\t} else {\n\t\taddr = s[:i]\n\t\tmask = s[i+1:]\n\t}\n\tip := net.ParseAddress(addr)\n\tswitch ip.Family() {\n\tcase net.AddressFamilyIPv4:\n\t\tbits := uint32(32)\n\t\tif len(mask) > 0 {\n\t\t\tbits64, err := strconv.ParseUint(mask, 10, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"invalid network mask for router: \", mask).Base(err)\n\t\t\t}\n\t\t\tbits = uint32(bits64)\n\t\t}\n\t\tif bits > 32 {\n\t\t\treturn nil, newError(\"invalid network mask for router: \", bits)\n\t\t}\n\t\treturn &routercommon.CIDR{\n\t\t\tIp:     []byte(ip.IP()),\n\t\t\tPrefix: bits,\n\t\t}, nil\n\tcase net.AddressFamilyIPv6:\n\t\tbits := uint32(128)\n\t\tif len(mask) > 0 {\n\t\t\tbits64, err := strconv.ParseUint(mask, 10, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"invalid network mask for router: \", mask).Base(err)\n\t\t\t}\n\t\t\tbits = uint32(bits64)\n\t\t}\n\t\tif bits > 128 {\n\t\t\treturn nil, newError(\"invalid network mask for router: \", bits)\n\t\t}\n\t\treturn &routercommon.CIDR{\n\t\t\tIp:     []byte(ip.IP()),\n\t\t\tPrefix: bits,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, newError(\"unsupported address for router: \", s)\n\t}\n}\n\nfunc ParseDomainRule(ctx context.Context, domain string) ([]*routercommon.Domain, error) {\n\treturn parseDomainRule(ctx, domain)\n}\n\nfunc ToCidrList(ctx context.Context, ips cfgcommon.StringList) ([]*routercommon.GeoIP, error) {\n\treturn toCidrList(ctx, ips)\n}\n\ntype RouterRule struct {\n\tType        string `json:\"type\"`\n\tOutboundTag string `json:\"outboundTag\"`\n\tBalancerTag string `json:\"balancerTag\"`\n\n\tDomainMatcher string `json:\"domainMatcher\"`\n}\n"
  },
  {
    "path": "infra/conf/rule/rule_test.go",
    "content": "package rule_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/rule\"\n)\n\nfunc init() {\n\tconst geoipURL = \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat\"\n\n\twd, err := os.Getwd()\n\tcommon.Must(err)\n\n\ttempPath := filepath.Join(wd, \"..\", \"..\", \"..\", \"testing\", \"temp\")\n\tgeoipPath := filepath.Join(tempPath, \"geoip.dat\")\n\n\tos.Setenv(\"v2ray.location.asset\", tempPath)\n\n\tif _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeoipBytes, err := common.FetchHTTPContent(geoipURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geoipPath, geoipBytes))\n\t}\n}\n\nfunc TestToCidrList(t *testing.T) {\n\tt.Log(os.Getenv(\"v2ray.location.asset\"))\n\n\tcommon.Must(filesystem.CopyFile(platform.GetAssetLocation(\"geoiptestrouter.dat\"), platform.GetAssetLocation(\"geoip.dat\"), 0o600))\n\n\tips := cfgcommon.StringList([]string{\n\t\t\"geoip:us\",\n\t\t\"geoip:cn\",\n\t\t\"geoip:!cn\",\n\t\t\"ext:geoiptestrouter.dat:!cn\",\n\t\t\"ext:geoiptestrouter.dat:ca\",\n\t\t\"ext-ip:geoiptestrouter.dat:!cn\",\n\t\t\"ext-ip:geoiptestrouter.dat:!ca\",\n\t})\n\n\tcfgctx := cfgcommon.NewConfigureLoadingContext(context.Background())\n\n\tif loader, err := geodata.GetGeoDataLoader(\"standard\"); err == nil {\n\t\tcfgcommon.SetGeoDataLoader(cfgctx, loader)\n\t} else {\n\t\tt.Fatal(err)\n\t}\n\n\t_, err := rule.ToCidrList(cfgctx, ips)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to parse geoip list, got %s\", err)\n\t}\n}\n"
  },
  {
    "path": "infra/conf/serial/errors.generated.go",
    "content": "package serial\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/serial/loader.go",
    "content": "package serial\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\tjson_reader \"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n)\n\ntype offset struct {\n\tline int\n\tchar int\n}\n\nfunc findOffset(b []byte, o int) *offset {\n\tif o >= len(b) || o < 0 {\n\t\treturn nil\n\t}\n\n\tline := 1\n\tchar := 0\n\tfor i, x := range b {\n\t\tif i == o {\n\t\t\tbreak\n\t\t}\n\t\tif x == '\\n' {\n\t\t\tline++\n\t\t\tchar = 0\n\t\t} else {\n\t\t\tchar++\n\t\t}\n\t}\n\n\treturn &offset{line: line, char: char}\n}\n\n// DecodeJSONConfig reads from reader and decode the config into *conf.Config\n// syntax error could be detected.\nfunc DecodeJSONConfig(reader io.Reader) (*v4.Config, error) {\n\tjsonConfig := &v4.Config{}\n\terr := DecodeJSON(reader, jsonConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn jsonConfig, nil\n}\n\n// DecodeJSON reads from reader and decode into target\n// syntax error could be detected.\nfunc DecodeJSON(reader io.Reader, target interface{}) error {\n\tjsonContent := bytes.NewBuffer(make([]byte, 0, 10240))\n\tjsonReader := io.TeeReader(&json_reader.Reader{\n\t\tReader: reader,\n\t}, jsonContent)\n\tdecoder := json.NewDecoder(jsonReader)\n\n\tif err := decoder.Decode(target); err != nil {\n\t\tvar pos *offset\n\t\tcause := errors.Cause(err)\n\t\tswitch tErr := cause.(type) {\n\t\tcase *json.SyntaxError:\n\t\t\tpos = findOffset(jsonContent.Bytes(), int(tErr.Offset))\n\t\tcase *json.UnmarshalTypeError:\n\t\t\tpos = findOffset(jsonContent.Bytes(), int(tErr.Offset))\n\t\t}\n\t\tif pos != nil {\n\t\t\treturn newError(\"failed to read config file at line \", pos.line, \" char \", pos.char).Base(err)\n\t\t}\n\t\treturn newError(\"failed to read config file\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc LoadJSONConfig(reader io.Reader) (*core.Config, error) {\n\tjsonConfig, err := DecodeJSONConfig(reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpbConfig, err := jsonConfig.Build()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse json config\").Base(err)\n\t}\n\n\treturn pbConfig, nil\n}\n"
  },
  {
    "path": "infra/conf/serial/loader_test.go",
    "content": "package serial_test\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/serial\"\n)\n\nfunc TestLoaderError(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput  string\n\t\tOutput string\n\t}{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"log\": {\n\t\t\t\t\t// abcd\n\t\t\t\t\t0,\n\t\t\t\t\t\"loglevel\": \"info\"\n\t\t\t\t}\n\t\t}`,\n\t\t\tOutput: \"line 4 char 6\",\n\t\t},\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"log\": {\n\t\t\t\t\t// abcd\n\t\t\t\t\t\"loglevel\": \"info\",\n\t\t\t\t}\n\t\t}`,\n\t\t\tOutput: \"line 5 char 5\",\n\t\t},\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"port\": 1,\n\t\t\t\t\"inbounds\": [{\n\t\t\t\t\t\"protocol\": \"test\"\n\t\t\t\t}]\n\t\t}`,\n\t\t\tOutput: \"parse json config\",\n\t\t},\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"inbounds\": [{\n\t\t\t\t\t\"port\": 1,\n\t\t\t\t\t\"listen\": 0,\n\t\t\t\t\t\"protocol\": \"test\"\n\t\t\t\t}]\n\t\t}`,\n\t\t\tOutput: \"line 1 char 1\",\n\t\t},\n\t}\n\tfor _, testCase := range testCases {\n\t\treader := bytes.NewReader([]byte(testCase.Input))\n\t\t_, err := serial.LoadJSONConfig(reader)\n\t\terrString := err.Error()\n\t\tif !strings.Contains(errString, testCase.Output) {\n\t\t\tt.Error(\"unexpected output from json: \", testCase.Input, \". expected \", testCase.Output, \", but actually \", errString)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "infra/conf/serial/serial.go",
    "content": "package serial\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "infra/conf/synthetic/dns/dns.go",
    "content": "package dns\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n\trule2 \"github.com/v2fly/v2ray-core/v5/infra/conf/rule\"\n)\n\ntype NameServerConfig struct {\n\tAddress          *cfgcommon.Address\n\tClientIP         *cfgcommon.Address\n\tPort             uint16\n\tTag              string\n\tQueryStrategy    string\n\tCacheStrategy    string\n\tFallbackStrategy string\n\tSkipFallback     bool\n\tDomains          []string\n\tExpectIPs        cfgcommon.StringList\n\tFakeDNS          FakeDNSConfigExtend\n\n\tcfgctx context.Context\n}\n\nfunc (c *NameServerConfig) UnmarshalJSON(data []byte) error {\n\tvar address cfgcommon.Address\n\tif err := json.Unmarshal(data, &address); err == nil {\n\t\tc.Address = &address\n\t\treturn nil\n\t}\n\n\tvar advanced struct {\n\t\tAddress          *cfgcommon.Address   `json:\"address\"`\n\t\tClientIP         *cfgcommon.Address   `json:\"clientIp\"`\n\t\tPort             uint16               `json:\"port\"`\n\t\tTag              string               `json:\"tag\"`\n\t\tQueryStrategy    string               `json:\"queryStrategy\"`\n\t\tCacheStrategy    string               `json:\"cacheStrategy\"`\n\t\tFallbackStrategy string               `json:\"fallbackStrategy\"`\n\t\tSkipFallback     bool                 `json:\"skipFallback\"`\n\t\tDomains          []string             `json:\"domains\"`\n\t\tExpectIPs        cfgcommon.StringList `json:\"expectIps\"`\n\t\tFakeDNS          FakeDNSConfigExtend  `json:\"fakedns\"`\n\t}\n\tif err := json.Unmarshal(data, &advanced); err == nil {\n\t\tc.Address = advanced.Address\n\t\tc.ClientIP = advanced.ClientIP\n\t\tc.Port = advanced.Port\n\t\tc.Tag = advanced.Tag\n\t\tc.QueryStrategy = advanced.QueryStrategy\n\t\tc.CacheStrategy = advanced.CacheStrategy\n\t\tc.FallbackStrategy = advanced.FallbackStrategy\n\t\tc.SkipFallback = advanced.SkipFallback\n\t\tc.Domains = advanced.Domains\n\t\tc.ExpectIPs = advanced.ExpectIPs\n\t\tc.FakeDNS = advanced.FakeDNS\n\t\treturn nil\n\t}\n\n\treturn newError(\"failed to parse name server: \", string(data))\n}\n\nfunc toDomainMatchingType(t routercommon.Domain_Type) dns.DomainMatchingType {\n\tswitch t {\n\tcase routercommon.Domain_RootDomain:\n\t\treturn dns.DomainMatchingType_Subdomain\n\tcase routercommon.Domain_Full:\n\t\treturn dns.DomainMatchingType_Full\n\tcase routercommon.Domain_Plain:\n\t\treturn dns.DomainMatchingType_Keyword\n\tcase routercommon.Domain_Regex:\n\t\treturn dns.DomainMatchingType_Regex\n\tdefault:\n\t\tpanic(\"unknown domain type\")\n\t}\n}\n\nfunc (c *NameServerConfig) BuildV5(ctx context.Context) (*dns.NameServer, error) {\n\tc.cfgctx = ctx\n\treturn c.Build()\n}\n\nfunc (c *NameServerConfig) Build() (*dns.NameServer, error) {\n\tcfgctx := c.cfgctx\n\n\tif c.Address == nil {\n\t\treturn nil, newError(\"NameServer address is not specified.\")\n\t}\n\n\tvar domains []*dns.NameServer_PriorityDomain\n\tvar originalRules []*dns.NameServer_OriginalRule\n\n\tfor _, rule := range c.Domains {\n\t\tparsedDomain, err := rule2.ParseDomainRule(cfgctx, rule)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid domain rule: \", rule).Base(err)\n\t\t}\n\n\t\tfor _, pd := range parsedDomain {\n\t\t\tdomains = append(domains, &dns.NameServer_PriorityDomain{\n\t\t\t\tType:   toDomainMatchingType(pd.Type),\n\t\t\t\tDomain: pd.Value,\n\t\t\t})\n\t\t}\n\t\toriginalRules = append(originalRules, &dns.NameServer_OriginalRule{\n\t\t\tRule: rule,\n\t\t\tSize: uint32(len(parsedDomain)),\n\t\t})\n\t}\n\n\tgeoipList, err := rule2.ToCidrList(cfgctx, c.ExpectIPs)\n\tif err != nil {\n\t\treturn nil, newError(\"invalid IP rule: \", c.ExpectIPs).Base(err)\n\t}\n\n\tvar fakeDNS *fakedns.FakeDnsPoolMulti\n\tif c.FakeDNS.FakeDNSConfig != nil {\n\t\tfake, err := c.FakeDNS.FakeDNSConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build fakedns\").Base(err)\n\t\t}\n\t\tfakeDNS = fake\n\t}\n\n\tvar myClientIP []byte\n\tif c.ClientIP != nil {\n\t\tif !c.ClientIP.Family().IsIP() {\n\t\t\treturn nil, newError(\"not an IP address:\", c.ClientIP.String())\n\t\t}\n\t\tmyClientIP = []byte(c.ClientIP.IP())\n\t}\n\n\tqueryStrategy := new(dns.QueryStrategy)\n\tswitch strings.ToLower(c.QueryStrategy) {\n\tcase \"useip\", \"use_ip\", \"use-ip\":\n\t\t*queryStrategy = dns.QueryStrategy_USE_IP\n\tcase \"useip4\", \"useipv4\", \"use_ip4\", \"use_ipv4\", \"use_ip_v4\", \"use-ip4\", \"use-ipv4\", \"use-ip-v4\":\n\t\t*queryStrategy = dns.QueryStrategy_USE_IP4\n\tcase \"useip6\", \"useipv6\", \"use_ip6\", \"use_ipv6\", \"use_ip_v6\", \"use-ip6\", \"use-ipv6\", \"use-ip-v6\":\n\t\t*queryStrategy = dns.QueryStrategy_USE_IP6\n\tdefault:\n\t\tqueryStrategy = nil\n\t}\n\n\tcacheStrategy := new(dns.CacheStrategy)\n\tswitch strings.ToLower(c.CacheStrategy) {\n\tcase \"enabled\":\n\t\t*cacheStrategy = dns.CacheStrategy_CacheEnabled\n\tcase \"disabled\":\n\t\t*cacheStrategy = dns.CacheStrategy_CacheDisabled\n\tdefault:\n\t\tcacheStrategy = nil\n\t}\n\n\tfallbackStrategy := new(dns.FallbackStrategy)\n\tswitch strings.ToLower(c.FallbackStrategy) {\n\tcase \"enabled\":\n\t\t*fallbackStrategy = dns.FallbackStrategy_Enabled\n\tcase \"disabled\":\n\t\t*fallbackStrategy = dns.FallbackStrategy_Disabled\n\tcase \"disabledifanymatch\", \"disabled_if_any_match\", \"disabled-if-any-match\":\n\t\t*fallbackStrategy = dns.FallbackStrategy_DisabledIfAnyMatch\n\tdefault:\n\t\tfallbackStrategy = nil\n\t}\n\n\treturn &dns.NameServer{\n\t\tAddress: &net.Endpoint{\n\t\t\tNetwork: net.Network_UDP,\n\t\t\tAddress: c.Address.Build(),\n\t\t\tPort:    uint32(c.Port),\n\t\t},\n\t\tClientIp:          myClientIP,\n\t\tTag:               c.Tag,\n\t\tSkipFallback:      c.SkipFallback,\n\t\tQueryStrategy:     queryStrategy,\n\t\tCacheStrategy:     cacheStrategy,\n\t\tFallbackStrategy:  fallbackStrategy,\n\t\tPrioritizedDomain: domains,\n\t\tGeoip:             geoipList,\n\t\tOriginalRules:     originalRules,\n\t\tFakeDns:           fakeDNS,\n\t}, nil\n}\n\nvar typeMap = map[routercommon.Domain_Type]dns.DomainMatchingType{\n\troutercommon.Domain_Full:       dns.DomainMatchingType_Full,\n\troutercommon.Domain_RootDomain: dns.DomainMatchingType_Subdomain,\n\troutercommon.Domain_Plain:      dns.DomainMatchingType_Keyword,\n\troutercommon.Domain_Regex:      dns.DomainMatchingType_Regex,\n}\n\n// DNSConfig is a JSON serializable object for dns.Config.\ntype DNSConfig struct { // nolint: revive\n\tServers                []*NameServerConfig     `json:\"servers\"`\n\tHosts                  map[string]*HostAddress `json:\"hosts\"`\n\tFakeDNS                *FakeDNSConfig          `json:\"fakedns\"`\n\tDomainMatcher          string                  `json:\"domainMatcher\"`\n\tClientIP               *cfgcommon.Address      `json:\"clientIp\"`\n\tTag                    string                  `json:\"tag\"`\n\tQueryStrategy          string                  `json:\"queryStrategy\"`\n\tCacheStrategy          string                  `json:\"cacheStrategy\"`\n\tFallbackStrategy       string                  `json:\"fallbackStrategy\"`\n\tDisableCache           bool                    `json:\"disableCache\"`\n\tDisableFallback        bool                    `json:\"disableFallback\"`\n\tDisableFallbackIfMatch bool                    `json:\"disableFallbackIfMatch\"`\n\tcfgctx                 context.Context\n}\n\ntype HostAddress struct {\n\taddr  *cfgcommon.Address\n\taddrs []*cfgcommon.Address\n}\n\n// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON\nfunc (h *HostAddress) UnmarshalJSON(data []byte) error {\n\taddr := new(cfgcommon.Address)\n\tvar addrs []*cfgcommon.Address\n\tswitch {\n\tcase json.Unmarshal(data, &addr) == nil:\n\t\th.addr = addr\n\tcase json.Unmarshal(data, &addrs) == nil:\n\t\th.addrs = addrs\n\tdefault:\n\t\treturn newError(\"invalid address\")\n\t}\n\treturn nil\n}\n\nfunc getHostMapping(ha *HostAddress) *dns.HostMapping {\n\tif ha.addr != nil {\n\t\tif ha.addr.Family().IsDomain() {\n\t\t\treturn &dns.HostMapping{\n\t\t\t\tProxiedDomain: ha.addr.Domain(),\n\t\t\t}\n\t\t}\n\t\treturn &dns.HostMapping{\n\t\t\tIp: [][]byte{ha.addr.IP()},\n\t\t}\n\t}\n\n\tips := make([][]byte, 0, len(ha.addrs))\n\tfor _, addr := range ha.addrs {\n\t\tif addr.Family().IsDomain() {\n\t\t\treturn &dns.HostMapping{\n\t\t\t\tProxiedDomain: addr.Domain(),\n\t\t\t}\n\t\t}\n\t\tips = append(ips, []byte(addr.IP()))\n\t}\n\treturn &dns.HostMapping{\n\t\tIp: ips,\n\t}\n}\n\nfunc (c *DNSConfig) BuildV5(ctx context.Context) (*dns.Config, error) {\n\tc.cfgctx = ctx\n\treturn c.Build()\n}\n\n// Build implements Buildable\nfunc (c *DNSConfig) Build() (*dns.Config, error) {\n\tif c.cfgctx == nil {\n\t\tc.cfgctx = cfgcommon.NewConfigureLoadingContext(context.Background())\n\n\t\tgeoloadername := platform.NewEnvFlag(\"v2ray.conf.geoloader\").GetValue(func() string {\n\t\t\treturn \"standard\"\n\t\t})\n\n\t\tif loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {\n\t\t\tcfgcommon.SetGeoDataLoader(c.cfgctx, loader)\n\t\t} else {\n\t\t\treturn nil, newError(\"unable to create geo data loader \").Base(err)\n\t\t}\n\t}\n\n\tcfgEnv := cfgcommon.GetConfigureLoadingEnvironment(c.cfgctx)\n\tgeoLoader := cfgEnv.GetGeoLoader()\n\n\tconfig := &dns.Config{\n\t\tTag:                    c.Tag,\n\t\tDisableCache:           c.DisableCache,\n\t\tDisableFallback:        c.DisableFallback,\n\t\tDisableFallbackIfMatch: c.DisableFallbackIfMatch,\n\t\tDomainMatcher:          c.DomainMatcher,\n\t}\n\n\tif c.ClientIP != nil {\n\t\tif !c.ClientIP.Family().IsIP() {\n\t\t\treturn nil, newError(\"not an IP address:\", c.ClientIP.String())\n\t\t}\n\t\tconfig.ClientIp = []byte(c.ClientIP.IP())\n\t}\n\n\tconfig.QueryStrategy = dns.QueryStrategy_USE_IP\n\tswitch strings.ToLower(c.QueryStrategy) {\n\tcase \"useip\", \"use_ip\", \"use-ip\":\n\t\tconfig.QueryStrategy = dns.QueryStrategy_USE_IP\n\tcase \"useip4\", \"useipv4\", \"use_ip4\", \"use_ipv4\", \"use_ip_v4\", \"use-ip4\", \"use-ipv4\", \"use-ip-v4\":\n\t\tconfig.QueryStrategy = dns.QueryStrategy_USE_IP4\n\tcase \"useip6\", \"useipv6\", \"use_ip6\", \"use_ipv6\", \"use_ip_v6\", \"use-ip6\", \"use-ipv6\", \"use-ip-v6\":\n\t\tconfig.QueryStrategy = dns.QueryStrategy_USE_IP6\n\t}\n\n\tconfig.CacheStrategy = dns.CacheStrategy_CacheEnabled\n\tswitch strings.ToLower(c.CacheStrategy) {\n\tcase \"enabled\":\n\t\tconfig.CacheStrategy = dns.CacheStrategy_CacheEnabled\n\tcase \"disabled\":\n\t\tconfig.CacheStrategy = dns.CacheStrategy_CacheDisabled\n\t}\n\n\tconfig.FallbackStrategy = dns.FallbackStrategy_Enabled\n\tswitch strings.ToLower(c.FallbackStrategy) {\n\tcase \"enabled\":\n\t\tconfig.FallbackStrategy = dns.FallbackStrategy_Enabled\n\tcase \"disabled\":\n\t\tconfig.FallbackStrategy = dns.FallbackStrategy_Disabled\n\tcase \"disabledifanymatch\", \"disabled_if_any_match\", \"disabled-if-any-match\":\n\t\tconfig.FallbackStrategy = dns.FallbackStrategy_DisabledIfAnyMatch\n\t}\n\n\tfor _, server := range c.Servers {\n\t\tserver.cfgctx = c.cfgctx\n\t\tns, err := server.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build nameserver\").Base(err)\n\t\t}\n\t\tconfig.NameServer = append(config.NameServer, ns)\n\t}\n\n\tif c.Hosts != nil {\n\t\tmappings := make([]*dns.HostMapping, 0, 20)\n\n\t\tdomains := make([]string, 0, len(c.Hosts))\n\t\tfor domain := range c.Hosts {\n\t\t\tdomains = append(domains, domain)\n\t\t}\n\t\tsort.Strings(domains)\n\n\t\tfor _, domain := range domains {\n\t\t\tswitch {\n\t\t\tcase strings.HasPrefix(domain, \"domain:\"):\n\t\t\t\tdomainName := domain[7:]\n\t\t\t\tif len(domainName) == 0 {\n\t\t\t\t\treturn nil, newError(\"empty domain type of rule: \", domain)\n\t\t\t\t}\n\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\tmapping.Type = dns.DomainMatchingType_Subdomain\n\t\t\t\tmapping.Domain = domainName\n\t\t\t\tmappings = append(mappings, mapping)\n\n\t\t\tcase strings.HasPrefix(domain, \"geosite:\"):\n\t\t\t\tlistName := domain[8:]\n\t\t\t\tif len(listName) == 0 {\n\t\t\t\t\treturn nil, newError(\"empty geosite rule: \", domain)\n\t\t\t\t}\n\t\t\t\tgeositeList, err := geoLoader.LoadGeoSite(listName)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, newError(\"failed to load geosite: \", listName).Base(err)\n\t\t\t\t}\n\t\t\t\tfor _, d := range geositeList {\n\t\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\t\tmapping.Type = typeMap[d.Type]\n\t\t\t\t\tmapping.Domain = d.Value\n\t\t\t\t\tmappings = append(mappings, mapping)\n\t\t\t\t}\n\n\t\t\tcase strings.HasPrefix(domain, \"regexp:\"):\n\t\t\t\tregexpVal := domain[7:]\n\t\t\t\tif len(regexpVal) == 0 {\n\t\t\t\t\treturn nil, newError(\"empty regexp type of rule: \", domain)\n\t\t\t\t}\n\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\tmapping.Type = dns.DomainMatchingType_Regex\n\t\t\t\tmapping.Domain = regexpVal\n\t\t\t\tmappings = append(mappings, mapping)\n\n\t\t\tcase strings.HasPrefix(domain, \"keyword:\"):\n\t\t\t\tkeywordVal := domain[8:]\n\t\t\t\tif len(keywordVal) == 0 {\n\t\t\t\t\treturn nil, newError(\"empty keyword type of rule: \", domain)\n\t\t\t\t}\n\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\tmapping.Type = dns.DomainMatchingType_Keyword\n\t\t\t\tmapping.Domain = keywordVal\n\t\t\t\tmappings = append(mappings, mapping)\n\n\t\t\tcase strings.HasPrefix(domain, \"full:\"):\n\t\t\t\tfullVal := domain[5:]\n\t\t\t\tif len(fullVal) == 0 {\n\t\t\t\t\treturn nil, newError(\"empty full domain type of rule: \", domain)\n\t\t\t\t}\n\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\tmapping.Type = dns.DomainMatchingType_Full\n\t\t\t\tmapping.Domain = fullVal\n\t\t\t\tmappings = append(mappings, mapping)\n\n\t\t\tcase strings.HasPrefix(domain, \"dotless:\"):\n\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\tmapping.Type = dns.DomainMatchingType_Regex\n\t\t\t\tswitch substr := domain[8:]; {\n\t\t\t\tcase substr == \"\":\n\t\t\t\t\tmapping.Domain = \"^[^.]*$\"\n\t\t\t\tcase !strings.Contains(substr, \".\"):\n\t\t\t\t\tmapping.Domain = \"^[^.]*\" + substr + \"[^.]*$\"\n\t\t\t\tdefault:\n\t\t\t\t\treturn nil, newError(\"substr in dotless rule should not contain a dot: \", substr)\n\t\t\t\t}\n\t\t\t\tmappings = append(mappings, mapping)\n\n\t\t\tcase strings.HasPrefix(domain, \"ext:\"):\n\t\t\t\tkv := strings.Split(domain[4:], \":\")\n\t\t\t\tif len(kv) != 2 {\n\t\t\t\t\treturn nil, newError(\"invalid external resource: \", domain)\n\t\t\t\t}\n\t\t\t\tfilename := kv[0]\n\t\t\t\tlist := kv[1]\n\t\t\t\tgeositeList, err := geoLoader.LoadGeoSiteWithAttr(filename, list)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, newError(\"failed to load domain list: \", list, \" from \", filename).Base(err)\n\t\t\t\t}\n\t\t\t\tfor _, d := range geositeList {\n\t\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\t\tmapping.Type = typeMap[d.Type]\n\t\t\t\t\tmapping.Domain = d.Value\n\t\t\t\t\tmappings = append(mappings, mapping)\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tmapping := getHostMapping(c.Hosts[domain])\n\t\t\t\tmapping.Type = dns.DomainMatchingType_Full\n\t\t\t\tmapping.Domain = domain\n\t\t\t\tmappings = append(mappings, mapping)\n\t\t\t}\n\t\t}\n\n\t\tconfig.StaticHosts = append(config.StaticHosts, mappings...)\n\t}\n\n\tif c.FakeDNS != nil {\n\t\tfakeDNS, err := c.FakeDNS.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build fakedns\").Base(err)\n\t\t}\n\t\tconfig.FakeDns = fakeDNS\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/synthetic/dns/dns_test.go",
    "content": "package dns_test\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/runtime/protoiface\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform/filesystem\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard\"\n\tdns2 \"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/dns\"\n)\n\nfunc init() {\n\tconst (\n\t\tgeoipURL   = \"https://raw.githubusercontent.com/v2fly/geoip/release/geoip.dat\"\n\t\tgeositeURL = \"https://raw.githubusercontent.com/v2fly/domain-list-community/release/dlc.dat\"\n\t)\n\n\twd, err := os.Getwd()\n\tcommon.Must(err)\n\n\ttempPath := filepath.Join(wd, \"..\", \"..\", \"..\", \"..\", \"testing\", \"temp\")\n\tgeoipPath := filepath.Join(tempPath, \"geoip.dat\")\n\tgeositePath := filepath.Join(tempPath, \"geosite.dat\")\n\n\tos.Setenv(\"v2ray.location.asset\", tempPath)\n\n\tif _, err := os.Stat(geoipPath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeoipBytes, err := common.FetchHTTPContent(geoipURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geoipPath, geoipBytes))\n\t}\n\tif _, err := os.Stat(geositePath); err != nil && errors.Is(err, fs.ErrNotExist) {\n\t\tcommon.Must(os.MkdirAll(tempPath, 0o755))\n\t\tgeositeBytes, err := common.FetchHTTPContent(geositeURL)\n\t\tcommon.Must(err)\n\t\tcommon.Must(filesystem.WriteFile(geositePath, geositeBytes))\n\t}\n}\n\nfunc TestDNSConfigParsing(t *testing.T) {\n\tparserCreator := func() func(string) (protoiface.MessageV1, error) {\n\t\treturn func(s string) (protoiface.MessageV1, error) {\n\t\t\tconfig := new(dns2.DNSConfig)\n\t\t\tif err := json.Unmarshal([]byte(s), config); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn config.Build()\n\t\t}\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"servers\": [{\n\t\t\t\t\t\"address\": \"8.8.8.8\",\n\t\t\t\t\t\"clientIp\": \"10.0.0.1\",\n\t\t\t\t\t\"port\": 5353,\n\t\t\t\t\t\"skipFallback\": true,\n\t\t\t\t\t\"domains\": [\"domain:v2fly.org\"]\n\t\t\t\t}],\n\t\t\t\t\"hosts\": {\n\t\t\t\t\t\"v2fly.org\": \"127.0.0.1\",\n\t\t\t\t\t\"www.v2fly.org\": [\"1.2.3.4\", \"5.6.7.8\"],\n\t\t\t\t\t\"domain:example.com\": \"google.com\",\n\t\t\t\t\t\"geosite:test\": [\"127.0.0.1\", \"127.0.0.2\"],\n\t\t\t\t\t\"keyword:google\": [\"8.8.8.8\", \"8.8.4.4\"],\n\t\t\t\t\t\"regexp:.*\\\\.com\": \"8.8.4.4\"\n\t\t\t\t},\n\t\t\t\t\"clientIp\": \"10.0.0.1\",\n\t\t\t\t\"queryStrategy\": \"UseIPv4\",\n\t\t\t\t\"disableCache\": true,\n\t\t\t\t\"disableFallback\": true\n\t\t\t}`,\n\t\t\tParser: parserCreator(),\n\t\t\tOutput: &dns.Config{\n\t\t\t\tNameServer: []*dns.NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{8, 8, 8, 8},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tPort:    5353,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tClientIp:     []byte{10, 0, 0, 1},\n\t\t\t\t\t\tSkipFallback: true,\n\t\t\t\t\t\tPrioritizedDomain: []*dns.NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   dns.DomainMatchingType_Subdomain,\n\t\t\t\t\t\t\t\tDomain: \"v2fly.org\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tOriginalRules: []*dns.NameServer_OriginalRule{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tRule: \"domain:v2fly.org\",\n\t\t\t\t\t\t\t\tSize: 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\tStaticHosts: []*dns.HostMapping{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:          dns.DomainMatchingType_Subdomain,\n\t\t\t\t\t\tDomain:        \"example.com\",\n\t\t\t\t\t\tProxiedDomain: \"google.com\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"test.example.com\",\n\t\t\t\t\t\tIp:     [][]byte{{127, 0, 0, 1}, {127, 0, 0, 2}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Keyword,\n\t\t\t\t\t\tDomain: \"google\",\n\t\t\t\t\t\tIp:     [][]byte{{8, 8, 8, 8}, {8, 8, 4, 4}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Regex,\n\t\t\t\t\t\tDomain: \".*\\\\.com\",\n\t\t\t\t\t\tIp:     [][]byte{{8, 8, 4, 4}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"v2fly.org\",\n\t\t\t\t\t\tIp:     [][]byte{{127, 0, 0, 1}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"www.v2fly.org\",\n\t\t\t\t\t\tIp:     [][]byte{{1, 2, 3, 4}, {5, 6, 7, 8}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tClientIp:        []byte{10, 0, 0, 1},\n\t\t\t\tQueryStrategy:   dns.QueryStrategy_USE_IP4,\n\t\t\t\tDisableCache:    true,\n\t\t\t\tDisableFallback: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"servers\": [{\n\t\t\t\t\t\"address\": \"fakedns\",\n\t\t\t\t\t\"tag\": \"fake\",\n\t\t\t\t\t\"queryStrategy\": \"UseIPv6\",\n\t\t\t\t\t\"fallbackStrategy\": \"disabledIfAnyMatch\",\n\t\t\t\t\t\"fakedns\": true\n\t\t\t\t}, {\n\t\t\t\t\t\"address\": \"8.8.8.8\",\n\t\t\t\t\t\"port\": 5353,\n\t\t\t\t\t\"tag\": \"local\",\n\t\t\t\t\t\"clientIp\": \"10.0.0.1\",\n\t\t\t\t\t\"queryStrategy\": \"UseIP\",\n\t\t\t\t\t\"cacheStrategy\": \"enabled\",\n\t\t\t\t\t\"fallbackStrategy\": \"disabled\",\n\t\t\t\t\t\"domains\": [\"domain:v2fly.org\"],\n\t\t\t\t\t\"fakedns\": [\"198.19.0.0/16\", \"fc01::/18\"]\n\t\t\t\t}],\n\t\t\t\t\"hosts\": {\n\t\t\t\t\t\"v2fly.org\": \"127.0.0.1\",\n\t\t\t\t\t\"www.v2fly.org\": [\"1.2.3.4\", \"5.6.7.8\"],\n\t\t\t\t\t\"domain:example.com\": \"google.com\",\n\t\t\t\t\t\"geosite:test\": [\"127.0.0.1\", \"127.0.0.2\"],\n\t\t\t\t\t\"keyword:google\": [\"8.8.8.8\", \"8.8.4.4\"],\n\t\t\t\t\t\"regexp:.*\\\\.com\": \"8.8.4.4\"\n\t\t\t\t},\n\t\t\t\t\"fakedns\": [\n\t\t\t\t\t{ \"ipPool\": \"198.18.0.0/16\", \"poolSize\": 32768 },\n\t\t\t\t\t{ \"ipPool\": \"fc00::/18\", \"poolSize\": 32768 }\n\t\t\t\t],\n\t\t\t\t\"tag\": \"global\",\n\t\t\t\t\"clientIp\": \"10.0.0.1\",\n\t\t\t\t\"queryStrategy\": \"UseIPv4\",\n\t\t\t\t\"cacheStrategy\": \"disabled\",\n\t\t\t\t\"fallbackStrategy\": \"enabled\"\n\t\t\t}`,\n\t\t\tParser: parserCreator(),\n\t\t\tOutput: &dns.Config{\n\t\t\t\tNameServer: []*dns.NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Domain{\n\t\t\t\t\t\t\t\t\tDomain: \"fakedns\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTag:              \"fake\",\n\t\t\t\t\t\tQueryStrategy:    dns.QueryStrategy_USE_IP6.Enum(),\n\t\t\t\t\t\tFallbackStrategy: dns.FallbackStrategy_DisabledIfAnyMatch.Enum(),\n\t\t\t\t\t\tFakeDns: &fakedns.FakeDnsPoolMulti{\n\t\t\t\t\t\t\tPools: []*fakedns.FakeDnsPool{},\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\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{8, 8, 8, 8},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tPort:    5353,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTag:              \"local\",\n\t\t\t\t\t\tClientIp:         []byte{10, 0, 0, 1},\n\t\t\t\t\t\tQueryStrategy:    dns.QueryStrategy_USE_IP.Enum(),\n\t\t\t\t\t\tCacheStrategy:    dns.CacheStrategy_CacheEnabled.Enum(),\n\t\t\t\t\t\tFallbackStrategy: dns.FallbackStrategy_Disabled.Enum(),\n\t\t\t\t\t\tPrioritizedDomain: []*dns.NameServer_PriorityDomain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:   dns.DomainMatchingType_Subdomain,\n\t\t\t\t\t\t\t\tDomain: \"v2fly.org\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tOriginalRules: []*dns.NameServer_OriginalRule{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tRule: \"domain:v2fly.org\",\n\t\t\t\t\t\t\t\tSize: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tFakeDns: &fakedns.FakeDnsPoolMulti{\n\t\t\t\t\t\t\tPools: []*fakedns.FakeDnsPool{\n\t\t\t\t\t\t\t\t{IpPool: \"198.19.0.0/16\", LruSize: 65535},\n\t\t\t\t\t\t\t\t{IpPool: \"fc01::/18\", LruSize: 65535},\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\tStaticHosts: []*dns.HostMapping{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:          dns.DomainMatchingType_Subdomain,\n\t\t\t\t\t\tDomain:        \"example.com\",\n\t\t\t\t\t\tProxiedDomain: \"google.com\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"test.example.com\",\n\t\t\t\t\t\tIp:     [][]byte{{127, 0, 0, 1}, {127, 0, 0, 2}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Keyword,\n\t\t\t\t\t\tDomain: \"google\",\n\t\t\t\t\t\tIp:     [][]byte{{8, 8, 8, 8}, {8, 8, 4, 4}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Regex,\n\t\t\t\t\t\tDomain: \".*\\\\.com\",\n\t\t\t\t\t\tIp:     [][]byte{{8, 8, 4, 4}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"v2fly.org\",\n\t\t\t\t\t\tIp:     [][]byte{{127, 0, 0, 1}},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   dns.DomainMatchingType_Full,\n\t\t\t\t\t\tDomain: \"www.v2fly.org\",\n\t\t\t\t\t\tIp:     [][]byte{{1, 2, 3, 4}, {5, 6, 7, 8}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tFakeDns: &fakedns.FakeDnsPoolMulti{\n\t\t\t\t\tPools: []*fakedns.FakeDnsPool{\n\t\t\t\t\t\t{IpPool: \"198.18.0.0/16\", LruSize: 32768},\n\t\t\t\t\t\t{IpPool: \"fc00::/18\", LruSize: 32768},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tTag:              \"global\",\n\t\t\t\tClientIp:         []byte{10, 0, 0, 1},\n\t\t\t\tQueryStrategy:    dns.QueryStrategy_USE_IP4,\n\t\t\t\tCacheStrategy:    dns.CacheStrategy_CacheDisabled,\n\t\t\t\tFallbackStrategy: dns.FallbackStrategy_Enabled,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/synthetic/dns/errors.generated.go",
    "content": "package dns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/synthetic/dns/fakedns.go",
    "content": "package dns\n\nimport (\n\t\"encoding/json\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n)\n\ntype FakeDNSPoolElementConfig struct {\n\tIPPool  string `json:\"ipPool\"`\n\tLRUSize int64  `json:\"poolSize\"`\n}\n\ntype FakeDNSConfig struct {\n\tpool  *FakeDNSPoolElementConfig\n\tpools []*FakeDNSPoolElementConfig\n}\n\n// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON\nfunc (f *FakeDNSConfig) UnmarshalJSON(data []byte) error {\n\tvar pool FakeDNSPoolElementConfig\n\tvar pools []*FakeDNSPoolElementConfig\n\tvar ipPools []string\n\tswitch {\n\tcase json.Unmarshal(data, &pool) == nil:\n\t\tf.pool = &pool\n\tcase json.Unmarshal(data, &pools) == nil:\n\t\tf.pools = pools\n\tcase json.Unmarshal(data, &ipPools) == nil:\n\t\tf.pools = make([]*FakeDNSPoolElementConfig, 0, len(ipPools))\n\t\tfor _, ipPool := range ipPools {\n\t\t\t_, ipNet, err := net.ParseCIDR(ipPool)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tones, bits := ipNet.Mask.Size()\n\t\t\tsizeInBits := bits - ones\n\t\t\tif sizeInBits > 16 { // At most 65536 ips for a IP pool\n\t\t\t\tsizeInBits = 16\n\t\t\t}\n\t\t\tf.pools = append(f.pools, &FakeDNSPoolElementConfig{\n\t\t\t\tIPPool:  ipPool,\n\t\t\t\tLRUSize: (1 << sizeInBits) - 1,\n\t\t\t})\n\t\t}\n\tdefault:\n\t\treturn newError(\"invalid fakedns config\")\n\t}\n\treturn nil\n}\n\nfunc (f *FakeDNSConfig) Build() (*fakedns.FakeDnsPoolMulti, error) {\n\tfakeDNSPool := fakedns.FakeDnsPoolMulti{}\n\n\tif f.pool != nil {\n\t\tfakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{\n\t\t\tIpPool:  f.pool.IPPool,\n\t\t\tLruSize: f.pool.LRUSize,\n\t\t})\n\t\treturn &fakeDNSPool, nil\n\t}\n\n\tif f.pools != nil {\n\t\tfor _, v := range f.pools {\n\t\t\tfakeDNSPool.Pools = append(fakeDNSPool.Pools, &fakedns.FakeDnsPool{IpPool: v.IPPool, LruSize: v.LRUSize})\n\t\t}\n\t\treturn &fakeDNSPool, nil\n\t}\n\n\treturn nil, newError(\"no valid FakeDNS config\")\n}\n\ntype FakeDNSConfigExtend struct { // Adds boolean value parsing for \"fakedns\" config\n\t*FakeDNSConfig\n}\n\nfunc (f *FakeDNSConfigExtend) UnmarshalJSON(data []byte) error {\n\tvar enabled bool\n\tif json.Unmarshal(data, &enabled) == nil {\n\t\tif enabled {\n\t\t\tf.FakeDNSConfig = &FakeDNSConfig{pools: []*FakeDNSPoolElementConfig{}}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &f.FakeDNSConfig)\n}\n"
  },
  {
    "path": "infra/conf/synthetic/log/log.go",
    "content": "package log\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\nfunc DefaultLogConfig() *log.Config {\n\treturn &log.Config{\n\t\tAccess: &log.LogSpecification{Type: log.LogType_None},\n\t\tError:  &log.LogSpecification{Type: log.LogType_Console, Level: clog.Severity_Warning},\n\t}\n}\n\ntype LogConfig struct { // nolint: revive\n\tAccessLog string `json:\"access\"`\n\tErrorLog  string `json:\"error\"`\n\tLogLevel  string `json:\"loglevel\"`\n}\n\nfunc (v *LogConfig) Build() *log.Config {\n\tif v == nil {\n\t\treturn nil\n\t}\n\tconfig := &log.Config{\n\t\tAccess: &log.LogSpecification{Type: log.LogType_Console},\n\t\tError:  &log.LogSpecification{Type: log.LogType_Console},\n\t}\n\n\tif v.AccessLog == \"none\" {\n\t\tconfig.Access.Type = log.LogType_None\n\t} else if len(v.AccessLog) > 0 {\n\t\tconfig.Access.Path = v.AccessLog\n\t\tconfig.Access.Type = log.LogType_File\n\t}\n\tif v.ErrorLog == \"none\" {\n\t\tconfig.Error.Type = log.LogType_None\n\t} else if len(v.ErrorLog) > 0 {\n\t\tconfig.Error.Path = v.ErrorLog\n\t\tconfig.Error.Type = log.LogType_File\n\t}\n\n\tlevel := strings.ToLower(v.LogLevel)\n\tswitch level {\n\tcase \"debug\":\n\t\tconfig.Error.Level = clog.Severity_Debug\n\tcase \"info\":\n\t\tconfig.Error.Level = clog.Severity_Info\n\tcase \"error\":\n\t\tconfig.Error.Level = clog.Severity_Error\n\tcase \"none\":\n\t\tconfig.Error.Type = log.LogType_None\n\t\tconfig.Error.Type = log.LogType_None\n\tdefault:\n\t\tconfig.Error.Level = clog.Severity_Warning\n\t}\n\treturn config\n}\n"
  },
  {
    "path": "infra/conf/synthetic/router/errors.generated.go",
    "content": "package router\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/synthetic/router/router.go",
    "content": "package router\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n\trule2 \"github.com/v2fly/v2ray-core/v5/infra/conf/rule\"\n)\n\ntype RouterRulesConfig struct { // nolint: revive\n\tRuleList       []json.RawMessage `json:\"rules\"`\n\tDomainStrategy string            `json:\"domainStrategy\"`\n}\n\n// StrategyConfig represents a strategy config\ntype StrategyConfig struct {\n\tType     string           `json:\"type\"`\n\tSettings *json.RawMessage `json:\"settings\"`\n}\n\ntype BalancingRule struct {\n\tTag         string               `json:\"tag\"`\n\tSelectors   cfgcommon.StringList `json:\"selector\"`\n\tStrategy    StrategyConfig       `json:\"strategy\"`\n\tFallbackTag string               `json:\"fallbackTag\"`\n}\n\n// Build builds the balancing rule\nfunc (r *BalancingRule) Build() (*router.BalancingRule, error) {\n\tif r.Tag == \"\" {\n\t\treturn nil, newError(\"empty balancer tag\")\n\t}\n\tif len(r.Selectors) == 0 {\n\t\treturn nil, newError(\"empty selector list\")\n\t}\n\n\tvar strategy string\n\tswitch strings.ToLower(r.Strategy.Type) {\n\tcase strategyRandom, \"\":\n\t\tr.Strategy.Type = strategyRandom\n\t\tstrategy = strategyRandom\n\tcase strategyLeastLoad:\n\t\tstrategy = strategyLeastLoad\n\tcase strategyLeastPing:\n\t\tstrategy = \"leastping\"\n\tdefault:\n\t\treturn nil, newError(\"unknown balancing strategy: \" + r.Strategy.Type)\n\t}\n\n\tsettings := []byte(\"{}\")\n\tif r.Strategy.Settings != nil {\n\t\tsettings = ([]byte)(*r.Strategy.Settings)\n\t}\n\trawConfig, err := strategyConfigLoader.LoadWithID(settings, r.Strategy.Type)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse to strategy config.\").Base(err)\n\t}\n\tvar ts proto.Message\n\tif builder, ok := rawConfig.(cfgcommon.Buildable); ok {\n\t\tts, err = builder.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &router.BalancingRule{\n\t\tStrategy:         strategy,\n\t\tStrategySettings: serial.ToTypedMessage(ts),\n\t\tFallbackTag:      r.FallbackTag,\n\t\tOutboundSelector: r.Selectors,\n\t\tTag:              r.Tag,\n\t}, nil\n}\n\ntype RouterConfig struct { // nolint: revive\n\tSettings       *RouterRulesConfig `json:\"settings\"` // Deprecated\n\tRuleList       []json.RawMessage  `json:\"rules\"`\n\tDomainStrategy *string            `json:\"domainStrategy\"`\n\tBalancers      []*BalancingRule   `json:\"balancers\"`\n\n\tDomainMatcher string `json:\"domainMatcher\"`\n\n\tcfgctx context.Context\n}\n\nfunc (c *RouterConfig) getDomainStrategy() router.DomainStrategy {\n\tds := \"\"\n\tif c.DomainStrategy != nil {\n\t\tds = *c.DomainStrategy\n\t} else if c.Settings != nil {\n\t\tds = c.Settings.DomainStrategy\n\t}\n\n\tswitch strings.ToLower(ds) {\n\tcase \"alwaysip\", \"always_ip\", \"always-ip\":\n\t\treturn router.DomainStrategy_UseIp\n\tcase \"ipifnonmatch\", \"ip_if_non_match\", \"ip-if-non-match\":\n\t\treturn router.DomainStrategy_IpIfNonMatch\n\tcase \"ipondemand\", \"ip_on_demand\", \"ip-on-demand\":\n\t\treturn router.DomainStrategy_IpOnDemand\n\tdefault:\n\t\treturn router.DomainStrategy_AsIs\n\t}\n}\n\nfunc (c *RouterConfig) BuildV5(ctx context.Context) (*router.Config, error) {\n\tc.cfgctx = ctx\n\treturn c.Build()\n}\n\nfunc (c *RouterConfig) Build() (*router.Config, error) {\n\tconfig := new(router.Config)\n\tconfig.DomainStrategy = c.getDomainStrategy()\n\n\tif c.cfgctx == nil {\n\t\tc.cfgctx = cfgcommon.NewConfigureLoadingContext(context.Background())\n\n\t\tgeoloadername := platform.NewEnvFlag(\"v2ray.conf.geoloader\").GetValue(func() string {\n\t\t\treturn \"standard\"\n\t\t})\n\n\t\tif loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {\n\t\t\tcfgcommon.SetGeoDataLoader(c.cfgctx, loader)\n\t\t} else {\n\t\t\treturn nil, newError(\"unable to create geo data loader \").Base(err)\n\t\t}\n\t}\n\n\tvar rawRuleList []json.RawMessage\n\tif c != nil {\n\t\trawRuleList = c.RuleList\n\t\tif c.Settings != nil {\n\t\t\tc.RuleList = append(c.RuleList, c.Settings.RuleList...)\n\t\t\trawRuleList = c.RuleList\n\t\t}\n\t}\n\n\tfor _, rawRule := range rawRuleList {\n\t\trule, err := rule2.ParseRule(c.cfgctx, rawRule)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif rule.DomainMatcher == \"\" {\n\t\t\trule.DomainMatcher = c.DomainMatcher\n\t\t}\n\n\t\tconfig.Rule = append(config.Rule, rule)\n\t}\n\tfor _, rawBalancer := range c.Balancers {\n\t\tbalancer, err := rawBalancer.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.BalancingRule = append(config.BalancingRule, balancer)\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/synthetic/router/router_strategy.go",
    "content": "package router\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory/burst\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/duration\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/loader\"\n)\n\nconst (\n\tstrategyRandom    string = \"random\"\n\tstrategyLeastLoad string = \"leastload\"\n\tstrategyLeastPing string = \"leastping\"\n)\n\nvar strategyConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{\n\tstrategyRandom:    func() interface{} { return new(strategyRandomConfig) },\n\tstrategyLeastLoad: func() interface{} { return new(strategyLeastLoadConfig) },\n\tstrategyLeastPing: func() interface{} { return new(strategyLeastPingConfig) },\n}, \"type\", \"settings\")\n\ntype strategyEmptyConfig struct{}\n\nfunc (v *strategyEmptyConfig) Build() (proto.Message, error) {\n\treturn nil, nil\n}\n\ntype strategyLeastLoadConfig struct {\n\t// weight settings\n\tCosts []*router.StrategyWeight `json:\"costs,omitempty\"`\n\t// ping rtt baselines\n\tBaselines []duration.Duration `json:\"baselines,omitempty\"`\n\t// expected nodes count to select\n\tExpected int32 `json:\"expected,omitempty\"`\n\t// max acceptable rtt, filter away high delay nodes. default 0\n\tMaxRTT duration.Duration `json:\"maxRTT,omitempty\"`\n\t// acceptable failure rate\n\tTolerance float64 `json:\"tolerance,omitempty\"`\n\n\tObserverTag string `json:\"observerTag,omitempty\"`\n}\n\n// HealthCheckSettings holds settings for health Checker\ntype HealthCheckSettings struct {\n\tDestination   string            `json:\"destination\"`\n\tConnectivity  string            `json:\"connectivity\"`\n\tInterval      duration.Duration `json:\"interval\"`\n\tSamplingCount int               `json:\"sampling\"`\n\tTimeout       duration.Duration `json:\"timeout\"`\n}\n\nfunc (h HealthCheckSettings) Build() (proto.Message, error) {\n\treturn &burst.HealthPingConfig{\n\t\tDestination:   h.Destination,\n\t\tConnectivity:  h.Connectivity,\n\t\tInterval:      int64(h.Interval),\n\t\tTimeout:       int64(h.Timeout),\n\t\tSamplingCount: int32(h.SamplingCount),\n\t}, nil\n}\n\n// Build implements Buildable.\nfunc (v *strategyLeastLoadConfig) Build() (proto.Message, error) {\n\tconfig := &router.StrategyLeastLoadConfig{}\n\tconfig.Costs = v.Costs\n\tconfig.Tolerance = float32(v.Tolerance)\n\tconfig.ObserverTag = v.ObserverTag\n\tif config.Tolerance < 0 {\n\t\tconfig.Tolerance = 0\n\t}\n\tif config.Tolerance > 1 {\n\t\tconfig.Tolerance = 1\n\t}\n\tconfig.Expected = v.Expected\n\tif config.Expected < 0 {\n\t\tconfig.Expected = 0\n\t}\n\tconfig.MaxRTT = int64(v.MaxRTT)\n\tif config.MaxRTT < 0 {\n\t\tconfig.MaxRTT = 0\n\t}\n\tconfig.Baselines = make([]int64, 0)\n\tfor _, b := range v.Baselines {\n\t\tif b <= 0 {\n\t\t\tcontinue\n\t\t}\n\t\tconfig.Baselines = append(config.Baselines, int64(b))\n\t}\n\treturn config, nil\n}\n\ntype strategyLeastPingConfig struct {\n\tObserverTag string `json:\"observerTag,omitempty\"`\n}\n\nfunc (s strategyLeastPingConfig) Build() (proto.Message, error) {\n\treturn &router.StrategyLeastPingConfig{ObserverTag: s.ObserverTag}, nil\n}\n\ntype strategyRandomConfig struct {\n\tAliveOnly   bool   `json:\"aliveOnly,omitempty\"`\n\tObserverTag string `json:\"observerTag,omitempty\"`\n}\n\nfunc (s strategyRandomConfig) Build() (proto.Message, error) {\n\treturn &router.StrategyRandomConfig{ObserverTag: s.ObserverTag, AliveOnly: s.AliveOnly}, nil\n}\n"
  },
  {
    "path": "infra/conf/synthetic/router/router_test.go",
    "content": "package router_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\t_ \"unsafe\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/memconservative\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard\"\n\trouter2 \"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/router\"\n)\n\nfunc TestRouterConfig(t *testing.T) {\n\tcreateParser := func() func(string) (proto.Message, error) {\n\t\treturn func(s string) (proto.Message, error) {\n\t\t\tconfig := new(router2.RouterConfig)\n\t\t\tif err := json.Unmarshal([]byte(s), config); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn config.Build()\n\t\t}\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"strategy\": \"rules\",\n\t\t\t\t\"settings\": {\n\t\t\t\t\t\"domainStrategy\": \"AsIs\",\n\t\t\t\t\t\"rules\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"domain\": [\n\t\t\t\t\t\t\t\t\"baidu.com\",\n\t\t\t\t\t\t\t\t\"qq.com\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\t\t\"v2fly.org\",\n\t\t\t\t\t\t\t\t\"github.com\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"ip\": [\n\t\t\t\t\t\t\t\t\"10.0.0.0/8\",\n\t\t\t\t\t\t\t\t\"::1/128\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"outboundTag\": \"test\"\n\t\t\t\t\t\t},{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"port\": \"53, 443, 1000-2000\",\n\t\t\t\t\t\t\t\"outboundTag\": \"test\"\n\t\t\t\t\t\t},{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"port\": 123,\n\t\t\t\t\t\t\t\"outboundTag\": \"test\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t\"balancers\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"tag\": \"b1\",\n\t\t\t\t\t\t\"selector\": [\"test\"]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"tag\": \"b2\",\n\t\t\t\t\t\t\"selector\": [\"test\"],\n\t\t\t\t\t\t\"strategy\": {\n\t\t\t\t\t\t\t\"type\": \"leastload\",\n\t\t\t\t\t\t\t\"settings\": {\n\t\t\t\t\t\t\t\t\"healthCheck\": {\n\t\t\t\t\t\t\t\t\t\"interval\": \"5m0s\",\n\t\t\t\t\t\t\t\t\t\"sampling\": 2,\n\t\t\t\t\t\t\t\t\t\"timeout\": \"5s\",\n\t\t\t\t\t\t\t\t\t\"destination\": \"dest\",\n\t\t\t\t\t\t\t\t\t\"connectivity\": \"conn\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"costs\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"regexp\": true,\n\t\t\t\t\t\t\t\t\t\t\"match\": \"\\\\d+(\\\\.\\\\d+)\",\n\t\t\t\t\t\t\t\t\t\t\"value\": 5\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\t\"baselines\": [\"400ms\", \"600ms\"],\n\t\t\t\t\t\t\t\t\"expected\": 6,\n\t\t\t\t\t\t\t\t\"maxRTT\": \"1000ms\",\n\t\t\t\t\t\t\t\t\"tolerance\": 0.5\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"fallbackTag\": \"fall\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}`,\n\t\t\tParser: createParser(),\n\t\t\tOutput: &router.Config{\n\t\t\t\tDomainStrategy: router.DomainStrategy_AsIs,\n\t\t\t\tBalancingRule: []*router.BalancingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tTag:              \"b1\",\n\t\t\t\t\t\tOutboundSelector: []string{\"test\"},\n\t\t\t\t\t\tStrategy:         \"random\",\n\t\t\t\t\t\tStrategySettings: serial.ToTypedMessage(&router.StrategyRandomConfig{}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tTag:              \"b2\",\n\t\t\t\t\t\tOutboundSelector: []string{\"test\"},\n\t\t\t\t\t\tStrategy:         \"leastload\",\n\t\t\t\t\t\tStrategySettings: serial.ToTypedMessage(&router.StrategyLeastLoadConfig{\n\t\t\t\t\t\t\tCosts: []*router.StrategyWeight{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tRegexp: true,\n\t\t\t\t\t\t\t\t\tMatch:  \"\\\\d+(\\\\.\\\\d+)\",\n\t\t\t\t\t\t\t\t\tValue:  5,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tBaselines: []int64{\n\t\t\t\t\t\t\t\tint64(time.Duration(400) * time.Millisecond),\n\t\t\t\t\t\t\t\tint64(time.Duration(600) * time.Millisecond),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tExpected:  6,\n\t\t\t\t\t\t\tMaxRTT:    int64(time.Duration(1000) * time.Millisecond),\n\t\t\t\t\t\t\tTolerance: 0.5,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tFallbackTag: \"fall\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"baidu.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"qq.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"v2fly.org\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"github.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tIp:     []byte{10, 0, 0, 0},\n\t\t\t\t\t\t\t\t\t\tPrefix: 8,\n\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\t\tIp:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\t\t\t\t\t\t\t\tPrefix: 128,\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\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"test\",\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\tPortList: &net.PortList{\n\t\t\t\t\t\t\tRange: []*net.PortRange{\n\t\t\t\t\t\t\t\t{From: 53, To: 53},\n\t\t\t\t\t\t\t\t{From: 443, To: 443},\n\t\t\t\t\t\t\t\t{From: 1000, To: 2000},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"test\",\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\tPortList: &net.PortList{\n\t\t\t\t\t\t\tRange: []*net.PortRange{\n\t\t\t\t\t\t\t\t{From: 123, To: 123},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"test\",\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{\n\t\t\tInput: `{\n\t\t\t\t\"strategy\": \"rules\",\n\t\t\t\t\"settings\": {\n\t\t\t\t\t\"domainStrategy\": \"IPIfNonMatch\",\n\t\t\t\t\t\"rules\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"domain\": [\n\t\t\t\t\t\t\t\t\"baidu.com\",\n\t\t\t\t\t\t\t\t\"qq.com\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\t\t\"v2fly.org\",\n\t\t\t\t\t\t\t\t\"github.com\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\"ip\": [\n\t\t\t\t\t\t\t\t\"10.0.0.0/8\",\n\t\t\t\t\t\t\t\t\"::1/128\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"outboundTag\": \"test\"\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\tParser: createParser(),\n\t\t\tOutput: &router.Config{\n\t\t\t\tDomainStrategy: router.DomainStrategy_IpIfNonMatch,\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"baidu.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"qq.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"v2fly.org\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"github.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tIp:     []byte{10, 0, 0, 0},\n\t\t\t\t\t\t\t\t\t\tPrefix: 8,\n\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\t\tIp:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\t\t\t\t\t\t\t\tPrefix: 128,\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\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"test\",\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{\n\t\t\tInput: `{\n\t\t\t\t\"domainStrategy\": \"AsIs\",\n\t\t\t\t\"rules\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\"domain\": [\n\t\t\t\t\t\t\t\"baidu.com\",\n\t\t\t\t\t\t\t\"qq.com\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\"domains\": [\n\t\t\t\t\t\t\t\"v2fly.org\",\n\t\t\t\t\t\t\t\"github.com\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"outboundTag\": \"direct\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\"ip\": [\n\t\t\t\t\t\t\t\"10.0.0.0/8\",\n\t\t\t\t\t\t\t\"::1/128\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"outboundTag\": \"test\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}`,\n\t\t\tParser: createParser(),\n\t\t\tOutput: &router.Config{\n\t\t\t\tDomainStrategy: router.DomainStrategy_AsIs,\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"baidu.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"qq.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"v2fly.org\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tType:  routercommon.Domain_Plain,\n\t\t\t\t\t\t\t\tValue: \"github.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tIp:     []byte{10, 0, 0, 0},\n\t\t\t\t\t\t\t\t\t\tPrefix: 8,\n\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\t\tIp:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\t\t\t\t\t\t\t\tPrefix: 128,\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\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"test\",\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"
  },
  {
    "path": "infra/conf/v2jsonpb/any2.go",
    "content": "package v2jsonpb\n\nimport (\n\t\"github.com/golang/protobuf/jsonpb\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n)\n\ntype anyresolverv2 struct {\n\tbackgroundResolver jsonpb.AnyResolver\n}\n\nfunc (r anyresolverv2) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {\n\tpanic(\"implement me\")\n}\n\nfunc (r anyresolverv2) FindMessageByURL(url string) (protoreflect.MessageType, error) {\n\tmsg, err := r.backgroundResolver.Resolve(url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn msg.(proto.Message).ProtoReflect().Type(), nil\n}\n\nfunc (r anyresolverv2) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {\n\tpanic(\"implement me\")\n}\n\nfunc (r anyresolverv2) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {\n\tpanic(\"implement me\")\n}\n"
  },
  {
    "path": "infra/conf/v2jsonpb/errors.generated.go",
    "content": "package v2jsonpb\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/v2jsonpb/follower.go",
    "content": "package v2jsonpb\n\nimport (\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype V2JsonProtobufFollowerFieldDescriptor struct {\n\tprotoreflect.FieldDescriptor\n}\n\ntype V2JsonProtobufFollower struct {\n\tprotoreflect.Message\n}\n\nfunc (v *V2JsonProtobufFollower) Type() protoreflect.MessageType {\n\tpanic(\"implement me\")\n}\n\nfunc (v *V2JsonProtobufFollower) New() protoreflect.Message {\n\tpanic(\"implement me\")\n}\n\nfunc (v *V2JsonProtobufFollower) Interface() protoreflect.ProtoMessage {\n\treturn v.Message.Interface()\n}\n\nfunc (v *V2JsonProtobufFollower) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {\n\tv.Message.Range(func(descriptor protoreflect.FieldDescriptor, value protoreflect.Value) bool {\n\t\tname := descriptor.FullName()\n\t\tfullname := v.Message.Descriptor().FullName()\n\t\tif fullname == \"google.protobuf.Any\" {\n\t\t\tswitch name {\n\t\t\tcase \"google.protobuf.Any.type_url\":\n\t\t\t\tfd := V2JsonProtobufAnyTypeFieldDescriptor{descriptor}\n\t\t\t\treturn f(fd, value)\n\t\t\tcase \"google.protobuf.Any.value\":\n\t\t\t\turl := v.Message.Get(v.Message.Descriptor().Fields().ByName(\"type_url\")).String()\n\t\t\t\tfd := &V2JsonProtobufAnyValueField{descriptor, url}\n\n\t\t\t\tbytesout := v.Message.Get(v.Message.Descriptor().Fields().Get(1)).Bytes()\n\t\t\t\tv2type := serial.V2TypeFromURL(url)\n\t\t\t\tinstance, err := serial.GetInstance(v2type)\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(err)\n\t\t\t\t}\n\t\t\t\tunmarshaler := proto.UnmarshalOptions{AllowPartial: true, Resolver: anyresolverv2{backgroundResolver: serial.GetResolver()}}\n\t\t\t\terr = unmarshaler.Unmarshal(bytesout, instance.(proto.Message))\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(err)\n\t\t\t\t}\n\n\t\t\t\treturn f(fd, protoreflect.ValueOfMessage(&V2JsonProtobufFollower{instance.(proto.Message).ProtoReflect()}))\n\t\t\tdefault:\n\t\t\t\tpanic(\"unexpected any value\")\n\t\t\t}\n\t\t}\n\t\treturn followValue(descriptor, value, f)\n\t})\n}\n\nfunc followValue(descriptor protoreflect.FieldDescriptor, value protoreflect.Value, f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) bool {\n\tfd := V2JsonProtobufFollowerFieldDescriptor{descriptor}\n\tif descriptor.Kind() == protoreflect.MessageKind {\n\t\tif descriptor.IsList() {\n\t\t\tvalue2 := protoreflect.ValueOfList(V2JsonProtobufListFollower{value.List()})\n\t\t\treturn f(fd, value2)\n\t\t}\n\t\tif descriptor.IsMap() {\n\t\t\tvalue2 := protoreflect.ValueOfMap(V2JsonProtobufMapFollower{value.Map(), descriptor.MapValue()})\n\t\t\treturn f(fd, value2)\n\t\t}\n\t\tvalue2 := protoreflect.ValueOfMessage(&V2JsonProtobufFollower{value.Message()})\n\t\treturn f(fd, value2)\n\t}\n\n\treturn f(fd, value)\n}\n\nfunc (v *V2JsonProtobufFollower) Has(descriptor protoreflect.FieldDescriptor) bool {\n\tpanic(\"implement me\")\n}\n\nfunc (v *V2JsonProtobufFollower) Clear(descriptor protoreflect.FieldDescriptor) {\n\tv.Message.Clear(descriptor)\n}\n\nfunc (v *V2JsonProtobufFollower) Set(descriptor protoreflect.FieldDescriptor, value protoreflect.Value) {\n\tswitch descriptor := descriptor.(type) {\n\tcase V2JsonProtobufFollowerFieldDescriptor:\n\t\tv.Message.Set(descriptor.FieldDescriptor, value)\n\tcase *V2JsonProtobufFollowerFieldDescriptor:\n\t\tv.Message.Set(descriptor.FieldDescriptor, value)\n\tcase *V2JsonProtobufAnyValueField:\n\t\tprotodata := value.Message()\n\t\tbytesw, err := proto.MarshalOptions{AllowPartial: true}.Marshal(&V2JsonProtobufAnyValueFieldReturn{protodata})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tv.Message.Set(descriptor.FieldDescriptor, protoreflect.ValueOfBytes(bytesw))\n\tdefault:\n\t\tv.Message.Set(descriptor, value)\n\t}\n}\n\nfunc (v *V2JsonProtobufFollower) Mutable(descriptor protoreflect.FieldDescriptor) protoreflect.Value {\n\tvalue := v.Message.Mutable(descriptor.(V2JsonProtobufFollowerFieldDescriptor).FieldDescriptor)\n\tif descriptor.IsList() {\n\t\treturn protoreflect.ValueOfList(&V2JsonProtobufListFollower{value.List()})\n\t}\n\tif descriptor.IsMap() {\n\t\treturn protoreflect.ValueOfMap(&V2JsonProtobufMapFollower{value.Map(), descriptor})\n\t}\n\tif descriptor.Kind() == protoreflect.MessageKind {\n\t\treturn protoreflect.ValueOfMessage(&V2JsonProtobufFollower{value.Message()})\n\t}\n\treturn value\n}\n\nfunc (v *V2JsonProtobufFollower) NewField(descriptor protoreflect.FieldDescriptor) protoreflect.Value {\n\tif _, ok := descriptor.(*V2JsonProtobufAnyValueField); ok {\n\t\turl := v.Message.Get(v.Message.Descriptor().Fields().ByName(\"type_url\")).String()\n\t\tv2type := serial.V2TypeFromURL(url)\n\t\tinstance, err := serial.GetInstance(v2type)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tnewvalue := protoreflect.ValueOfMessage(&V2JsonProtobufFollower{instance.(proto.Message).ProtoReflect()})\n\t\treturn newvalue\n\t}\n\n\tvalue := v.Message.NewField(descriptor.(V2JsonProtobufFollowerFieldDescriptor).FieldDescriptor)\n\tnewvalue := protoreflect.ValueOfMessage(&V2JsonProtobufFollower{value.Message()})\n\treturn newvalue\n}\n\nfunc (v *V2JsonProtobufFollower) WhichOneof(descriptor protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {\n\tpanic(\"implement me\")\n}\n\nfunc (v *V2JsonProtobufFollower) GetUnknown() protoreflect.RawFields {\n\tpanic(\"implement me\")\n}\n\nfunc (v *V2JsonProtobufFollower) SetUnknown(fields protoreflect.RawFields) {\n\tv.Message.SetUnknown(fields)\n}\n\nfunc (v *V2JsonProtobufFollower) IsValid() bool {\n\treturn v.Message.IsValid()\n}\n\nfunc (v *V2JsonProtobufFollower) ProtoReflect() protoreflect.Message {\n\treturn v\n}\n\nfunc (v *V2JsonProtobufFollower) Descriptor() protoreflect.MessageDescriptor {\n\tfullname := v.Message.Descriptor().FullName()\n\tif fullname == \"google.protobuf.Any\" {\n\t\tdesc := &V2JsonProtobufAnyTypeDescriptor{(&anypb.Any{}).ProtoReflect().Descriptor()}\n\t\treturn desc\n\t}\n\treturn &V2JsonProtobufFollowerDescriptor{v.Message.Descriptor()}\n}\n\nfunc (v *V2JsonProtobufFollower) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {\n\tpanic(\"implement me\")\n}\n\ntype V2JsonProtobufFollowerDescriptor struct {\n\tprotoreflect.MessageDescriptor\n}\n\nfunc (v *V2JsonProtobufFollowerDescriptor) Fields() protoreflect.FieldDescriptors {\n\treturn &V2JsonProtobufFollowerFields{v.MessageDescriptor.Fields()}\n}\n\ntype V2JsonProtobufFollowerFields struct {\n\tprotoreflect.FieldDescriptors\n}\n\nfunc (v *V2JsonProtobufFollowerFields) ByJSONName(s string) protoreflect.FieldDescriptor {\n\treturn V2JsonProtobufFollowerFieldDescriptor{v.FieldDescriptors.ByJSONName(s)}\n}\n\nfunc (v *V2JsonProtobufFollowerFields) ByTextName(s string) protoreflect.FieldDescriptor {\n\treturn V2JsonProtobufFollowerFieldDescriptor{v.FieldDescriptors.ByTextName(s)}\n}\n"
  },
  {
    "path": "infra/conf/v2jsonpb/followerany.go",
    "content": "package v2jsonpb\n\nimport \"google.golang.org/protobuf/reflect/protoreflect\"\n\ntype V2JsonProtobufAnyTypeDescriptor struct {\n\tprotoreflect.MessageDescriptor\n}\n\nfunc (v V2JsonProtobufAnyTypeDescriptor) FullName() protoreflect.FullName {\n\treturn \"org.v2fly.SynAny\"\n}\n\nfunc (v V2JsonProtobufAnyTypeDescriptor) Fields() protoreflect.FieldDescriptors {\n\treturn V2JsonProtobufAnyTypeFields{v.MessageDescriptor.Fields()}\n}\n\ntype V2JsonProtobufAnyTypeFields struct {\n\tprotoreflect.FieldDescriptors\n}\n\nfunc (v V2JsonProtobufAnyTypeFields) Len() int {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufAnyTypeFields) Get(i int) protoreflect.FieldDescriptor {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufAnyTypeFields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufAnyTypeFields) ByJSONName(s string) protoreflect.FieldDescriptor {\n\tswitch s {\n\tcase \"type\":\n\t\treturn &V2JsonProtobufFollowerFieldDescriptor{v.FieldDescriptors.ByName(\"type_url\")}\n\tdefault:\n\t\treturn &V2JsonProtobufAnyValueField{v.FieldDescriptors.ByName(\"value\"), \"value\"}\n\t}\n}\n\nfunc (v V2JsonProtobufAnyTypeFields) ByTextName(s string) protoreflect.FieldDescriptor {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufAnyTypeFields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {\n\tpanic(\"implement me\")\n}\n\ntype V2JsonProtobufAnyTypeFieldDescriptor struct {\n\tprotoreflect.FieldDescriptor\n}\n\nfunc (v V2JsonProtobufAnyTypeFieldDescriptor) JSONName() string {\n\treturn \"type\"\n}\n\nfunc (v V2JsonProtobufAnyTypeFieldDescriptor) TextName() string {\n\treturn \"type\"\n}\n\ntype V2JsonProtobufAnyValueField struct {\n\tprotoreflect.FieldDescriptor\n\tname string\n}\n\nfunc (v *V2JsonProtobufAnyValueField) Kind() protoreflect.Kind {\n\treturn protoreflect.MessageKind\n}\n\nfunc (v *V2JsonProtobufAnyValueField) JSONName() string {\n\treturn v.name\n}\n\nfunc (v *V2JsonProtobufAnyValueField) TextName() string {\n\treturn v.name\n}\n\ntype V2JsonProtobufAnyValueFieldReturn struct {\n\tprotoreflect.Message\n}\n\nfunc (v *V2JsonProtobufAnyValueFieldReturn) ProtoReflect() protoreflect.Message {\n\tif bufFollow, ok := v.Message.(*V2JsonProtobufFollower); ok {\n\t\treturn bufFollow.Message\n\t}\n\treturn v.Message\n}\n"
  },
  {
    "path": "infra/conf/v2jsonpb/followerlist.go",
    "content": "package v2jsonpb\n\nimport \"google.golang.org/protobuf/reflect/protoreflect\"\n\ntype V2JsonProtobufListFollower struct {\n\tprotoreflect.List\n}\n\nfunc (v V2JsonProtobufListFollower) Len() int {\n\treturn v.List.Len()\n}\n\nfunc (v V2JsonProtobufListFollower) Get(i int) protoreflect.Value {\n\treturn protoreflect.ValueOfMessage(&V2JsonProtobufFollower{v.List.Get(i).Message()})\n}\n\nfunc (v V2JsonProtobufListFollower) Set(i int, value protoreflect.Value) {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufListFollower) Append(value protoreflect.Value) {\n\tv.List.Append(value)\n}\n\nfunc (v V2JsonProtobufListFollower) AppendMutable() protoreflect.Value {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufListFollower) Truncate(i int) {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufListFollower) NewElement() protoreflect.Value {\n\tnewelement := v.List.NewElement()\n\treturn protoreflect.ValueOfMessage(&V2JsonProtobufFollower{newelement.Message()})\n}\n\nfunc (v V2JsonProtobufListFollower) IsValid() bool {\n\tpanic(\"implement me\")\n}\n"
  },
  {
    "path": "infra/conf/v2jsonpb/followermap.go",
    "content": "package v2jsonpb\n\nimport \"google.golang.org/protobuf/reflect/protoreflect\"\n\ntype V2JsonProtobufMapFollower struct {\n\tprotoreflect.Map\n\tValueKind protoreflect.FieldDescriptor\n}\n\nfunc (v V2JsonProtobufMapFollower) Len() int {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufMapFollower) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) {\n\tv.Map.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool {\n\t\treturn followMapValue(v.ValueKind, value, key, f)\n\t})\n}\n\nfunc (v V2JsonProtobufMapFollower) Has(key protoreflect.MapKey) bool {\n\treturn v.Map.Has(key)\n}\n\nfunc (v V2JsonProtobufMapFollower) Clear(key protoreflect.MapKey) {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufMapFollower) Get(key protoreflect.MapKey) protoreflect.Value {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufMapFollower) Set(key protoreflect.MapKey, value protoreflect.Value) {\n\tv.Map.Set(key, value)\n}\n\nfunc (v V2JsonProtobufMapFollower) Mutable(key protoreflect.MapKey) protoreflect.Value {\n\tpanic(\"implement me\")\n}\n\nfunc (v V2JsonProtobufMapFollower) NewValue() protoreflect.Value {\n\tnewelement := v.Map.NewValue()\n\treturn protoreflect.ValueOfMessage(&V2JsonProtobufFollower{newelement.Message()})\n}\n\nfunc (v V2JsonProtobufMapFollower) IsValid() bool {\n\tpanic(\"implement me\")\n}\n\nfunc followMapValue(descriptor protoreflect.FieldDescriptor, value protoreflect.Value, mapkey protoreflect.MapKey, f func(protoreflect.MapKey, protoreflect.Value) bool) bool {\n\tif descriptor.Kind() == protoreflect.MessageKind {\n\t\tif descriptor.IsList() {\n\t\t\tvalue2 := protoreflect.ValueOfList(V2JsonProtobufListFollower{value.List()})\n\t\t\treturn f(mapkey, value2)\n\t\t}\n\t\tif descriptor.IsMap() {\n\t\t\tvalue2 := protoreflect.ValueOfMap(V2JsonProtobufMapFollower{value.Map(), descriptor.MapValue()})\n\t\t\treturn f(mapkey, value2)\n\t\t}\n\t\tvalue2 := protoreflect.ValueOfMessage(&V2JsonProtobufFollower{value.Message()})\n\t\treturn f(mapkey, value2)\n\t}\n\n\treturn f(mapkey, value)\n}\n"
  },
  {
    "path": "infra/conf/v2jsonpb/v2jsonpb.go",
    "content": "package v2jsonpb\n\nimport (\n\t\"io\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc loadV2JsonPb(data []byte) (*core.Config, error) {\n\tcoreconf := &core.Config{}\n\tjsonpbloader := &protojson.UnmarshalOptions{Resolver: anyresolverv2{serial.GetResolver()}, AllowPartial: true}\n\terr := jsonpbloader.Unmarshal(data, &V2JsonProtobufFollower{coreconf.ProtoReflect()})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn coreconf, nil\n}\n\nfunc dumpV2JsonPb(config proto.Message) ([]byte, error) {\n\tjsonpbdumper := &protojson.MarshalOptions{Resolver: anyresolverv2{serial.GetResolver()}, AllowPartial: true}\n\tbytew, err := jsonpbdumper.Marshal(&V2JsonProtobufFollower{config.ProtoReflect()})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bytew, nil\n}\n\nfunc DumpV2JsonPb(config proto.Message) ([]byte, error) {\n\treturn dumpV2JsonPb(config)\n}\n\nconst FormatProtobufV2JSONPB = \"v2jsonpb\"\n\nfunc init() {\n\tcommon.Must(core.RegisterConfigLoader(&core.ConfigFormat{\n\t\tName:      []string{FormatProtobufV2JSONPB},\n\t\tExtension: []string{\".v2pb.json\", \".v2pbjson\"},\n\t\tLoader: func(input interface{}) (*core.Config, error) {\n\t\t\tswitch v := input.(type) {\n\t\t\tcase string:\n\t\t\t\tr, err := cmdarg.LoadArg(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\tdata, err := buf.ReadAllToBytes(r)\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 loadV2JsonPb(data)\n\t\t\tcase []byte:\n\t\t\t\treturn loadV2JsonPb(v)\n\t\t\tcase io.Reader:\n\t\t\t\tdata, err := buf.ReadAllToBytes(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\treturn loadV2JsonPb(data)\n\t\t\tdefault:\n\t\t\t\treturn nil, newError(\"unknown type\")\n\t\t\t}\n\t\t},\n\t}))\n}\n"
  },
  {
    "path": "infra/conf/v4/api.go",
    "content": "package v4\n\nimport (\n\t\"strings\"\n\n\t\"github.com/jhump/protoreflect/desc\"\n\t\"github.com/jhump/protoreflect/dynamic\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/commander\"\n\tloggerservice \"github.com/v2fly/v2ray-core/v5/app/log/command\"\n\tobservatoryservice \"github.com/v2fly/v2ray-core/v5/app/observatory/command\"\n\thandlerservice \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\trouterservice \"github.com/v2fly/v2ray-core/v5/app/router/command\"\n\tstatsservice \"github.com/v2fly/v2ray-core/v5/app/stats/command\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype APIConfig struct {\n\tTag      string   `json:\"tag\"`\n\tServices []string `json:\"services\"`\n}\n\nfunc (c *APIConfig) Build() (*commander.Config, error) {\n\tif c.Tag == \"\" {\n\t\treturn nil, newError(\"API tag can't be empty.\")\n\t}\n\n\tservices := make([]*anypb.Any, 0, 16)\n\tfor _, s := range c.Services {\n\t\tswitch strings.ToLower(s) {\n\t\tcase \"reflectionservice\":\n\t\t\tservices = append(services, serial.ToTypedMessage(&commander.ReflectionConfig{}))\n\t\tcase \"handlerservice\":\n\t\t\tservices = append(services, serial.ToTypedMessage(&handlerservice.Config{}))\n\t\tcase \"loggerservice\":\n\t\t\tservices = append(services, serial.ToTypedMessage(&loggerservice.Config{}))\n\t\tcase \"statsservice\":\n\t\t\tservices = append(services, serial.ToTypedMessage(&statsservice.Config{}))\n\t\tcase \"observatoryservice\":\n\t\t\tservices = append(services, serial.ToTypedMessage(&observatoryservice.Config{}))\n\t\tcase \"routingservice\":\n\t\t\tservices = append(services, serial.ToTypedMessage(&routerservice.Config{}))\n\t\tdefault:\n\t\t\tif !strings.HasPrefix(s, \"#\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmessage, err := desc.LoadMessageDescriptor(s[1:])\n\t\t\tif err != nil || message == nil {\n\t\t\t\treturn nil, newError(\"Cannot find API\", s, \"\").Base(err)\n\t\t\t}\n\t\t\tserviceConfig := dynamic.NewMessage(message)\n\t\t\tservices = append(services, serial.ToTypedMessage(serviceConfig))\n\t\t}\n\t}\n\n\treturn &commander.Config{\n\t\tTag:     c.Tag,\n\t\tService: services,\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/blackhole.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/loader\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n)\n\ntype NoneResponse struct{}\n\nfunc (*NoneResponse) Build() (proto.Message, error) {\n\treturn new(blackhole.NoneResponse), nil\n}\n\ntype HTTPResponse struct{}\n\nfunc (*HTTPResponse) Build() (proto.Message, error) {\n\treturn new(blackhole.HTTPResponse), nil\n}\n\ntype BlackholeConfig struct {\n\tResponse json.RawMessage `json:\"response\"`\n}\n\nfunc (v *BlackholeConfig) Build() (proto.Message, error) {\n\tconfig := new(blackhole.Config)\n\tif v.Response != nil {\n\t\tresponse, _, err := configLoader.Load(v.Response)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Config: Failed to parse Blackhole response config.\").Base(err)\n\t\t}\n\t\tresponseSettings, err := response.(cfgcommon.Buildable).Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Response = serial.ToTypedMessage(responseSettings)\n\t}\n\n\treturn config, nil\n}\n\nvar configLoader = loader.NewJSONConfigLoader(\n\tloader.ConfigCreatorCache{\n\t\t\"none\": func() interface{} { return new(NoneResponse) },\n\t\t\"http\": func() interface{} { return new(HTTPResponse) },\n\t},\n\t\"type\",\n\t\"\")\n"
  },
  {
    "path": "infra/conf/v4/blackhole_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n)\n\nfunc TestHTTPResponseJSON(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.BlackholeConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"response\": {\n\t\t\t\t\t\"type\": \"http\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &blackhole.Config{\n\t\t\t\tResponse: serial.ToTypedMessage(&blackhole.HTTPResponse{}),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput:  `{}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &blackhole.Config{},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/browser_forwarder.go",
    "content": "package v4\n\nimport (\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/browserforwarder\"\n)\n\ntype BrowserForwarderConfig struct {\n\tListenAddr string `json:\"listenAddr\"`\n\tListenPort int32  `json:\"listenPort\"`\n}\n\nfunc (b *BrowserForwarderConfig) Build() (proto.Message, error) {\n\tb.ListenAddr = strings.TrimSpace(b.ListenAddr)\n\tif b.ListenAddr != \"\" && b.ListenPort == 0 {\n\t\tb.ListenPort = 54321\n\t}\n\treturn &browserforwarder.Config{\n\t\tListenAddr: b.ListenAddr,\n\t\tListenPort: b.ListenPort,\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/conf.go",
    "content": "package v4\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "infra/conf/v4/dns_proxy.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dns\"\n)\n\ntype DNSOutboundConfig struct {\n\tNetwork   cfgcommon.Network  `json:\"network\"`\n\tAddress   *cfgcommon.Address `json:\"address\"`\n\tPort      uint16             `json:\"port\"`\n\tUserLevel uint32             `json:\"userLevel\"`\n}\n\nfunc (c *DNSOutboundConfig) Build() (proto.Message, error) {\n\tconfig := &dns.Config{\n\t\tServer: &net.Endpoint{\n\t\t\tNetwork: c.Network.Build(),\n\t\t\tPort:    uint32(c.Port),\n\t\t},\n\t\tUserLevel: c.UserLevel,\n\t}\n\tif c.Address != nil {\n\t\tconfig.Server.Address = c.Address.Build()\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/dns_proxy_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dns\"\n)\n\nfunc TestDnsProxyConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.DNSOutboundConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"address\": \"8.8.8.8\",\n\t\t\t\t\"port\": 53,\n\t\t\t\t\"network\": \"tcp\"\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &dns.Config{\n\t\t\t\tServer: &net.Endpoint{\n\t\t\t\t\tNetwork: net.Network_TCP,\n\t\t\t\t\tAddress: net.NewIPOrDomain(net.IPAddress([]byte{8, 8, 8, 8})),\n\t\t\t\t\tPort:    53,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/dokodemo.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n)\n\ntype DokodemoConfig struct {\n\tHost         *cfgcommon.Address     `json:\"address\"`\n\tPortValue    uint16                 `json:\"port\"`\n\tNetworkList  *cfgcommon.NetworkList `json:\"network\"`\n\tTimeoutValue uint32                 `json:\"timeout\"`\n\tRedirect     bool                   `json:\"followRedirect\"`\n\tUserLevel    uint32                 `json:\"userLevel\"`\n}\n\nfunc (v *DokodemoConfig) Build() (proto.Message, error) {\n\tconfig := new(dokodemo.Config)\n\tif v.Host != nil {\n\t\tconfig.Address = v.Host.Build()\n\t}\n\tconfig.Port = uint32(v.PortValue)\n\tconfig.Networks = v.NetworkList.Build()\n\tconfig.Timeout = v.TimeoutValue\n\tconfig.FollowRedirect = v.Redirect\n\tconfig.UserLevel = v.UserLevel\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/dokodemo_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n)\n\nfunc TestDokodemoConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.DokodemoConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"address\": \"8.8.8.8\",\n\t\t\t\t\"port\": 53,\n\t\t\t\t\"network\": \"tcp\",\n\t\t\t\t\"timeout\": 10,\n\t\t\t\t\"followRedirect\": true,\n\t\t\t\t\"userLevel\": 1\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &dokodemo.Config{\n\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\tIp: []byte{8, 8, 8, 8},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPort:           53,\n\t\t\t\tNetworks:       []net.Network{net.Network_TCP},\n\t\t\t\tTimeout:        10,\n\t\t\t\tFollowRedirect: true,\n\t\t\t\tUserLevel:      1,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/errors.generated.go",
    "content": "package v4\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/v4/freedom.go",
    "content": "package v4\n\nimport (\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n)\n\ntype FreedomConfig struct {\n\tDomainStrategy string  `json:\"domainStrategy\"`\n\tTimeout        *uint32 `json:\"timeout\"`\n\tRedirect       string  `json:\"redirect\"`\n\tUserLevel      uint32  `json:\"userLevel\"`\n}\n\n// Build implements Buildable\nfunc (c *FreedomConfig) Build() (proto.Message, error) {\n\tconfig := new(freedom.Config)\n\tconfig.DomainStrategy = freedom.Config_AS_IS\n\tswitch strings.ToLower(c.DomainStrategy) {\n\tcase \"useip\", \"use_ip\", \"use-ip\":\n\t\tconfig.DomainStrategy = freedom.Config_USE_IP\n\tcase \"useip4\", \"useipv4\", \"use_ip4\", \"use_ipv4\", \"use_ip_v4\", \"use-ip4\", \"use-ipv4\", \"use-ip-v4\":\n\t\tconfig.DomainStrategy = freedom.Config_USE_IP4\n\tcase \"useip6\", \"useipv6\", \"use_ip6\", \"use_ipv6\", \"use_ip_v6\", \"use-ip6\", \"use-ipv6\", \"use-ip-v6\":\n\t\tconfig.DomainStrategy = freedom.Config_USE_IP6\n\t}\n\n\tif c.Timeout != nil {\n\t\tconfig.Timeout = *c.Timeout\n\t}\n\tconfig.UserLevel = c.UserLevel\n\tif len(c.Redirect) > 0 {\n\t\thost, portStr, err := net.SplitHostPort(c.Redirect)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid redirect address: \", c.Redirect, \": \", err).Base(err)\n\t\t}\n\t\tport, err := v2net.PortFromString(portStr)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid redirect port: \", c.Redirect, \": \", err).Base(err)\n\t\t}\n\t\tconfig.DestinationOverride = &freedom.DestinationOverride{\n\t\t\tServer: &protocol.ServerEndpoint{\n\t\t\t\tPort: uint32(port),\n\t\t\t},\n\t\t}\n\n\t\tif len(host) > 0 {\n\t\t\tconfig.DestinationOverride.Server.Address = v2net.NewIPOrDomain(v2net.ParseAddress(host))\n\t\t}\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/freedom_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n)\n\nfunc TestFreedomConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.FreedomConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"domainStrategy\": \"AsIs\",\n\t\t\t\t\"timeout\": 10,\n\t\t\t\t\"redirect\": \"127.0.0.1:3366\",\n\t\t\t\t\"userLevel\": 1\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &freedom.Config{\n\t\t\t\tDomainStrategy: freedom.Config_AS_IS,\n\t\t\t\tTimeout:        10,\n\t\t\t\tDestinationOverride: &freedom.DestinationOverride{\n\t\t\t\t\tServer: &protocol.ServerEndpoint{\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 3366,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tUserLevel: 1,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/gun.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/grpc\"\n)\n\ntype GunConfig struct {\n\tServiceName         string `json:\"serviceName\"`\n\tIdleTimeout         int32  `json:\"idle_timeout\"`\n\tHealthCheckTimeout  int32  `json:\"health_check_timeout\"`\n\tPermitWithoutStream bool   `json:\"permit_without_stream\"`\n\tInitialWindowsSize  int32  `json:\"initial_windows_size\"`\n}\n\nfunc (g GunConfig) Build() (proto.Message, error) {\n\tif g.IdleTimeout <= 0 {\n\t\tg.IdleTimeout = 0\n\t}\n\tif g.HealthCheckTimeout <= 0 {\n\t\tg.HealthCheckTimeout = 0\n\t}\n\tif g.InitialWindowsSize < 0 {\n\t\tg.InitialWindowsSize = 0\n\t}\n\treturn &grpc.Config{\n\t\tServiceName:         g.ServiceName,\n\t\tIdleTimeout:         g.IdleTimeout,\n\t\tHealthCheckTimeout:  g.HealthCheckTimeout,\n\t\tPermitWithoutStream: g.PermitWithoutStream,\n\t\tInitialWindowsSize:  g.InitialWindowsSize,\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/http.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/http\"\n)\n\ntype HTTPAccount struct {\n\tUsername string `json:\"user\"`\n\tPassword string `json:\"pass\"`\n}\n\nfunc (v *HTTPAccount) Build() *http.Account {\n\treturn &http.Account{\n\t\tUsername: v.Username,\n\t\tPassword: v.Password,\n\t}\n}\n\ntype HTTPServerConfig struct {\n\tTimeout     uint32         `json:\"timeout\"`\n\tAccounts    []*HTTPAccount `json:\"accounts\"`\n\tTransparent bool           `json:\"allowTransparent\"`\n\tUserLevel   uint32         `json:\"userLevel\"`\n}\n\nfunc (c *HTTPServerConfig) Build() (proto.Message, error) {\n\tconfig := &http.ServerConfig{\n\t\tTimeout:          c.Timeout,\n\t\tAllowTransparent: c.Transparent,\n\t\tUserLevel:        c.UserLevel,\n\t}\n\n\tif len(c.Accounts) > 0 {\n\t\tconfig.Accounts = make(map[string]string)\n\t\tfor _, account := range c.Accounts {\n\t\t\tconfig.Accounts[account.Username] = account.Password\n\t\t}\n\t}\n\n\treturn config, nil\n}\n\ntype HTTPRemoteConfig struct {\n\tAddress *cfgcommon.Address `json:\"address\"`\n\tPort    uint16             `json:\"port\"`\n\tUsers   []json.RawMessage  `json:\"users\"`\n}\n\ntype HTTPClientConfig struct {\n\tServers []*HTTPRemoteConfig `json:\"servers\"`\n}\n\nfunc (v *HTTPClientConfig) Build() (proto.Message, error) {\n\tconfig := new(http.ClientConfig)\n\tconfig.Server = make([]*protocol.ServerEndpoint, len(v.Servers))\n\tfor idx, serverConfig := range v.Servers {\n\t\tserver := &protocol.ServerEndpoint{\n\t\t\tAddress: serverConfig.Address.Build(),\n\t\t\tPort:    uint32(serverConfig.Port),\n\t\t}\n\t\tfor _, rawUser := range serverConfig.Users {\n\t\t\tuser := new(protocol.User)\n\t\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse HTTP user\").Base(err).AtError()\n\t\t\t}\n\t\t\taccount := new(HTTPAccount)\n\t\t\tif err := json.Unmarshal(rawUser, account); err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse HTTP account\").Base(err).AtError()\n\t\t\t}\n\t\t\tuser.Account = serial.ToTypedMessage(account.Build())\n\t\t\tserver.User = append(server.User, user)\n\t\t}\n\t\tconfig.Server[idx] = server\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/http_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/http\"\n)\n\nfunc TestHTTPServerConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.HTTPServerConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"timeout\": 10,\n\t\t\t\t\"accounts\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"user\": \"my-username\",\n\t\t\t\t\t\t\"pass\": \"my-password\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"allowTransparent\": true,\n\t\t\t\t\"userLevel\": 1\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &http.ServerConfig{\n\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\"my-username\": \"my-password\",\n\t\t\t\t},\n\t\t\t\tAllowTransparent: true,\n\t\t\t\tUserLevel:        1,\n\t\t\t\tTimeout:          10,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/hysteria2.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/hysteria2\"\n)\n\n// Hysteria2ServerTarget is configuration of a single hysteria2 server\ntype Hysteria2ServerTarget struct {\n\tAddress *cfgcommon.Address `json:\"address\"`\n\tPort    uint16             `json:\"port\"`\n\tEmail   string             `json:\"email\"`\n\tLevel   byte               `json:\"level\"`\n}\n\n// Hysteria2ClientConfig is configuration of hysteria2 servers\ntype Hysteria2ClientConfig struct {\n\tServers []*Hysteria2ServerTarget `json:\"servers\"`\n}\n\n// Build implements Buildable\nfunc (c *Hysteria2ClientConfig) Build() (proto.Message, error) {\n\tconfig := new(hysteria2.ClientConfig)\n\n\tif len(c.Servers) == 0 {\n\t\treturn nil, newError(\"0 Hysteria2 server configured.\")\n\t}\n\n\tserverSpecs := make([]*protocol.ServerEndpoint, len(c.Servers))\n\tfor idx, rec := range c.Servers {\n\t\tif rec.Address == nil {\n\t\t\treturn nil, newError(\"Hysteria2 server address is not set.\")\n\t\t}\n\t\tif rec.Port == 0 {\n\t\t\treturn nil, newError(\"Invalid Hysteria2 port.\")\n\t\t}\n\t\taccount := &hysteria2.Account{}\n\t\thysteria2 := &protocol.ServerEndpoint{\n\t\t\tAddress: rec.Address.Build(),\n\t\t\tPort:    uint32(rec.Port),\n\t\t\tUser: []*protocol.User{\n\t\t\t\t{\n\t\t\t\t\tLevel:   uint32(rec.Level),\n\t\t\t\t\tEmail:   rec.Email,\n\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tserverSpecs[idx] = hysteria2\n\t}\n\n\tconfig.Server = serverSpecs\n\n\treturn config, nil\n}\n\n// Hysteria2ServerConfig is Inbound configuration\ntype Hysteria2ServerConfig struct {\n\tPacketEncoding string `json:\"packetEncoding\"`\n}\n\n// Build implements Buildable\nfunc (c *Hysteria2ServerConfig) Build() (proto.Message, error) {\n\tconfig := new(hysteria2.ServerConfig)\n\tswitch c.PacketEncoding {\n\tcase \"Packet\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_Packet\n\tcase \"\", \"None\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_None\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/lint.go",
    "content": "package v4\n\ntype ConfigureFilePostProcessingStage interface {\n\tProcess(conf *Config) error\n}\n\nvar configureFilePostProcessingStages map[string]ConfigureFilePostProcessingStage\n\nfunc RegisterConfigureFilePostProcessingStage(name string, stage ConfigureFilePostProcessingStage) {\n\tif configureFilePostProcessingStages == nil {\n\t\tconfigureFilePostProcessingStages = make(map[string]ConfigureFilePostProcessingStage)\n\t}\n\tconfigureFilePostProcessingStages[name] = stage\n}\n\nfunc PostProcessConfigureFile(conf *Config) error {\n\tfor k, v := range configureFilePostProcessingStages {\n\t\tif err := v.Process(conf); err != nil {\n\t\t\treturn newError(\"Rejected by Postprocessing Stage \", k).AtError().Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "infra/conf/v4/loopback.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/proxy/loopback\"\n)\n\ntype LoopbackConfig struct {\n\tInboundTag string `json:\"inboundTag\"`\n}\n\nfunc (l LoopbackConfig) Build() (proto.Message, error) {\n\treturn &loopback.Config{InboundTag: l.InboundTag}, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/observatory.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory/burst\"\n\t\"github.com/v2fly/v2ray-core/v5/app/observatory/multiobservatory\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/taggedfeatures\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/duration\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/router\"\n)\n\ntype ObservatoryConfig struct {\n\tSubjectSelector []string          `json:\"subjectSelector\"`\n\tProbeURL        string            `json:\"probeURL\"`\n\tProbeInterval   duration.Duration `json:\"probeInterval\"`\n}\n\nfunc (o *ObservatoryConfig) Build() (proto.Message, error) {\n\treturn &observatory.Config{SubjectSelector: o.SubjectSelector, ProbeUrl: o.ProbeURL, ProbeInterval: int64(o.ProbeInterval)}, nil\n}\n\ntype BurstObservatoryConfig struct {\n\tSubjectSelector []string `json:\"subjectSelector\"`\n\t// health check settings\n\tHealthCheck *router.HealthCheckSettings `json:\"pingConfig,omitempty\"`\n}\n\nfunc (b BurstObservatoryConfig) Build() (proto.Message, error) {\n\tresult, err := b.HealthCheck.Build()\n\tif err == nil {\n\t\treturn &burst.Config{SubjectSelector: b.SubjectSelector, PingConfig: result.(*burst.HealthPingConfig)}, nil\n\t}\n\treturn nil, err\n}\n\ntype MultiObservatoryItem struct {\n\tMemberType string          `json:\"type\"`\n\tTag        string          `json:\"tag\"`\n\tValue      json.RawMessage `json:\"settings\"`\n}\n\ntype MultiObservatoryConfig struct {\n\tObservers []MultiObservatoryItem `json:\"observers\"`\n}\n\nfunc (o *MultiObservatoryConfig) Build() (proto.Message, error) {\n\tret := &multiobservatory.Config{Holders: &taggedfeatures.Config{Features: make(map[string]*anypb.Any)}}\n\tfor _, v := range o.Observers {\n\t\tswitch v.MemberType {\n\t\tcase \"burst\":\n\t\t\tvar burstObservatoryConfig BurstObservatoryConfig\n\t\t\terr := json.Unmarshal(v.Value, &burstObservatoryConfig)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tburstObservatoryConfigPb, err := burstObservatoryConfig.Build()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tret.Holders.Features[v.Tag] = serial.ToTypedMessage(burstObservatoryConfigPb)\n\t\tcase \"default\":\n\t\t\tfallthrough\n\t\tdefault:\n\t\t\tvar observatoryConfig ObservatoryConfig\n\t\t\terr := json.Unmarshal(v.Value, &observatoryConfig)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tobservatoryConfigPb, err := observatoryConfig.Build()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tret.Holders.Features[v.Tag] = serial.ToTypedMessage(observatoryConfigPb)\n\t\t}\n\t}\n\treturn ret, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/policy.go",
    "content": "package v4\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n)\n\ntype Policy struct {\n\tHandshake         *uint32 `json:\"handshake\"`\n\tConnectionIdle    *uint32 `json:\"connIdle\"`\n\tUplinkOnly        *uint32 `json:\"uplinkOnly\"`\n\tDownlinkOnly      *uint32 `json:\"downlinkOnly\"`\n\tStatsUserUplink   bool    `json:\"statsUserUplink\"`\n\tStatsUserDownlink bool    `json:\"statsUserDownlink\"`\n\tBufferSize        *int32  `json:\"bufferSize\"`\n}\n\nfunc (t *Policy) Build() (*policy.Policy, error) {\n\tconfig := new(policy.Policy_Timeout)\n\tif t.Handshake != nil {\n\t\tconfig.Handshake = &policy.Second{Value: *t.Handshake}\n\t}\n\tif t.ConnectionIdle != nil {\n\t\tconfig.ConnectionIdle = &policy.Second{Value: *t.ConnectionIdle}\n\t}\n\tif t.UplinkOnly != nil {\n\t\tconfig.UplinkOnly = &policy.Second{Value: *t.UplinkOnly}\n\t}\n\tif t.DownlinkOnly != nil {\n\t\tconfig.DownlinkOnly = &policy.Second{Value: *t.DownlinkOnly}\n\t}\n\n\tp := &policy.Policy{\n\t\tTimeout: config,\n\t\tStats: &policy.Policy_Stats{\n\t\t\tUserUplink:   t.StatsUserUplink,\n\t\t\tUserDownlink: t.StatsUserDownlink,\n\t\t},\n\t}\n\n\tif t.BufferSize != nil {\n\t\tbs := int32(-1)\n\t\tif *t.BufferSize >= 0 {\n\t\t\tbs = (*t.BufferSize) * 1024\n\t\t}\n\t\tp.Buffer = &policy.Policy_Buffer{\n\t\t\tConnection: bs,\n\t\t}\n\t}\n\n\treturn p, nil\n}\n\ntype SystemPolicy struct {\n\tStatsInboundUplink    bool `json:\"statsInboundUplink\"`\n\tStatsInboundDownlink  bool `json:\"statsInboundDownlink\"`\n\tStatsOutboundUplink   bool `json:\"statsOutboundUplink\"`\n\tStatsOutboundDownlink bool `json:\"statsOutboundDownlink\"`\n\tOverrideAccessLogDest bool `json:\"overrideAccessLogDest\"`\n}\n\nfunc (p *SystemPolicy) Build() (*policy.SystemPolicy, error) {\n\treturn &policy.SystemPolicy{\n\t\tStats: &policy.SystemPolicy_Stats{\n\t\t\tInboundUplink:    p.StatsInboundUplink,\n\t\t\tInboundDownlink:  p.StatsInboundDownlink,\n\t\t\tOutboundUplink:   p.StatsOutboundUplink,\n\t\t\tOutboundDownlink: p.StatsOutboundDownlink,\n\t\t},\n\t\tOverrideAccessLogDest: p.OverrideAccessLogDest,\n\t}, nil\n}\n\ntype PolicyConfig struct {\n\tLevels map[uint32]*Policy `json:\"levels\"`\n\tSystem *SystemPolicy      `json:\"system\"`\n}\n\nfunc (c *PolicyConfig) Build() (*policy.Config, error) {\n\tlevels := make(map[uint32]*policy.Policy)\n\tfor l, p := range c.Levels {\n\t\tif p != nil {\n\t\t\tpp, err := p.Build()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tlevels[l] = pp\n\t\t}\n\t}\n\tconfig := &policy.Config{\n\t\tLevel: levels,\n\t}\n\n\tif c.System != nil {\n\t\tsc, err := c.System.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.System = sc\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/policy_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n)\n\nfunc TestBufferSize(t *testing.T) {\n\tcases := []struct {\n\t\tInput  int32\n\t\tOutput int32\n\t}{\n\t\t{\n\t\t\tInput:  0,\n\t\t\tOutput: 0,\n\t\t},\n\t\t{\n\t\t\tInput:  -1,\n\t\t\tOutput: -1,\n\t\t},\n\t\t{\n\t\t\tInput:  1,\n\t\t\tOutput: 1024,\n\t\t},\n\t}\n\n\tfor _, c := range cases {\n\t\tbs := c.Input\n\t\tpConf := v4.Policy{\n\t\t\tBufferSize: &bs,\n\t\t}\n\t\tp, err := pConf.Build()\n\t\tcommon.Must(err)\n\t\tif p.Buffer.Connection != c.Output {\n\t\t\tt.Error(\"expected buffer size \", c.Output, \" but got \", p.Buffer.Connection)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "infra/conf/v4/reverse.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/reverse\"\n)\n\ntype BridgeConfig struct {\n\tTag    string `json:\"tag\"`\n\tDomain string `json:\"domain\"`\n}\n\nfunc (c *BridgeConfig) Build() (*reverse.BridgeConfig, error) {\n\treturn &reverse.BridgeConfig{\n\t\tTag:    c.Tag,\n\t\tDomain: c.Domain,\n\t}, nil\n}\n\ntype PortalConfig struct {\n\tTag    string `json:\"tag\"`\n\tDomain string `json:\"domain\"`\n}\n\nfunc (c *PortalConfig) Build() (*reverse.PortalConfig, error) {\n\treturn &reverse.PortalConfig{\n\t\tTag:    c.Tag,\n\t\tDomain: c.Domain,\n\t}, nil\n}\n\ntype ReverseConfig struct {\n\tBridges []BridgeConfig `json:\"bridges\"`\n\tPortals []PortalConfig `json:\"portals\"`\n}\n\nfunc (c *ReverseConfig) Build() (proto.Message, error) {\n\tconfig := &reverse.Config{}\n\tfor _, bconfig := range c.Bridges {\n\t\tb, err := bconfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.BridgeConfig = append(config.BridgeConfig, b)\n\t}\n\n\tfor _, pconfig := range c.Portals {\n\t\tp, err := pconfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.PortalConfig = append(config.PortalConfig, p)\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/reverse_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/reverse\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n)\n\nfunc TestReverseConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.ReverseConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"bridges\": [{\n\t\t\t\t\t\"tag\": \"test\",\n\t\t\t\t\t\"domain\": \"test.v2fly.org\"\n\t\t\t\t}]\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &reverse.Config{\n\t\t\t\tBridgeConfig: []*reverse.BridgeConfig{\n\t\t\t\t\t{Tag: \"test\", Domain: \"test.v2fly.org\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"portals\": [{\n\t\t\t\t\t\"tag\": \"test\",\n\t\t\t\t\t\"domain\": \"test.v2fly.org\"\n\t\t\t\t}]\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &reverse.Config{\n\t\t\t\tPortalConfig: []*reverse.PortalConfig{\n\t\t\t\t\t{Tag: \"test\", Domain: \"test.v2fly.org\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/services.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n\t\"github.com/jhump/protoreflect/desc\"\n\t\"github.com/jhump/protoreflect/dynamic\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nfunc (c *Config) BuildServices(service map[string]*json.RawMessage) ([]*anypb.Any, error) {\n\tvar ret []*anypb.Any\n\tfor k, v := range service {\n\t\tmessage, err := desc.LoadMessageDescriptor(k)\n\t\tif err != nil || message == nil {\n\t\t\treturn nil, newError(\"Cannot find service\", k, \"\").Base(err)\n\t\t}\n\n\t\tserviceConfig := dynamic.NewMessage(message)\n\n\t\tif err := serviceConfig.UnmarshalJSONPB(&jsonpb.Unmarshaler{AllowUnknownFields: false}, *v); err != nil {\n\t\t\treturn nil, newError(\"Cannot interpret service configure file\", k, \"\").Base(err)\n\t\t}\n\n\t\tret = append(ret, serial.ToTypedMessage(serviceConfig))\n\t}\n\treturn ret, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/shadowsocks.go",
    "content": "package v4\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n)\n\ntype ShadowsocksServerConfig struct {\n\tCipher         string                 `json:\"method\"`\n\tPassword       string                 `json:\"password\"`\n\tUDP            bool                   `json:\"udp\"`\n\tLevel          byte                   `json:\"level\"`\n\tEmail          string                 `json:\"email\"`\n\tNetworkList    *cfgcommon.NetworkList `json:\"network\"`\n\tIVCheck        bool                   `json:\"ivCheck\"`\n\tPacketEncoding string                 `json:\"packetEncoding\"`\n}\n\nfunc (v *ShadowsocksServerConfig) Build() (proto.Message, error) {\n\tconfig := new(shadowsocks.ServerConfig)\n\tconfig.UdpEnabled = v.UDP\n\tconfig.Network = v.NetworkList.Build()\n\n\tif v.Password == \"\" {\n\t\treturn nil, newError(\"Shadowsocks password is not specified.\")\n\t}\n\taccount := &shadowsocks.Account{\n\t\tPassword: v.Password,\n\t\tIvCheck:  v.IVCheck,\n\t}\n\taccount.CipherType = shadowsocks.CipherFromString(v.Cipher)\n\tif account.CipherType == shadowsocks.CipherType_UNKNOWN {\n\t\treturn nil, newError(\"unknown cipher method: \", v.Cipher)\n\t}\n\n\tconfig.User = &protocol.User{\n\t\tEmail:   v.Email,\n\t\tLevel:   uint32(v.Level),\n\t\tAccount: serial.ToTypedMessage(account),\n\t}\n\n\tswitch v.PacketEncoding {\n\tcase \"Packet\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_Packet\n\tcase \"\", \"None\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_None\n\t}\n\n\treturn config, nil\n}\n\ntype ShadowsocksServerTarget struct {\n\tAddress  *cfgcommon.Address `json:\"address\"`\n\tPort     uint16             `json:\"port\"`\n\tCipher   string             `json:\"method\"`\n\tPassword string             `json:\"password\"`\n\tEmail    string             `json:\"email\"`\n\tOta      bool               `json:\"ota\"`\n\tLevel    byte               `json:\"level\"`\n\tIVCheck  bool               `json:\"ivCheck\"`\n}\n\ntype ShadowsocksClientConfig struct {\n\tServers []*ShadowsocksServerTarget `json:\"servers\"`\n}\n\nfunc (v *ShadowsocksClientConfig) Build() (proto.Message, error) {\n\tconfig := new(shadowsocks.ClientConfig)\n\n\tif len(v.Servers) == 0 {\n\t\treturn nil, newError(\"0 Shadowsocks server configured.\")\n\t}\n\n\tserverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers))\n\tfor idx, server := range v.Servers {\n\t\tif server.Address == nil {\n\t\t\treturn nil, newError(\"Shadowsocks server address is not set.\")\n\t\t}\n\t\tif server.Port == 0 {\n\t\t\treturn nil, newError(\"Invalid Shadowsocks port.\")\n\t\t}\n\t\tif server.Password == \"\" {\n\t\t\treturn nil, newError(\"Shadowsocks password is not specified.\")\n\t\t}\n\t\taccount := &shadowsocks.Account{\n\t\t\tPassword: server.Password,\n\t\t}\n\t\taccount.CipherType = shadowsocks.CipherFromString(server.Cipher)\n\t\tif account.CipherType == shadowsocks.CipherType_UNKNOWN {\n\t\t\treturn nil, newError(\"unknown cipher method: \", server.Cipher)\n\t\t}\n\n\t\taccount.IvCheck = server.IVCheck\n\n\t\tss := &protocol.ServerEndpoint{\n\t\t\tAddress: server.Address.Build(),\n\t\t\tPort:    uint32(server.Port),\n\t\t\tUser: []*protocol.User{\n\t\t\t\t{\n\t\t\t\t\tLevel:   uint32(server.Level),\n\t\t\t\t\tEmail:   server.Email,\n\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tserverSpecs[idx] = ss\n\t}\n\n\tconfig.Server = serverSpecs\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/shadowsocks_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n)\n\nfunc TestShadowsocksServerConfigParsing(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.ShadowsocksServerConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"method\": \"aes-256-GCM\",\n\t\t\t\t\"password\": \"v2ray-password\"\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &shadowsocks.ServerConfig{\n\t\t\t\tUser: &protocol.User{\n\t\t\t\t\tAccount: serial.ToTypedMessage(&shadowsocks.Account{\n\t\t\t\t\t\tCipherType: shadowsocks.CipherType_AES_256_GCM,\n\t\t\t\t\t\tPassword:   \"v2ray-password\",\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/socks.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n)\n\ntype SocksAccount struct {\n\tUsername string `json:\"user\"`\n\tPassword string `json:\"pass\"`\n}\n\nfunc (v *SocksAccount) Build() *socks.Account {\n\treturn &socks.Account{\n\t\tUsername: v.Username,\n\t\tPassword: v.Password,\n\t}\n}\n\nconst (\n\tAuthMethodNoAuth   = \"noauth\"\n\tAuthMethodUserPass = \"password\"\n)\n\ntype SocksServerConfig struct {\n\tAuthMethod     string             `json:\"auth\"`\n\tAccounts       []*SocksAccount    `json:\"accounts\"`\n\tUDP            bool               `json:\"udp\"`\n\tHost           *cfgcommon.Address `json:\"ip\"`\n\tTimeout        uint32             `json:\"timeout\"`\n\tUserLevel      uint32             `json:\"userLevel\"`\n\tPacketEncoding string             `json:\"packetEncoding\"`\n}\n\nfunc (v *SocksServerConfig) Build() (proto.Message, error) {\n\tconfig := new(socks.ServerConfig)\n\tswitch v.AuthMethod {\n\tcase AuthMethodNoAuth:\n\t\tconfig.AuthType = socks.AuthType_NO_AUTH\n\tcase AuthMethodUserPass:\n\t\tconfig.AuthType = socks.AuthType_PASSWORD\n\tdefault:\n\t\t// newError(\"unknown socks auth method: \", v.AuthMethod, \". Default to noauth.\").AtWarning().WriteToLog()\n\t\tconfig.AuthType = socks.AuthType_NO_AUTH\n\t}\n\n\tif len(v.Accounts) > 0 {\n\t\tconfig.Accounts = make(map[string]string, len(v.Accounts))\n\t\tfor _, account := range v.Accounts {\n\t\t\tconfig.Accounts[account.Username] = account.Password\n\t\t}\n\t}\n\n\tconfig.UdpEnabled = v.UDP\n\tif v.Host != nil {\n\t\tconfig.Address = v.Host.Build()\n\t}\n\n\tconfig.Timeout = v.Timeout\n\tconfig.UserLevel = v.UserLevel\n\n\tswitch v.PacketEncoding {\n\tcase \"Packet\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_Packet\n\tcase \"\", \"None\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_None\n\t}\n\n\treturn config, nil\n}\n\ntype SocksRemoteConfig struct {\n\tAddress *cfgcommon.Address `json:\"address\"`\n\tPort    uint16             `json:\"port\"`\n\tUsers   []json.RawMessage  `json:\"users\"`\n}\n\ntype SocksClientConfig struct {\n\tServers []*SocksRemoteConfig `json:\"servers\"`\n\tVersion string               `json:\"version\"`\n}\n\nfunc (v *SocksClientConfig) Build() (proto.Message, error) {\n\tconfig := new(socks.ClientConfig)\n\tconfig.Server = make([]*protocol.ServerEndpoint, len(v.Servers))\n\tswitch strings.ToLower(v.Version) {\n\tcase \"4\":\n\t\tconfig.Version = socks.Version_SOCKS4\n\tcase \"4a\":\n\t\tconfig.Version = socks.Version_SOCKS4A\n\tcase \"\", \"5\":\n\t\tconfig.Version = socks.Version_SOCKS5\n\tdefault:\n\t\treturn nil, newError(\"failed to parse socks server version: \", v.Version).AtError()\n\t}\n\tfor idx, serverConfig := range v.Servers {\n\t\tserver := &protocol.ServerEndpoint{\n\t\t\tAddress: serverConfig.Address.Build(),\n\t\t\tPort:    uint32(serverConfig.Port),\n\t\t}\n\t\tfor _, rawUser := range serverConfig.Users {\n\t\t\tuser := new(protocol.User)\n\t\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse Socks user\").Base(err).AtError()\n\t\t\t}\n\t\t\taccount := new(SocksAccount)\n\t\t\tif err := json.Unmarshal(rawUser, account); err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse socks account\").Base(err).AtError()\n\t\t\t}\n\t\t\tif config.Version != socks.Version_SOCKS5 && account.Password != \"\" {\n\t\t\t\treturn nil, newError(\"password is only supported in socks5\").AtError()\n\t\t\t}\n\t\t\tuser.Account = serial.ToTypedMessage(account.Build())\n\t\t\tserver.User = append(server.User, user)\n\t\t}\n\t\tconfig.Server[idx] = server\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/socks_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n)\n\nfunc TestSocksInboundConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.SocksServerConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"auth\": \"password\",\n\t\t\t\t\"accounts\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"user\": \"my-username\",\n\t\t\t\t\t\t\"pass\": \"my-password\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"udp\": false,\n\t\t\t\t\"ip\": \"127.0.0.1\",\n\t\t\t\t\"timeout\": 5,\n\t\t\t\t\"userLevel\": 1,\n\t\t\t\t\"packetEncoding\": \"Packet\"\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &socks.ServerConfig{\n\t\t\t\tAuthType: socks.AuthType_PASSWORD,\n\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\"my-username\": \"my-password\",\n\t\t\t\t},\n\t\t\t\tUdpEnabled: false,\n\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tTimeout:        5,\n\t\t\t\tUserLevel:      1,\n\t\t\t\tPacketEncoding: packetaddr.PacketAddrType_Packet,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestSocksOutboundConfig(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.SocksClientConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"servers\": [{\n\t\t\t\t\t\"address\": \"127.0.0.1\",\n\t\t\t\t\t\"port\": 1234,\n\t\t\t\t\t\"users\": [\n\t\t\t\t\t\t{\"user\": \"test user\", \"pass\": \"test pass\", \"email\": \"test@email.com\"}\n\t\t\t\t\t]\n\t\t\t\t}]\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &socks.ClientConfig{\n\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 1234,\n\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tEmail: \"test@email.com\",\n\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&socks.Account{\n\t\t\t\t\t\t\t\t\tUsername: \"test user\",\n\t\t\t\t\t\t\t\t\tPassword: \"test pass\",\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"
  },
  {
    "path": "infra/conf/v4/transport.go",
    "content": "package v4\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype TransportConfig struct {\n\tTCPConfig  *TCPConfig          `json:\"tcpSettings\"`\n\tKCPConfig  *KCPConfig          `json:\"kcpSettings\"`\n\tWSConfig   *WebSocketConfig    `json:\"wsSettings\"`\n\tHTTPConfig *HTTPConfig         `json:\"httpSettings\"`\n\tDSConfig   *DomainSocketConfig `json:\"dsSettings\"`\n\tQUICConfig *QUICConfig         `json:\"quicSettings\"`\n\tGunConfig  *GunConfig          `json:\"gunSettings\"`\n\tGRPCConfig *GunConfig          `json:\"grpcSettings\"`\n}\n\n// Build implements Buildable.\nfunc (c *TransportConfig) Build() (*transport.Config, error) {\n\tconfig := new(transport.Config)\n\n\tif c.TCPConfig != nil {\n\t\tts, err := c.TCPConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build TCP config\").Base(err).AtError()\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"tcp\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\n\tif c.KCPConfig != nil {\n\t\tts, err := c.KCPConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build mKCP config\").Base(err).AtError()\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"mkcp\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\n\tif c.WSConfig != nil {\n\t\tts, err := c.WSConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build WebSocket config\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"websocket\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\n\tif c.HTTPConfig != nil {\n\t\tts, err := c.HTTPConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build HTTP config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"http\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\n\tif c.DSConfig != nil {\n\t\tds, err := c.DSConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build DomainSocket config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"domainsocket\",\n\t\t\tSettings:     serial.ToTypedMessage(ds),\n\t\t})\n\t}\n\n\tif c.QUICConfig != nil {\n\t\tqs, err := c.QUICConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build QUIC config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"quic\",\n\t\t\tSettings:     serial.ToTypedMessage(qs),\n\t\t})\n\t}\n\n\tif c.GunConfig == nil {\n\t\tc.GunConfig = c.GRPCConfig\n\t}\n\tif c.GunConfig != nil {\n\t\tgs, err := c.GunConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build Gun config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"gun\",\n\t\t\tSettings:     serial.ToTypedMessage(gs),\n\t\t})\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/transport_authenticators.go",
    "content": "package v4\n\nimport (\n\t\"sort\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/srtp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/utp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wireguard\"\n)\n\ntype NoOpAuthenticator struct{}\n\nfunc (NoOpAuthenticator) Build() (proto.Message, error) {\n\treturn new(noop.Config), nil\n}\n\ntype NoOpConnectionAuthenticator struct{}\n\nfunc (NoOpConnectionAuthenticator) Build() (proto.Message, error) {\n\treturn new(noop.ConnectionConfig), nil\n}\n\ntype SRTPAuthenticator struct{}\n\nfunc (SRTPAuthenticator) Build() (proto.Message, error) {\n\treturn new(srtp.Config), nil\n}\n\ntype UTPAuthenticator struct{}\n\nfunc (UTPAuthenticator) Build() (proto.Message, error) {\n\treturn new(utp.Config), nil\n}\n\ntype WechatVideoAuthenticator struct{}\n\nfunc (WechatVideoAuthenticator) Build() (proto.Message, error) {\n\treturn new(wechat.VideoConfig), nil\n}\n\ntype WireguardAuthenticator struct{}\n\nfunc (WireguardAuthenticator) Build() (proto.Message, error) {\n\treturn new(wireguard.WireguardConfig), nil\n}\n\ntype DTLSAuthenticator struct{}\n\nfunc (DTLSAuthenticator) Build() (proto.Message, error) {\n\treturn new(tls.PacketConfig), nil\n}\n\ntype AuthenticatorRequest struct {\n\tVersion string                           `json:\"version\"`\n\tMethod  string                           `json:\"method\"`\n\tPath    cfgcommon.StringList             `json:\"path\"`\n\tHeaders map[string]*cfgcommon.StringList `json:\"headers\"`\n}\n\nfunc sortMapKeys(m map[string]*cfgcommon.StringList) []string {\n\tvar keys []string\n\tfor key := range m {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\treturn keys\n}\n\nfunc (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) {\n\tconfig := &http.RequestConfig{\n\t\tUri: []string{\"/\"},\n\t\tHeader: []*http.Header{\n\t\t\t{\n\t\t\t\tName:  \"Host\",\n\t\t\t\tValue: []string{\"www.baidu.com\", \"www.bing.com\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName: \"User-Agent\",\n\t\t\t\tValue: []string{\n\t\t\t\t\t\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\",\n\t\t\t\t\t\"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Accept-Encoding\",\n\t\t\t\tValue: []string{\"gzip, deflate\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Connection\",\n\t\t\t\tValue: []string{\"keep-alive\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Pragma\",\n\t\t\t\tValue: []string{\"no-cache\"},\n\t\t\t},\n\t\t},\n\t}\n\n\tif len(v.Version) > 0 {\n\t\tconfig.Version = &http.Version{Value: v.Version}\n\t}\n\n\tif len(v.Method) > 0 {\n\t\tconfig.Method = &http.Method{Value: v.Method}\n\t}\n\n\tif len(v.Path) > 0 {\n\t\tconfig.Uri = append([]string(nil), (v.Path)...)\n\t}\n\n\tif len(v.Headers) > 0 {\n\t\tconfig.Header = make([]*http.Header, 0, len(v.Headers))\n\t\theaderNames := sortMapKeys(v.Headers)\n\t\tfor _, key := range headerNames {\n\t\t\tvalue := v.Headers[key]\n\t\t\tif value == nil {\n\t\t\t\treturn nil, newError(\"empty HTTP header value: \" + key).AtError()\n\t\t\t}\n\t\t\tconfig.Header = append(config.Header, &http.Header{\n\t\t\t\tName:  key,\n\t\t\t\tValue: append([]string(nil), (*value)...),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn config, nil\n}\n\ntype AuthenticatorResponse struct {\n\tVersion string                           `json:\"version\"`\n\tStatus  string                           `json:\"status\"`\n\tReason  string                           `json:\"reason\"`\n\tHeaders map[string]*cfgcommon.StringList `json:\"headers\"`\n}\n\nfunc (v *AuthenticatorResponse) Build() (*http.ResponseConfig, error) {\n\tconfig := &http.ResponseConfig{\n\t\tHeader: []*http.Header{\n\t\t\t{\n\t\t\t\tName:  \"Content-Type\",\n\t\t\t\tValue: []string{\"application/octet-stream\", \"video/mpeg\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Transfer-Encoding\",\n\t\t\t\tValue: []string{\"chunked\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Connection\",\n\t\t\t\tValue: []string{\"keep-alive\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Pragma\",\n\t\t\t\tValue: []string{\"no-cache\"},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"Cache-Control\",\n\t\t\t\tValue: []string{\"private\", \"no-cache\"},\n\t\t\t},\n\t\t},\n\t}\n\n\tif len(v.Version) > 0 {\n\t\tconfig.Version = &http.Version{Value: v.Version}\n\t}\n\n\tif len(v.Status) > 0 || len(v.Reason) > 0 {\n\t\tconfig.Status = &http.Status{\n\t\t\tCode:   \"200\",\n\t\t\tReason: \"OK\",\n\t\t}\n\t\tif len(v.Status) > 0 {\n\t\t\tconfig.Status.Code = v.Status\n\t\t}\n\t\tif len(v.Reason) > 0 {\n\t\t\tconfig.Status.Reason = v.Reason\n\t\t}\n\t}\n\n\tif len(v.Headers) > 0 {\n\t\tconfig.Header = make([]*http.Header, 0, len(v.Headers))\n\t\theaderNames := sortMapKeys(v.Headers)\n\t\tfor _, key := range headerNames {\n\t\t\tvalue := v.Headers[key]\n\t\t\tif value == nil {\n\t\t\t\treturn nil, newError(\"empty HTTP header value: \" + key).AtError()\n\t\t\t}\n\t\t\tconfig.Header = append(config.Header, &http.Header{\n\t\t\t\tName:  key,\n\t\t\t\tValue: append([]string(nil), (*value)...),\n\t\t\t})\n\t\t}\n\t}\n\n\treturn config, nil\n}\n\ntype Authenticator struct {\n\tRequest  AuthenticatorRequest  `json:\"request\"`\n\tResponse AuthenticatorResponse `json:\"response\"`\n}\n\nfunc (v *Authenticator) Build() (proto.Message, error) {\n\tconfig := new(http.Config)\n\trequestConfig, err := v.Request.Build()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconfig.Request = requestConfig\n\n\tresponseConfig, err := v.Response.Build()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconfig.Response = responseConfig\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/transport_internet.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/loader\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/socketcfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/tlscfg\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket\"\n\thttpheader \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/quic\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\"\n)\n\nvar (\n\tkcpHeaderLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{\n\t\t\"none\":         func() interface{} { return new(NoOpAuthenticator) },\n\t\t\"srtp\":         func() interface{} { return new(SRTPAuthenticator) },\n\t\t\"utp\":          func() interface{} { return new(UTPAuthenticator) },\n\t\t\"wechat-video\": func() interface{} { return new(WechatVideoAuthenticator) },\n\t\t\"dtls\":         func() interface{} { return new(DTLSAuthenticator) },\n\t\t\"wireguard\":    func() interface{} { return new(WireguardAuthenticator) },\n\t}, \"type\", \"\")\n\n\ttcpHeaderLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{\n\t\t\"none\": func() interface{} { return new(NoOpConnectionAuthenticator) },\n\t\t\"http\": func() interface{} { return new(Authenticator) },\n\t}, \"type\", \"\")\n)\n\ntype KCPConfig struct {\n\tMtu             *uint32         `json:\"mtu\"`\n\tTti             *uint32         `json:\"tti\"`\n\tUpCap           *uint32         `json:\"uplinkCapacity\"`\n\tDownCap         *uint32         `json:\"downlinkCapacity\"`\n\tCongestion      *bool           `json:\"congestion\"`\n\tReadBufferSize  *uint32         `json:\"readBufferSize\"`\n\tWriteBufferSize *uint32         `json:\"writeBufferSize\"`\n\tHeaderConfig    json.RawMessage `json:\"header\"`\n\tSeed            *string         `json:\"seed\"`\n}\n\n// Build implements Buildable.\nfunc (c *KCPConfig) Build() (proto.Message, error) {\n\tconfig := new(kcp.Config)\n\n\tif c.Mtu != nil {\n\t\tmtu := *c.Mtu\n\t\tif mtu < 576 || mtu > 1460 {\n\t\t\treturn nil, newError(\"invalid mKCP MTU size: \", mtu).AtError()\n\t\t}\n\t\tconfig.Mtu = &kcp.MTU{Value: mtu}\n\t}\n\tif c.Tti != nil {\n\t\ttti := *c.Tti\n\t\tif tti < 10 || tti > 100 {\n\t\t\treturn nil, newError(\"invalid mKCP TTI: \", tti).AtError()\n\t\t}\n\t\tconfig.Tti = &kcp.TTI{Value: tti}\n\t}\n\tif c.UpCap != nil {\n\t\tconfig.UplinkCapacity = &kcp.UplinkCapacity{Value: *c.UpCap}\n\t}\n\tif c.DownCap != nil {\n\t\tconfig.DownlinkCapacity = &kcp.DownlinkCapacity{Value: *c.DownCap}\n\t}\n\tif c.Congestion != nil {\n\t\tconfig.Congestion = *c.Congestion\n\t}\n\tif c.ReadBufferSize != nil {\n\t\tsize := *c.ReadBufferSize\n\t\tif size > 0 {\n\t\t\tconfig.ReadBuffer = &kcp.ReadBuffer{Size: size * 1024 * 1024}\n\t\t} else {\n\t\t\tconfig.ReadBuffer = &kcp.ReadBuffer{Size: 512 * 1024}\n\t\t}\n\t}\n\tif c.WriteBufferSize != nil {\n\t\tsize := *c.WriteBufferSize\n\t\tif size > 0 {\n\t\t\tconfig.WriteBuffer = &kcp.WriteBuffer{Size: size * 1024 * 1024}\n\t\t} else {\n\t\t\tconfig.WriteBuffer = &kcp.WriteBuffer{Size: 512 * 1024}\n\t\t}\n\t}\n\tif len(c.HeaderConfig) > 0 {\n\t\theaderConfig, _, err := kcpHeaderLoader.Load(c.HeaderConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid mKCP header config.\").Base(err).AtError()\n\t\t}\n\t\tts, err := headerConfig.(cfgcommon.Buildable).Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid mKCP header config\").Base(err).AtError()\n\t\t}\n\t\tconfig.HeaderConfig = serial.ToTypedMessage(ts)\n\t}\n\n\tif c.Seed != nil {\n\t\tconfig.Seed = &kcp.EncryptionSeed{Seed: *c.Seed}\n\t}\n\n\treturn config, nil\n}\n\ntype TCPConfig struct {\n\tHeaderConfig        json.RawMessage `json:\"header\"`\n\tAcceptProxyProtocol bool            `json:\"acceptProxyProtocol\"`\n}\n\n// Build implements Buildable.\nfunc (c *TCPConfig) Build() (proto.Message, error) {\n\tconfig := new(tcp.Config)\n\tif len(c.HeaderConfig) > 0 {\n\t\theaderConfig, _, err := tcpHeaderLoader.Load(c.HeaderConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid TCP header config\").Base(err).AtError()\n\t\t}\n\t\tts, err := headerConfig.(cfgcommon.Buildable).Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid TCP header config\").Base(err).AtError()\n\t\t}\n\t\tconfig.HeaderSettings = serial.ToTypedMessage(ts)\n\t}\n\tif c.AcceptProxyProtocol {\n\t\tconfig.AcceptProxyProtocol = c.AcceptProxyProtocol\n\t}\n\treturn config, nil\n}\n\ntype Hy2ConfigCongestion struct {\n\tType     string `json:\"type\"`\n\tUpMbps   uint64 `json:\"up_mbps\"`\n\tDownMbps uint64 `json:\"down_mbps\"`\n}\n\ntype Hy2Config struct {\n\tPassword              string              `json:\"password\"`\n\tCongestion            Hy2ConfigCongestion `json:\"congestion\"`\n\tUseUDPExtension       bool                `json:\"use_udp_extension\"`\n\tIgnoreClientBandwidth bool                `json:\"ignore_client_bandwidth\"`\n}\n\n// Build implements Buildable.\nfunc (c *Hy2Config) Build() (proto.Message, error) {\n\treturn &hysteria2.Config{\n\t\tPassword: c.Password,\n\t\tCongestion: &hysteria2.Congestion{\n\t\t\tType:     c.Congestion.Type,\n\t\t\tDownMbps: c.Congestion.DownMbps,\n\t\t\tUpMbps:   c.Congestion.UpMbps,\n\t\t},\n\t\tUseUdpExtension:       c.UseUDPExtension,\n\t\tIgnoreClientBandwidth: c.IgnoreClientBandwidth,\n\t}, nil\n}\n\ntype WebSocketConfig struct {\n\tPath                 string            `json:\"path\"`\n\tHeaders              map[string]string `json:\"headers\"`\n\tAcceptProxyProtocol  bool              `json:\"acceptProxyProtocol\"`\n\tMaxEarlyData         int32             `json:\"maxEarlyData\"`\n\tUseBrowserForwarding bool              `json:\"useBrowserForwarding\"`\n\tEarlyDataHeaderName  string            `json:\"earlyDataHeaderName\"`\n}\n\n// Build implements Buildable.\nfunc (c *WebSocketConfig) Build() (proto.Message, error) {\n\tpath := c.Path\n\theader := make([]*websocket.Header, 0, 32)\n\tfor key, value := range c.Headers {\n\t\theader = append(header, &websocket.Header{\n\t\t\tKey:   key,\n\t\t\tValue: value,\n\t\t})\n\t}\n\tconfig := &websocket.Config{\n\t\tPath:                 path,\n\t\tHeader:               header,\n\t\tMaxEarlyData:         c.MaxEarlyData,\n\t\tUseBrowserForwarding: c.UseBrowserForwarding,\n\t\tEarlyDataHeaderName:  c.EarlyDataHeaderName,\n\t}\n\tif c.AcceptProxyProtocol {\n\t\tconfig.AcceptProxyProtocol = c.AcceptProxyProtocol\n\t}\n\treturn config, nil\n}\n\ntype HTTPConfig struct {\n\tHost    *cfgcommon.StringList            `json:\"host\"`\n\tPath    string                           `json:\"path\"`\n\tMethod  string                           `json:\"method\"`\n\tHeaders map[string]*cfgcommon.StringList `json:\"headers\"`\n}\n\n// Build implements Buildable.\nfunc (c *HTTPConfig) Build() (proto.Message, error) {\n\tconfig := &http.Config{\n\t\tPath: c.Path,\n\t}\n\tif c.Host != nil {\n\t\tconfig.Host = []string(*c.Host)\n\t}\n\tif c.Method != \"\" {\n\t\tconfig.Method = c.Method\n\t}\n\tif len(c.Headers) > 0 {\n\t\tconfig.Header = make([]*httpheader.Header, 0, len(c.Headers))\n\t\theaderNames := sortMapKeys(c.Headers)\n\t\tfor _, key := range headerNames {\n\t\t\tvalue := c.Headers[key]\n\t\t\tif value == nil {\n\t\t\t\treturn nil, newError(\"empty HTTP header value: \" + key).AtError()\n\t\t\t}\n\t\t\tconfig.Header = append(config.Header, &httpheader.Header{\n\t\t\t\tName:  key,\n\t\t\t\tValue: append([]string(nil), (*value)...),\n\t\t\t})\n\t\t}\n\t}\n\treturn config, nil\n}\n\ntype QUICConfig struct {\n\tHeader   json.RawMessage `json:\"header\"`\n\tSecurity string          `json:\"security\"`\n\tKey      string          `json:\"key\"`\n}\n\n// Build implements Buildable.\nfunc (c *QUICConfig) Build() (proto.Message, error) {\n\tconfig := &quic.Config{\n\t\tKey: c.Key,\n\t}\n\n\tif len(c.Header) > 0 {\n\t\theaderConfig, _, err := kcpHeaderLoader.Load(c.Header)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid QUIC header config.\").Base(err).AtError()\n\t\t}\n\t\tts, err := headerConfig.(cfgcommon.Buildable).Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid QUIC header config\").Base(err).AtError()\n\t\t}\n\t\tconfig.Header = serial.ToTypedMessage(ts)\n\t}\n\n\tvar st protocol.SecurityType\n\tswitch strings.ToLower(c.Security) {\n\tcase \"aes-128-gcm\":\n\t\tst = protocol.SecurityType_AES128_GCM\n\tcase \"chacha20-poly1305\":\n\t\tst = protocol.SecurityType_CHACHA20_POLY1305\n\tdefault:\n\t\tst = protocol.SecurityType_NONE\n\t}\n\n\tconfig.Security = &protocol.SecurityConfig{\n\t\tType: st,\n\t}\n\n\treturn config, nil\n}\n\ntype DomainSocketConfig struct {\n\tPath     string `json:\"path\"`\n\tAbstract bool   `json:\"abstract\"`\n\tPadding  bool   `json:\"padding\"`\n}\n\n// Build implements Buildable.\nfunc (c *DomainSocketConfig) Build() (proto.Message, error) {\n\treturn &domainsocket.Config{\n\t\tPath:     c.Path,\n\t\tAbstract: c.Abstract,\n\t\tPadding:  c.Padding,\n\t}, nil\n}\n\ntype TransportProtocol string\n\n// Build implements Buildable.\nfunc (p TransportProtocol) Build() (string, error) {\n\tswitch strings.ToLower(string(p)) {\n\tcase \"tcp\":\n\t\treturn \"tcp\", nil\n\tcase \"kcp\", \"mkcp\":\n\t\treturn \"mkcp\", nil\n\tcase \"ws\", \"websocket\":\n\t\treturn \"websocket\", nil\n\tcase \"h2\", \"http\":\n\t\treturn \"http\", nil\n\tcase \"ds\", \"domainsocket\":\n\t\treturn \"domainsocket\", nil\n\tcase \"quic\":\n\t\treturn \"quic\", nil\n\tcase \"gun\", \"grpc\":\n\t\treturn \"gun\", nil\n\tcase \"hy2\", \"hysteria2\":\n\t\treturn \"hysteria2\", nil\n\tdefault:\n\t\treturn \"\", newError(\"Config: unknown transport protocol: \", p)\n\t}\n}\n\ntype StreamConfig struct {\n\tNetwork        *TransportProtocol      `json:\"network\"`\n\tSecurity       string                  `json:\"security\"`\n\tTLSSettings    *tlscfg.TLSConfig       `json:\"tlsSettings\"`\n\tTCPSettings    *TCPConfig              `json:\"tcpSettings\"`\n\tKCPSettings    *KCPConfig              `json:\"kcpSettings\"`\n\tWSSettings     *WebSocketConfig        `json:\"wsSettings\"`\n\tHTTPSettings   *HTTPConfig             `json:\"httpSettings\"`\n\tDSSettings     *DomainSocketConfig     `json:\"dsSettings\"`\n\tQUICSettings   *QUICConfig             `json:\"quicSettings\"`\n\tGunSettings    *GunConfig              `json:\"gunSettings\"`\n\tGRPCSettings   *GunConfig              `json:\"grpcSettings\"`\n\tHy2Settings    *Hy2Config              `json:\"hy2Settings\"`\n\tSocketSettings *socketcfg.SocketConfig `json:\"sockopt\"`\n}\n\n// Build implements Buildable.\nfunc (c *StreamConfig) Build() (*internet.StreamConfig, error) {\n\tconfig := &internet.StreamConfig{\n\t\tProtocolName: \"tcp\",\n\t}\n\tif c.Network != nil {\n\t\tprotocol, err := c.Network.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.ProtocolName = protocol\n\t}\n\tif strings.EqualFold(c.Security, \"tls\") {\n\t\ttlsSettings := c.TLSSettings\n\t\tif tlsSettings == nil {\n\t\t\ttlsSettings = &tlscfg.TLSConfig{}\n\t\t}\n\t\tts, err := tlsSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build TLS config.\").Base(err)\n\t\t}\n\t\ttm := serial.ToTypedMessage(ts)\n\t\tconfig.SecuritySettings = append(config.SecuritySettings, tm)\n\t\tconfig.SecurityType = serial.V2Type(tm)\n\t}\n\tif c.TCPSettings != nil {\n\t\tts, err := c.TCPSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build TCP config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"tcp\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\tif c.KCPSettings != nil {\n\t\tts, err := c.KCPSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build mKCP config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"mkcp\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\tif c.WSSettings != nil {\n\t\tts, err := c.WSSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build WebSocket config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"websocket\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\tif c.HTTPSettings != nil {\n\t\tts, err := c.HTTPSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build HTTP config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"http\",\n\t\t\tSettings:     serial.ToTypedMessage(ts),\n\t\t})\n\t}\n\tif c.DSSettings != nil {\n\t\tds, err := c.DSSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build DomainSocket config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"domainsocket\",\n\t\t\tSettings:     serial.ToTypedMessage(ds),\n\t\t})\n\t}\n\tif c.QUICSettings != nil {\n\t\tqs, err := c.QUICSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build QUIC config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"quic\",\n\t\t\tSettings:     serial.ToTypedMessage(qs),\n\t\t})\n\t}\n\tif c.GunSettings == nil {\n\t\tc.GunSettings = c.GRPCSettings\n\t}\n\tif c.GunSettings != nil {\n\t\tgs, err := c.GunSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build Gun config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"gun\",\n\t\t\tSettings:     serial.ToTypedMessage(gs),\n\t\t})\n\t}\n\tif c.Hy2Settings != nil {\n\t\thy2, err := c.Hy2Settings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build hy2 config.\").Base(err)\n\t\t}\n\t\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\t\tProtocolName: \"hysteria2\",\n\t\t\tSettings:     serial.ToTypedMessage(hy2),\n\t\t})\n\t}\n\tif c.SocketSettings != nil {\n\t\tss, err := c.SocketSettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"Failed to build sockopt.\").Base(err)\n\t\t}\n\t\tconfig.SocketSettings = ss\n\t}\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/transport_test.go",
    "content": "package v4_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/socketcfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/quic\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\"\n)\n\nfunc TestSocketConfig(t *testing.T) {\n\tcreateParser := func() func(string) (proto.Message, error) {\n\t\treturn func(s string) (proto.Message, error) {\n\t\t\tconfig := new(socketcfg.SocketConfig)\n\t\t\tif err := json.Unmarshal([]byte(s), config); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn config.Build()\n\t\t}\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"mark\": 1,\n\t\t\t\t\"tcpFastOpen\": true,\n\t\t\t\t\"tcpFastOpenQueueLength\": 1024,\n\t\t\t\t\"mptcp\": true\n\t\t\t}`,\n\t\t\tParser: createParser(),\n\t\t\tOutput: &internet.SocketConfig{\n\t\t\t\tMark:           1,\n\t\t\t\tTfo:            internet.SocketConfig_Enable,\n\t\t\t\tTfoQueueLength: 1024,\n\t\t\t\tMptcp:          internet.MPTCPState_Enable,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTransportConfig(t *testing.T) {\n\tcreateParser := func() func(string) (proto.Message, error) {\n\t\treturn func(s string) (proto.Message, error) {\n\t\t\tconfig := new(v4.TransportConfig)\n\t\t\tif err := json.Unmarshal([]byte(s), config); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn config.Build()\n\t\t}\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"tcpSettings\": {\n\t\t\t\t\t\"header\": {\n\t\t\t\t\t\t\"type\": \"http\",\n\t\t\t\t\t\t\"request\": {\n\t\t\t\t\t\t\t\"version\": \"1.1\",\n\t\t\t\t\t\t\t\"method\": \"GET\",\n\t\t\t\t\t\t\t\"path\": \"/b\",\n\t\t\t\t\t\t\t\"headers\": {\n\t\t\t\t\t\t\t\t\"a\": \"b\",\n\t\t\t\t\t\t\t\t\"c\": \"d\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"response\": {\n\t\t\t\t\t\t\t\"version\": \"1.0\",\n\t\t\t\t\t\t\t\"status\": \"404\",\n\t\t\t\t\t\t\t\"reason\": \"Not Found\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"kcpSettings\": {\n\t\t\t\t\t\"mtu\": 1200,\n\t\t\t\t\t\"header\": {\n\t\t\t\t\t\t\"type\": \"none\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"wsSettings\": {\n\t\t\t\t\t\"path\": \"/t\"\n\t\t\t\t},\n\t\t\t\t\"quicSettings\": {\n\t\t\t\t\t\"key\": \"abcd\",\n\t\t\t\t\t\"header\": {\n\t\t\t\t\t\t\"type\": \"dtls\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t\tParser: createParser(),\n\t\t\tOutput: &transport.Config{\n\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tProtocolName: \"tcp\",\n\t\t\t\t\t\tSettings: serial.ToTypedMessage(&tcp.Config{\n\t\t\t\t\t\t\tHeaderSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\tRequest: &http.RequestConfig{\n\t\t\t\t\t\t\t\t\tVersion: &http.Version{Value: \"1.1\"},\n\t\t\t\t\t\t\t\t\tMethod:  &http.Method{Value: \"GET\"},\n\t\t\t\t\t\t\t\t\tUri:     []string{\"/b\"},\n\t\t\t\t\t\t\t\t\tHeader: []*http.Header{\n\t\t\t\t\t\t\t\t\t\t{Name: \"a\", Value: []string{\"b\"}},\n\t\t\t\t\t\t\t\t\t\t{Name: \"c\", Value: []string{\"d\"}},\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\tResponse: &http.ResponseConfig{\n\t\t\t\t\t\t\t\t\tVersion: &http.Version{Value: \"1.0\"},\n\t\t\t\t\t\t\t\t\tStatus:  &http.Status{Code: \"404\", Reason: \"Not Found\"},\n\t\t\t\t\t\t\t\t\tHeader: []*http.Header{\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tName:  \"Content-Type\",\n\t\t\t\t\t\t\t\t\t\t\tValue: []string{\"application/octet-stream\", \"video/mpeg\"},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tName:  \"Transfer-Encoding\",\n\t\t\t\t\t\t\t\t\t\t\tValue: []string{\"chunked\"},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tName:  \"Connection\",\n\t\t\t\t\t\t\t\t\t\t\tValue: []string{\"keep-alive\"},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tName:  \"Pragma\",\n\t\t\t\t\t\t\t\t\t\t\tValue: []string{\"no-cache\"},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tName:  \"Cache-Control\",\n\t\t\t\t\t\t\t\t\t\t\tValue: []string{\"private\", \"no-cache\"},\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\t{\n\t\t\t\t\t\tProtocolName: \"mkcp\",\n\t\t\t\t\t\tSettings: serial.ToTypedMessage(&kcp.Config{\n\t\t\t\t\t\t\tMtu:          &kcp.MTU{Value: 1200},\n\t\t\t\t\t\t\tHeaderConfig: serial.ToTypedMessage(&noop.Config{}),\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\tProtocolName: \"websocket\",\n\t\t\t\t\t\tSettings: serial.ToTypedMessage(&websocket.Config{\n\t\t\t\t\t\t\tPath: \"/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\tProtocolName: \"quic\",\n\t\t\t\t\t\tSettings: serial.ToTypedMessage(&quic.Config{\n\t\t\t\t\t\t\tKey: \"abcd\",\n\t\t\t\t\t\t\tSecurity: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\tType: protocol.SecurityType_NONE,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tHeader: serial.ToTypedMessage(&tls.PacketConfig{}),\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"
  },
  {
    "path": "infra/conf/v4/trojan.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/trojan\"\n)\n\n// TrojanServerTarget is configuration of a single trojan server\ntype TrojanServerTarget struct {\n\tAddress  *cfgcommon.Address `json:\"address\"`\n\tPort     uint16             `json:\"port\"`\n\tPassword string             `json:\"password\"`\n\tEmail    string             `json:\"email\"`\n\tLevel    byte               `json:\"level\"`\n}\n\n// TrojanClientConfig is configuration of trojan servers\ntype TrojanClientConfig struct {\n\tServers []*TrojanServerTarget `json:\"servers\"`\n}\n\n// Build implements Buildable\nfunc (c *TrojanClientConfig) Build() (proto.Message, error) {\n\tconfig := new(trojan.ClientConfig)\n\n\tif len(c.Servers) == 0 {\n\t\treturn nil, newError(\"0 Trojan server configured.\")\n\t}\n\n\tserverSpecs := make([]*protocol.ServerEndpoint, len(c.Servers))\n\tfor idx, rec := range c.Servers {\n\t\tif rec.Address == nil {\n\t\t\treturn nil, newError(\"Trojan server address is not set.\")\n\t\t}\n\t\tif rec.Port == 0 {\n\t\t\treturn nil, newError(\"Invalid Trojan port.\")\n\t\t}\n\t\tif rec.Password == \"\" {\n\t\t\treturn nil, newError(\"Trojan password is not specified.\")\n\t\t}\n\t\taccount := &trojan.Account{\n\t\t\tPassword: rec.Password,\n\t\t}\n\t\ttrojan := &protocol.ServerEndpoint{\n\t\t\tAddress: rec.Address.Build(),\n\t\t\tPort:    uint32(rec.Port),\n\t\t\tUser: []*protocol.User{\n\t\t\t\t{\n\t\t\t\t\tLevel:   uint32(rec.Level),\n\t\t\t\t\tEmail:   rec.Email,\n\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tserverSpecs[idx] = trojan\n\t}\n\n\tconfig.Server = serverSpecs\n\n\treturn config, nil\n}\n\n// TrojanInboundFallback is fallback configuration\ntype TrojanInboundFallback struct {\n\tAlpn string          `json:\"alpn\"`\n\tPath string          `json:\"path\"`\n\tType string          `json:\"type\"`\n\tDest json.RawMessage `json:\"dest\"`\n\tXver uint64          `json:\"xver\"`\n}\n\n// TrojanUserConfig is user configuration\ntype TrojanUserConfig struct {\n\tPassword string `json:\"password\"`\n\tLevel    byte   `json:\"level\"`\n\tEmail    string `json:\"email\"`\n}\n\n// TrojanServerConfig is Inbound configuration\ntype TrojanServerConfig struct {\n\tClients        []*TrojanUserConfig      `json:\"clients\"`\n\tFallback       json.RawMessage          `json:\"fallback\"`\n\tFallbacks      []*TrojanInboundFallback `json:\"fallbacks\"`\n\tPacketEncoding string                   `json:\"packetEncoding\"`\n}\n\n// Build implements Buildable\nfunc (c *TrojanServerConfig) Build() (proto.Message, error) {\n\tconfig := new(trojan.ServerConfig)\n\tconfig.Users = make([]*protocol.User, len(c.Clients))\n\tfor idx, rawUser := range c.Clients {\n\t\tuser := new(protocol.User)\n\t\taccount := &trojan.Account{\n\t\t\tPassword: rawUser.Password,\n\t\t}\n\n\t\tuser.Email = rawUser.Email\n\t\tuser.Level = uint32(rawUser.Level)\n\t\tuser.Account = serial.ToTypedMessage(account)\n\t\tconfig.Users[idx] = user\n\t}\n\n\tif c.Fallback != nil {\n\t\treturn nil, newError(`Trojan settings: please use \"fallbacks\":[{}] instead of \"fallback\":{}`)\n\t}\n\tfor _, fb := range c.Fallbacks {\n\t\tvar i uint16\n\t\tvar s string\n\t\tif err := json.Unmarshal(fb.Dest, &i); err == nil {\n\t\t\ts = strconv.Itoa(int(i))\n\t\t} else {\n\t\t\t_ = json.Unmarshal(fb.Dest, &s)\n\t\t}\n\t\tconfig.Fallbacks = append(config.Fallbacks, &trojan.Fallback{\n\t\t\tAlpn: fb.Alpn,\n\t\t\tPath: fb.Path,\n\t\t\tType: fb.Type,\n\t\t\tDest: s,\n\t\t\tXver: fb.Xver,\n\t\t})\n\t}\n\tfor _, fb := range config.Fallbacks {\n\t\t/*\n\t\t\tif fb.Alpn == \"h2\" && fb.Path != \"\" {\n\t\t\t\treturn nil, newError(`Trojan fallbacks: \"alpn\":\"h2\" doesn't support \"path\"`)\n\t\t\t}\n\t\t*/\n\t\tif fb.Path != \"\" && fb.Path[0] != '/' {\n\t\t\treturn nil, newError(`Trojan fallbacks: \"path\" must be empty or start with \"/\"`)\n\t\t}\n\t\tif fb.Type == \"\" && fb.Dest != \"\" {\n\t\t\tif fb.Dest == \"serve-ws-none\" { // nolint:gocritic\n\t\t\t\tfb.Type = \"serve\"\n\t\t\t} else if filepath.IsAbs(fb.Dest) || fb.Dest[0] == '@' {\n\t\t\t\tfb.Type = \"unix\"\n\t\t\t\tif strings.HasPrefix(fb.Dest, \"@@\") && (runtime.GOOS == \"linux\" || runtime.GOOS == \"android\") {\n\t\t\t\t\tfullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy\n\t\t\t\t\tcopy(fullAddr, fb.Dest[1:])\n\t\t\t\t\tfb.Dest = string(fullAddr)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif _, err := strconv.Atoi(fb.Dest); err == nil {\n\t\t\t\t\tfb.Dest = \"127.0.0.1:\" + fb.Dest\n\t\t\t\t}\n\t\t\t\tif _, _, err := net.SplitHostPort(fb.Dest); err == nil {\n\t\t\t\t\tfb.Type = \"tcp\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif fb.Type == \"\" {\n\t\t\treturn nil, newError(`Trojan fallbacks: please fill in a valid value for every \"dest\"`)\n\t\t}\n\t\tif fb.Xver > 2 {\n\t\t\treturn nil, newError(`Trojan fallbacks: invalid PROXY protocol version, \"xver\" only accepts 0, 1, 2`)\n\t\t}\n\t}\n\n\tswitch c.PacketEncoding {\n\tcase \"Packet\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_Packet\n\tcase \"\", \"None\":\n\t\tconfig.PacketEncoding = packetaddr.PacketAddrType_None\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/v2ray.go",
    "content": "package v4\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/stats\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/loader\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/muxcfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/proxycfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/sniffer\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/log\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/router\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/v5cfg\"\n)\n\nvar (\n\tinboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{\n\t\t\"dokodemo-door\": func() interface{} { return new(DokodemoConfig) },\n\t\t\"http\":          func() interface{} { return new(HTTPServerConfig) },\n\t\t\"shadowsocks\":   func() interface{} { return new(ShadowsocksServerConfig) },\n\t\t\"socks\":         func() interface{} { return new(SocksServerConfig) },\n\t\t\"vless\":         func() interface{} { return new(VLessInboundConfig) },\n\t\t\"vmess\":         func() interface{} { return new(VMessInboundConfig) },\n\t\t\"trojan\":        func() interface{} { return new(TrojanServerConfig) },\n\t\t\"hysteria2\":     func() interface{} { return new(Hysteria2ServerConfig) },\n\t}, \"protocol\", \"settings\")\n\n\toutboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{\n\t\t\"blackhole\":   func() interface{} { return new(BlackholeConfig) },\n\t\t\"freedom\":     func() interface{} { return new(FreedomConfig) },\n\t\t\"http\":        func() interface{} { return new(HTTPClientConfig) },\n\t\t\"shadowsocks\": func() interface{} { return new(ShadowsocksClientConfig) },\n\t\t\"socks\":       func() interface{} { return new(SocksClientConfig) },\n\t\t\"vless\":       func() interface{} { return new(VLessOutboundConfig) },\n\t\t\"vmess\":       func() interface{} { return new(VMessOutboundConfig) },\n\t\t\"trojan\":      func() interface{} { return new(TrojanClientConfig) },\n\t\t\"hysteria2\":   func() interface{} { return new(Hysteria2ClientConfig) },\n\t\t\"dns\":         func() interface{} { return new(DNSOutboundConfig) },\n\t\t\"loopback\":    func() interface{} { return new(LoopbackConfig) },\n\t}, \"protocol\", \"settings\")\n)\n\nfunc toProtocolList(s []string) ([]proxyman.KnownProtocols, error) {\n\tkp := make([]proxyman.KnownProtocols, 0, 8)\n\tfor _, p := range s {\n\t\tswitch strings.ToLower(p) {\n\t\tcase \"http\":\n\t\t\tkp = append(kp, proxyman.KnownProtocols_HTTP)\n\t\tcase \"https\", \"tls\", \"ssl\":\n\t\t\tkp = append(kp, proxyman.KnownProtocols_TLS)\n\t\tdefault:\n\t\t\treturn nil, newError(\"Unknown protocol: \", p)\n\t\t}\n\t}\n\treturn kp, nil\n}\n\ntype InboundDetourAllocationConfig struct {\n\tStrategy    string  `json:\"strategy\"`\n\tConcurrency *uint32 `json:\"concurrency\"`\n\tRefreshMin  *uint32 `json:\"refresh\"`\n}\n\n// Build implements Buildable.\nfunc (c *InboundDetourAllocationConfig) Build() (*proxyman.AllocationStrategy, error) {\n\tconfig := new(proxyman.AllocationStrategy)\n\tswitch strings.ToLower(c.Strategy) {\n\tcase \"always\":\n\t\tconfig.Type = proxyman.AllocationStrategy_Always\n\tcase \"random\":\n\t\tconfig.Type = proxyman.AllocationStrategy_Random\n\tcase \"external\":\n\t\tconfig.Type = proxyman.AllocationStrategy_External\n\tdefault:\n\t\treturn nil, newError(\"unknown allocation strategy: \", c.Strategy)\n\t}\n\tif c.Concurrency != nil {\n\t\tconfig.Concurrency = &proxyman.AllocationStrategy_AllocationStrategyConcurrency{\n\t\t\tValue: *c.Concurrency,\n\t\t}\n\t}\n\n\tif c.RefreshMin != nil {\n\t\tconfig.Refresh = &proxyman.AllocationStrategy_AllocationStrategyRefresh{\n\t\t\tValue: *c.RefreshMin,\n\t\t}\n\t}\n\n\treturn config, nil\n}\n\ntype InboundDetourConfig struct {\n\tProtocol       string                         `json:\"protocol\"`\n\tPortRange      *cfgcommon.PortRange           `json:\"port\"`\n\tListenOn       *cfgcommon.Address             `json:\"listen\"`\n\tSettings       *json.RawMessage               `json:\"settings\"`\n\tTag            string                         `json:\"tag\"`\n\tAllocation     *InboundDetourAllocationConfig `json:\"allocate\"`\n\tStreamSetting  *StreamConfig                  `json:\"streamSettings\"`\n\tDomainOverride *cfgcommon.StringList          `json:\"domainOverride\"`\n\tSniffingConfig *sniffer.SniffingConfig        `json:\"sniffing\"`\n}\n\n// Build implements Buildable.\nfunc (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {\n\treceiverSettings := &proxyman.ReceiverConfig{}\n\n\tif c.ListenOn == nil {\n\t\t// Listen on anyip, must set PortRange\n\t\tif c.PortRange == nil {\n\t\t\treturn nil, newError(\"Listen on AnyIP but no Port(s) set in InboundDetour.\")\n\t\t}\n\t\treceiverSettings.PortRange = c.PortRange.Build()\n\t} else {\n\t\t// Listen on specific IP or Unix Domain Socket\n\t\treceiverSettings.Listen = c.ListenOn.Build()\n\t\tlistenDS := c.ListenOn.Family().IsDomain() && (filepath.IsAbs(c.ListenOn.Domain()) || c.ListenOn.Domain()[0] == '@')\n\t\tlistenIP := c.ListenOn.Family().IsIP() || (c.ListenOn.Family().IsDomain() && c.ListenOn.Domain() == \"localhost\")\n\t\tswitch {\n\t\tcase listenIP:\n\t\t\t// Listen on specific IP, must set PortRange\n\t\t\tif c.PortRange == nil {\n\t\t\t\treturn nil, newError(\"Listen on specific ip without port in InboundDetour.\")\n\t\t\t}\n\t\t\t// Listen on IP:Port\n\t\t\treceiverSettings.PortRange = c.PortRange.Build()\n\t\tcase listenDS:\n\t\t\tif c.PortRange != nil {\n\t\t\t\t// Listen on Unix Domain Socket, PortRange should be nil\n\t\t\t\treceiverSettings.PortRange = nil\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, newError(\"unable to listen on domain address: \", c.ListenOn.Domain())\n\t\t}\n\t}\n\n\tif c.Allocation != nil {\n\t\tconcurrency := -1\n\t\tif c.Allocation.Concurrency != nil && c.Allocation.Strategy == \"random\" {\n\t\t\tconcurrency = int(*c.Allocation.Concurrency)\n\t\t}\n\t\tportRange := int(c.PortRange.To - c.PortRange.From + 1)\n\t\tif concurrency >= 0 && concurrency >= portRange {\n\t\t\treturn nil, newError(\"not enough ports. concurrency = \", concurrency, \" ports: \", c.PortRange.From, \" - \", c.PortRange.To)\n\t\t}\n\n\t\tas, err := c.Allocation.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treceiverSettings.AllocationStrategy = as\n\t}\n\tif c.StreamSetting != nil {\n\t\tss, err := c.StreamSetting.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treceiverSettings.StreamSettings = ss\n\t}\n\tif c.SniffingConfig != nil {\n\t\ts, err := c.SniffingConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build sniffing config\").Base(err)\n\t\t}\n\t\treceiverSettings.SniffingSettings = s\n\t}\n\tif c.DomainOverride != nil {\n\t\tkp, err := toProtocolList(*c.DomainOverride)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse inbound detour config\").Base(err)\n\t\t}\n\t\treceiverSettings.DomainOverride = kp\n\t}\n\n\tsettings := []byte(\"{}\")\n\tif c.Settings != nil {\n\t\tsettings = ([]byte)(*c.Settings)\n\t}\n\trawConfig, err := inboundConfigLoader.LoadWithID(settings, c.Protocol)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to load inbound detour config.\").Base(err)\n\t}\n\tif dokodemoConfig, ok := rawConfig.(*DokodemoConfig); ok {\n\t\treceiverSettings.ReceiveOriginalDestination = dokodemoConfig.Redirect\n\t}\n\tts, err := rawConfig.(cfgcommon.Buildable).Build()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &core.InboundHandlerConfig{\n\t\tTag:              c.Tag,\n\t\tReceiverSettings: serial.ToTypedMessage(receiverSettings),\n\t\tProxySettings:    serial.ToTypedMessage(ts),\n\t}, nil\n}\n\ntype OutboundDetourConfig struct {\n\tProtocol       string                `json:\"protocol\"`\n\tSendThrough    *cfgcommon.Address    `json:\"sendThrough\"`\n\tTag            string                `json:\"tag\"`\n\tSettings       *json.RawMessage      `json:\"settings\"`\n\tStreamSetting  *StreamConfig         `json:\"streamSettings\"`\n\tProxySettings  *proxycfg.ProxyConfig `json:\"proxySettings\"`\n\tMuxSettings    *muxcfg.MuxConfig     `json:\"mux\"`\n\tDomainStrategy string                `json:\"domainStrategy\"`\n}\n\n// Build implements Buildable.\nfunc (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {\n\tsenderSettings := &proxyman.SenderConfig{}\n\n\tif c.SendThrough != nil {\n\t\taddress := c.SendThrough\n\t\tif address.Family().IsDomain() {\n\t\t\treturn nil, newError(\"unable to send through: \" + address.String())\n\t\t}\n\t\tsenderSettings.Via = address.Build()\n\t}\n\n\tif c.StreamSetting != nil {\n\t\tss, err := c.StreamSetting.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsenderSettings.StreamSettings = ss\n\t}\n\n\tif c.ProxySettings != nil {\n\t\tps, err := c.ProxySettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid outbound detour proxy settings.\").Base(err)\n\t\t}\n\t\tsenderSettings.ProxySettings = ps\n\t}\n\n\tif c.MuxSettings != nil {\n\t\tsenderSettings.MultiplexSettings = c.MuxSettings.Build()\n\t}\n\n\tsenderSettings.DomainStrategy = proxyman.SenderConfig_AS_IS\n\tswitch strings.ToLower(c.DomainStrategy) {\n\tcase \"useip\", \"use_ip\", \"use-ip\":\n\t\tsenderSettings.DomainStrategy = proxyman.SenderConfig_USE_IP\n\tcase \"useip4\", \"useipv4\", \"use_ip4\", \"use_ipv4\", \"use_ip_v4\", \"use-ip4\", \"use-ipv4\", \"use-ip-v4\":\n\t\tsenderSettings.DomainStrategy = proxyman.SenderConfig_USE_IP4\n\tcase \"useip6\", \"useipv6\", \"use_ip6\", \"use_ipv6\", \"use_ip_v6\", \"use-ip6\", \"use-ipv6\", \"use-ip-v6\":\n\t\tsenderSettings.DomainStrategy = proxyman.SenderConfig_USE_IP6\n\t}\n\n\tsettings := []byte(\"{}\")\n\tif c.Settings != nil {\n\t\tsettings = ([]byte)(*c.Settings)\n\t}\n\trawConfig, err := outboundConfigLoader.LoadWithID(settings, c.Protocol)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse to outbound detour config.\").Base(err)\n\t}\n\tts, err := rawConfig.(cfgcommon.Buildable).Build()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &core.OutboundHandlerConfig{\n\t\tSenderSettings: serial.ToTypedMessage(senderSettings),\n\t\tTag:            c.Tag,\n\t\tProxySettings:  serial.ToTypedMessage(ts),\n\t}, nil\n}\n\ntype StatsConfig struct{}\n\n// Build implements Buildable.\nfunc (c *StatsConfig) Build() (*stats.Config, error) {\n\treturn &stats.Config{}, nil\n}\n\ntype Config struct {\n\t// Port of this Point server.\n\t// Deprecated: Port exists for historical compatibility\n\t// and should not be used.\n\tPort uint16 `json:\"port\"`\n\n\t// Deprecated: InboundConfig exists for historical compatibility\n\t// and should not be used.\n\tInboundConfig *InboundDetourConfig `json:\"inbound\"`\n\n\t// Deprecated: OutboundConfig exists for historical compatibility\n\t// and should not be used.\n\tOutboundConfig *OutboundDetourConfig `json:\"outbound\"`\n\n\t// Deprecated: InboundDetours exists for historical compatibility\n\t// and should not be used.\n\tInboundDetours []InboundDetourConfig `json:\"inboundDetour\"`\n\n\t// Deprecated: OutboundDetours exists for historical compatibility\n\t// and should not be used.\n\tOutboundDetours []OutboundDetourConfig `json:\"outboundDetour\"`\n\n\tLogConfig        *log.LogConfig          `json:\"log\"`\n\tRouterConfig     *router.RouterConfig    `json:\"routing\"`\n\tDNSConfig        *dns.DNSConfig          `json:\"dns\"`\n\tInboundConfigs   []InboundDetourConfig   `json:\"inbounds\"`\n\tOutboundConfigs  []OutboundDetourConfig  `json:\"outbounds\"`\n\tTransport        *TransportConfig        `json:\"transport\"`\n\tPolicy           *PolicyConfig           `json:\"policy\"`\n\tAPI              *APIConfig              `json:\"api\"`\n\tStats            *StatsConfig            `json:\"stats\"`\n\tReverse          *ReverseConfig          `json:\"reverse\"`\n\tFakeDNS          *dns.FakeDNSConfig      `json:\"fakeDns\"`\n\tBrowserForwarder *BrowserForwarderConfig `json:\"browserForwarder\"`\n\tObservatory      *ObservatoryConfig      `json:\"observatory\"`\n\tBurstObservatory *BurstObservatoryConfig `json:\"burstObservatory\"`\n\tMultiObservatory *MultiObservatoryConfig `json:\"multiObservatory\"`\n\n\tServices map[string]*json.RawMessage `json:\"services\"`\n}\n\nfunc (c *Config) findInboundTag(tag string) int {\n\tfound := -1\n\tfor idx, ib := range c.InboundConfigs {\n\t\tif ib.Tag == tag {\n\t\t\tfound = idx\n\t\t\tbreak\n\t\t}\n\t}\n\treturn found\n}\n\nfunc (c *Config) findOutboundTag(tag string) int {\n\tfound := -1\n\tfor idx, ob := range c.OutboundConfigs {\n\t\tif ob.Tag == tag {\n\t\t\tfound = idx\n\t\t\tbreak\n\t\t}\n\t}\n\treturn found\n}\n\nfunc applyTransportConfig(s *StreamConfig, t *TransportConfig) {\n\tif s.TCPSettings == nil {\n\t\ts.TCPSettings = t.TCPConfig\n\t}\n\tif s.KCPSettings == nil {\n\t\ts.KCPSettings = t.KCPConfig\n\t}\n\tif s.WSSettings == nil {\n\t\ts.WSSettings = t.WSConfig\n\t}\n\tif s.HTTPSettings == nil {\n\t\ts.HTTPSettings = t.HTTPConfig\n\t}\n\tif s.DSSettings == nil {\n\t\ts.DSSettings = t.DSConfig\n\t}\n}\n\n// Build implements Buildable.\nfunc (c *Config) Build() (*core.Config, error) {\n\tif err := PostProcessConfigureFile(c); err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t}\n\n\tif c.API != nil {\n\t\tapiConf, err := c.API.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(apiConf))\n\t}\n\n\tif c.Stats != nil {\n\t\tstatsConf, err := c.Stats.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(statsConf))\n\t}\n\n\tvar logConfMsg *anypb.Any\n\tif c.LogConfig != nil {\n\t\tlogConfMsg = serial.ToTypedMessage(c.LogConfig.Build())\n\t} else {\n\t\tlogConfMsg = serial.ToTypedMessage(log.DefaultLogConfig())\n\t}\n\t// let logger module be the first App to start,\n\t// so that other modules could print log during initiating\n\tconfig.App = append([]*anypb.Any{logConfMsg}, config.App...)\n\n\tif c.RouterConfig != nil {\n\t\trouterConfig, err := c.RouterConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(routerConfig))\n\t}\n\n\tif c.FakeDNS != nil {\n\t\tfeatures.PrintDeprecatedFeatureWarning(\"root fakedns settings\")\n\t\tif c.DNSConfig != nil {\n\t\t\tc.DNSConfig.FakeDNS = c.FakeDNS\n\t\t} else {\n\t\t\tc.DNSConfig = &dns.DNSConfig{\n\t\t\t\tFakeDNS: c.FakeDNS,\n\t\t\t}\n\t\t}\n\t}\n\n\tif c.DNSConfig != nil {\n\t\tdnsApp, err := c.DNSConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse DNS config\").Base(err)\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(dnsApp))\n\t}\n\n\tif c.Policy != nil {\n\t\tpc, err := c.Policy.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(pc))\n\t}\n\n\tif c.Reverse != nil {\n\t\tr, err := c.Reverse.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(r))\n\t}\n\n\tif c.BrowserForwarder != nil {\n\t\tr, err := c.BrowserForwarder.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(r))\n\t}\n\n\tif c.Observatory != nil {\n\t\tr, err := c.Observatory.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(r))\n\t}\n\n\tif c.BurstObservatory != nil {\n\t\tr, err := c.BurstObservatory.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(r))\n\t}\n\n\tif c.MultiObservatory != nil {\n\t\tr, err := c.MultiObservatory.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(r))\n\t}\n\n\t// Load Additional Services that do not have a json translator\n\n\tfor serviceName, service := range c.Services {\n\t\tservicePackedConfig, err := v5cfg.LoadHeterogeneousConfigFromRawJSON(context.Background(), \"service\", serviceName, *service)\n\t\tif err != nil {\n\t\t\treturn nil, newError(fmt.Sprintf(\"failed to parse %v config in Services\", serviceName)).Base(err)\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(servicePackedConfig))\n\t}\n\n\tvar inbounds []InboundDetourConfig\n\n\tif c.InboundConfig != nil {\n\t\tinbounds = append(inbounds, *c.InboundConfig)\n\t}\n\n\tif len(c.InboundDetours) > 0 {\n\t\tinbounds = append(inbounds, c.InboundDetours...)\n\t}\n\n\tif len(c.InboundConfigs) > 0 {\n\t\tinbounds = append(inbounds, c.InboundConfigs...)\n\t}\n\n\t// Backward compatibility.\n\tif len(inbounds) > 0 && inbounds[0].PortRange == nil && c.Port > 0 {\n\t\tinbounds[0].PortRange = &cfgcommon.PortRange{\n\t\t\tFrom: uint32(c.Port),\n\t\t\tTo:   uint32(c.Port),\n\t\t}\n\t}\n\n\tfor _, rawInboundConfig := range inbounds {\n\t\tif c.Transport != nil {\n\t\t\tif rawInboundConfig.StreamSetting == nil {\n\t\t\t\trawInboundConfig.StreamSetting = &StreamConfig{}\n\t\t\t}\n\t\t\tapplyTransportConfig(rawInboundConfig.StreamSetting, c.Transport)\n\t\t}\n\t\tic, err := rawInboundConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Inbound = append(config.Inbound, ic)\n\t}\n\n\tvar outbounds []OutboundDetourConfig\n\n\tif c.OutboundConfig != nil {\n\t\toutbounds = append(outbounds, *c.OutboundConfig)\n\t}\n\n\tif len(c.OutboundDetours) > 0 {\n\t\toutbounds = append(outbounds, c.OutboundDetours...)\n\t}\n\n\tif len(c.OutboundConfigs) > 0 {\n\t\toutbounds = append(outbounds, c.OutboundConfigs...)\n\t}\n\n\tfor _, rawOutboundConfig := range outbounds {\n\t\tif c.Transport != nil {\n\t\t\tif rawOutboundConfig.StreamSetting == nil {\n\t\t\t\trawOutboundConfig.StreamSetting = &StreamConfig{}\n\t\t\t}\n\t\t\tapplyTransportConfig(rawOutboundConfig.StreamSetting, c.Transport)\n\t\t}\n\t\toc, err := rawOutboundConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Outbound = append(config.Outbound, oc)\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/v2ray_test.go",
    "content": "package v4_test\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/muxcfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/memconservative\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\tdns_proxy \"github.com/v2fly/v2ray-core/v5/proxy/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\"\n)\n\nfunc TestV2RayConfig(t *testing.T) {\n\tcreateParser := func() func(string) (proto.Message, error) {\n\t\treturn func(s string) (proto.Message, error) {\n\t\t\tconfig := new(v4.Config)\n\t\t\tif err := json.Unmarshal([]byte(s), config); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn config.Build()\n\t\t}\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"outbound\": {\n\t\t\t\t\t\"protocol\": \"freedom\",\n\t\t\t\t\t\"settings\": {}\n\t\t\t\t},\n\t\t\t\t\"log\": {\n\t\t\t\t\t\"access\": \"/var/log/v2ray/access.log\",\n\t\t\t\t\t\"loglevel\": \"error\",\n\t\t\t\t\t\"error\": \"/var/log/v2ray/error.log\"\n\t\t\t\t},\n\t\t\t\t\"inbound\": {\n\t\t\t\t\t\"streamSettings\": {\n\t\t\t\t\t\t\"network\": \"ws\",\n\t\t\t\t\t\t\"wsSettings\": {\n\t\t\t\t\t\t\t\"headers\": {\n\t\t\t\t\t\t\t\t\"host\": \"example.domain\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"path\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"tlsSettings\": {\n\t\t\t\t\t\t\t\"alpn\": \"h2\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"security\": \"tls\"\n\t\t\t\t\t},\n\t\t\t\t\t\"protocol\": \"vmess\",\n\t\t\t\t\t\"port\": 443,\n\t\t\t\t\t\"settings\": {\n\t\t\t\t\t\t\"clients\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"alterId\": 100,\n\t\t\t\t\t\t\t\t\"security\": \"aes-128-gcm\",\n\t\t\t\t\t\t\t\t\"id\": \"0cdf8a45-303d-4fed-9780-29aa7f54175e\"\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\t\"inbounds\": [{\n\t\t\t\t\t\"streamSettings\": {\n\t\t\t\t\t\t\"network\": \"ws\",\n\t\t\t\t\t\t\"wsSettings\": {\n\t\t\t\t\t\t\t\"headers\": {\n\t\t\t\t\t\t\t\t\"host\": \"example.domain\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"path\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"tlsSettings\": {\n\t\t\t\t\t\t\t\"alpn\": \"h2\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"security\": \"tls\"\n\t\t\t\t\t},\n\t\t\t\t\t\"protocol\": \"vmess\",\n\t\t\t\t\t\"port\": \"443-500\",\n\t\t\t\t\t\"allocate\": {\n\t\t\t\t\t\t\"strategy\": \"random\",\n\t\t\t\t\t\t\"concurrency\": 3\n\t\t\t\t\t},\n\t\t\t\t\t\"settings\": {\n\t\t\t\t\t\t\"clients\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"alterId\": 100,\n\t\t\t\t\t\t\t\t\"security\": \"aes-128-gcm\",\n\t\t\t\t\t\t\t\t\"id\": \"0cdf8a45-303d-4fed-9780-29aa7f54175e\"\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\t\"outboundDetour\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"tag\": \"blocked\",\n\t\t\t\t\t\t\"protocol\": \"blackhole\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"protocol\": \"dns\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"routing\": {\n\t\t\t\t\t\"strategy\": \"rules\",\n\t\t\t\t\t\"settings\": {\n\t\t\t\t\t\t\"rules\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"ip\": [\n\t\t\t\t\t\t\t\t\t\"10.0.0.0/8\"\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"type\": \"field\",\n\t\t\t\t\t\t\t\t\"outboundTag\": \"blocked\"\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\t\"transport\": {\n\t\t\t\t\t\"httpSettings\": {\n\t\t\t\t\t\t\"path\": \"/test\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t\tParser: createParser(),\n\t\t\tOutput: &core.Config{\n\t\t\t\tApp: []*anypb.Any{\n\t\t\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\t\t\tError: &log.LogSpecification{\n\t\t\t\t\t\t\tType:  log.LogType_File,\n\t\t\t\t\t\t\tLevel: clog.Severity_Error,\n\t\t\t\t\t\t\tPath:  \"/var/log/v2ray/error.log\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAccess: &log.LogSpecification{\n\t\t\t\t\t\t\tType: log.LogType_File,\n\t\t\t\t\t\t\tPath: \"/var/log/v2ray/access.log\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\t\t\tDomainStrategy: router.DomainStrategy_AsIs,\n\t\t\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tGeoip: []*routercommon.GeoIP{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tIp:     []byte{10, 0, 0, 0},\n\t\t\t\t\t\t\t\t\t\t\t\tPrefix: 8,\n\t\t\t\t\t\t\t\t\t\t\t},\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\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\t\t\tTag: \"blocked\",\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\t\t\tProtocolName: \"tcp\",\n\t\t\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tProtocolName: \"http\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\t\t\tPath: \"/test\",\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\tProxySettings: serial.ToTypedMessage(&freedom.Config{\n\t\t\t\t\t\t\tDomainStrategy: freedom.Config_AS_IS,\n\t\t\t\t\t\t\tUserLevel:      0,\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\tTag: \"blocked\",\n\t\t\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\t\t\tProtocolName: \"tcp\",\n\t\t\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tProtocolName: \"http\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\t\t\tPath: \"/test\",\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\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\t\t\tProtocolName: \"tcp\",\n\t\t\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tProtocolName: \"http\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\t\t\tPath: \"/test\",\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\tProxySettings: serial.ToTypedMessage(&dns_proxy.Config{\n\t\t\t\t\t\t\tServer: &net.Endpoint{},\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\t\t\tPortRange: &net.PortRange{\n\t\t\t\t\t\t\t\tFrom: 443,\n\t\t\t\t\t\t\t\tTo:   443,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\t\t\tProtocolName: \"websocket\",\n\t\t\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tProtocolName: \"websocket\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&websocket.Config{\n\t\t\t\t\t\t\t\t\t\t\tHeader: []*websocket.Header{\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\t\tKey:   \"host\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tValue: \"example.domain\",\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}),\n\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\t\tProtocolName: \"http\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\t\t\tPath: \"/test\",\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\tSecurityType: \"v2ray.core.transport.internet.tls.Config\",\n\t\t\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\t\t\tNextProtocol: []string{\"h2\"},\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLevel: 0,\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      \"0cdf8a45-303d-4fed-9780-29aa7f54175e\",\n\t\t\t\t\t\t\t\t\t\tAlterId: 100,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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\t{\n\t\t\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\t\t\tPortRange: &net.PortRange{\n\t\t\t\t\t\t\t\tFrom: 443,\n\t\t\t\t\t\t\t\tTo:   500,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tAllocationStrategy: &proxyman.AllocationStrategy{\n\t\t\t\t\t\t\t\tType: proxyman.AllocationStrategy_Random,\n\t\t\t\t\t\t\t\tConcurrency: &proxyman.AllocationStrategy_AllocationStrategyConcurrency{\n\t\t\t\t\t\t\t\t\tValue: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\t\t\tProtocolName: \"websocket\",\n\t\t\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tProtocolName: \"websocket\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&websocket.Config{\n\t\t\t\t\t\t\t\t\t\t\tHeader: []*websocket.Header{\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\t\tKey:   \"host\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tValue: \"example.domain\",\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}),\n\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\t\tProtocolName: \"http\",\n\t\t\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\t\t\tPath: \"/test\",\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\tSecurityType: \"v2ray.core.transport.internet.tls.Config\",\n\t\t\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\t\t\tNextProtocol: []string{\"h2\"},\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLevel: 0,\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      \"0cdf8a45-303d-4fed-9780-29aa7f54175e\",\n\t\t\t\t\t\t\t\t\t\tAlterId: 100,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t})\n}\n\nfunc TestMuxConfig_Build(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tfields string\n\t\twant   *proxyman.MultiplexingConfig\n\t}{\n\t\t{\"default\", `{\"enabled\": true, \"concurrency\": 16}`, &proxyman.MultiplexingConfig{\n\t\t\tEnabled:     true,\n\t\t\tConcurrency: 16,\n\t\t}},\n\t\t{\"empty def\", `{}`, &proxyman.MultiplexingConfig{\n\t\t\tEnabled:     false,\n\t\t\tConcurrency: 8,\n\t\t}},\n\t\t{\"not enable\", `{\"enabled\": false, \"concurrency\": 4}`, &proxyman.MultiplexingConfig{\n\t\t\tEnabled:     false,\n\t\t\tConcurrency: 4,\n\t\t}},\n\t\t{\"forbidden\", `{\"enabled\": false, \"concurrency\": -1}`, nil},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tm := &muxcfg.MuxConfig{}\n\t\t\tcommon.Must(json.Unmarshal([]byte(tt.fields), m))\n\t\t\tif got := m.Build(); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"MuxConfig.Build() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "infra/conf/v4/vless.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless/outbound\"\n)\n\ntype VLessInboundFallback struct {\n\tAlpn string          `json:\"alpn\"`\n\tPath string          `json:\"path\"`\n\tType string          `json:\"type\"`\n\tDest json.RawMessage `json:\"dest\"`\n\tXver uint64          `json:\"xver\"`\n}\n\ntype VLessInboundConfig struct {\n\tClients    []json.RawMessage       `json:\"clients\"`\n\tDecryption string                  `json:\"decryption\"`\n\tFallback   json.RawMessage         `json:\"fallback\"`\n\tFallbacks  []*VLessInboundFallback `json:\"fallbacks\"`\n}\n\n// Build implements Buildable\nfunc (c *VLessInboundConfig) Build() (proto.Message, error) {\n\tconfig := new(inbound.Config)\n\tconfig.Clients = make([]*protocol.User, len(c.Clients))\n\tfor idx, rawUser := range c.Clients {\n\t\tuser := new(protocol.User)\n\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\treturn nil, newError(`VLESS clients: invalid user`).Base(err)\n\t\t}\n\t\taccount := new(vless.Account)\n\t\tif err := json.Unmarshal(rawUser, account); err != nil {\n\t\t\treturn nil, newError(`VLESS clients: invalid user`).Base(err)\n\t\t}\n\n\t\tif account.Encryption != \"\" {\n\t\t\treturn nil, newError(`VLESS clients: \"encryption\" should not in inbound settings`)\n\t\t}\n\n\t\tuser.Account = serial.ToTypedMessage(account)\n\t\tconfig.Clients[idx] = user\n\t}\n\n\tif c.Decryption != \"none\" {\n\t\treturn nil, newError(`VLESS settings: please add/set \"decryption\":\"none\" to every settings`)\n\t}\n\tconfig.Decryption = c.Decryption\n\n\tif c.Fallback != nil {\n\t\treturn nil, newError(`VLESS settings: please use \"fallbacks\":[{}] instead of \"fallback\":{}`)\n\t}\n\tfor _, fb := range c.Fallbacks {\n\t\tvar i uint16\n\t\tvar s string\n\t\tif err := json.Unmarshal(fb.Dest, &i); err == nil {\n\t\t\ts = strconv.Itoa(int(i))\n\t\t} else {\n\t\t\t_ = json.Unmarshal(fb.Dest, &s)\n\t\t}\n\t\tconfig.Fallbacks = append(config.Fallbacks, &inbound.Fallback{\n\t\t\tAlpn: fb.Alpn,\n\t\t\tPath: fb.Path,\n\t\t\tType: fb.Type,\n\t\t\tDest: s,\n\t\t\tXver: fb.Xver,\n\t\t})\n\t}\n\tfor _, fb := range config.Fallbacks {\n\t\t/*\n\t\t\tif fb.Alpn == \"h2\" && fb.Path != \"\" {\n\t\t\t\treturn nil, newError(`VLESS fallbacks: \"alpn\":\"h2\" doesn't support \"path\"`)\n\t\t\t}\n\t\t*/\n\t\tif fb.Path != \"\" && fb.Path[0] != '/' {\n\t\t\treturn nil, newError(`VLESS fallbacks: \"path\" must be empty or start with \"/\"`)\n\t\t}\n\t\tif fb.Type == \"\" && fb.Dest != \"\" {\n\t\t\tif fb.Dest == \"serve-ws-none\" { // nolint:gocritic\n\t\t\t\tfb.Type = \"serve\"\n\t\t\t} else if filepath.IsAbs(fb.Dest) || fb.Dest[0] == '@' {\n\t\t\t\tfb.Type = \"unix\"\n\t\t\t\tif strings.HasPrefix(fb.Dest, \"@@\") && (runtime.GOOS == \"linux\" || runtime.GOOS == \"android\") {\n\t\t\t\t\tfullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy\n\t\t\t\t\tcopy(fullAddr, fb.Dest[1:])\n\t\t\t\t\tfb.Dest = string(fullAddr)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif _, err := strconv.Atoi(fb.Dest); err == nil {\n\t\t\t\t\tfb.Dest = \"127.0.0.1:\" + fb.Dest\n\t\t\t\t}\n\t\t\t\tif _, _, err := net.SplitHostPort(fb.Dest); err == nil {\n\t\t\t\t\tfb.Type = \"tcp\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif fb.Type == \"\" {\n\t\t\treturn nil, newError(`VLESS fallbacks: please fill in a valid value for every \"dest\"`)\n\t\t}\n\t\tif fb.Xver > 2 {\n\t\t\treturn nil, newError(`VLESS fallbacks: invalid PROXY protocol version, \"xver\" only accepts 0, 1, 2`)\n\t\t}\n\t}\n\n\treturn config, nil\n}\n\ntype VLessOutboundVnext struct {\n\tAddress *cfgcommon.Address `json:\"address\"`\n\tPort    uint16             `json:\"port\"`\n\tUsers   []json.RawMessage  `json:\"users\"`\n}\n\ntype VLessOutboundConfig struct {\n\tVnext []*VLessOutboundVnext `json:\"vnext\"`\n}\n\n// Build implements Buildable\nfunc (c *VLessOutboundConfig) Build() (proto.Message, error) {\n\tconfig := new(outbound.Config)\n\n\tif len(c.Vnext) == 0 {\n\t\treturn nil, newError(`VLESS settings: \"vnext\" is empty`)\n\t}\n\tconfig.Vnext = make([]*protocol.ServerEndpoint, len(c.Vnext))\n\tfor idx, rec := range c.Vnext {\n\t\tif rec.Address == nil {\n\t\t\treturn nil, newError(`VLESS vnext: \"address\" is not set`)\n\t\t}\n\t\tif len(rec.Users) == 0 {\n\t\t\treturn nil, newError(`VLESS vnext: \"users\" is empty`)\n\t\t}\n\t\tspec := &protocol.ServerEndpoint{\n\t\t\tAddress: rec.Address.Build(),\n\t\t\tPort:    uint32(rec.Port),\n\t\t\tUser:    make([]*protocol.User, len(rec.Users)),\n\t\t}\n\t\tfor idx, rawUser := range rec.Users {\n\t\t\tuser := new(protocol.User)\n\t\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\t\treturn nil, newError(`VLESS users: invalid user`).Base(err)\n\t\t\t}\n\t\t\taccount := new(vless.Account)\n\t\t\tif err := json.Unmarshal(rawUser, account); err != nil {\n\t\t\t\treturn nil, newError(`VLESS users: invalid user`).Base(err)\n\t\t\t}\n\n\t\t\tif account.Encryption != \"none\" {\n\t\t\t\treturn nil, newError(`VLESS users: please add/set \"encryption\":\"none\" for every user`)\n\t\t\t}\n\n\t\t\tuser.Account = serial.ToTypedMessage(account)\n\t\t\tspec.User[idx] = user\n\t\t}\n\t\tconfig.Vnext[idx] = spec\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/vless_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless/outbound\"\n)\n\nfunc TestVLessOutbound(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.VLessOutboundConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"vnext\": [{\n\t\t\t\t\t\"address\": \"example.com\",\n\t\t\t\t\t\"port\": 443,\n\t\t\t\t\t\"users\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"27848739-7e62-4138-9fd3-098a63964b6b\",\n\t\t\t\t\t\t\t\"encryption\": \"none\",\n\t\t\t\t\t\t\t\"level\": 0\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\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &outbound.Config{\n\t\t\t\tVnext: []*protocol.ServerEndpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Domain{\n\t\t\t\t\t\t\t\tDomain: \"example.com\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 443,\n\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vless.Account{\n\t\t\t\t\t\t\t\t\tId:         \"27848739-7e62-4138-9fd3-098a63964b6b\",\n\t\t\t\t\t\t\t\t\tEncryption: \"none\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tLevel: 0,\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 TestVLessInbound(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.VLessInboundConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"clients\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"id\": \"27848739-7e62-4138-9fd3-098a63964b6b\",\n\t\t\t\t\t\t\"level\": 0,\n\t\t\t\t\t\t\"email\": \"love@v2fly.org\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"decryption\": \"none\",\n\t\t\t\t\"fallbacks\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"dest\": 80\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"alpn\": \"h2\",\n\t\t\t\t\t\t\"dest\": \"@/dev/shm/domain.socket\",\n\t\t\t\t\t\t\"xver\": 2\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"path\": \"/innerws\",\n\t\t\t\t\t\t\"dest\": \"serve-ws-none\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &inbound.Config{\n\t\t\t\tClients: []*protocol.User{\n\t\t\t\t\t{\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vless.Account{\n\t\t\t\t\t\t\tId: \"27848739-7e62-4138-9fd3-098a63964b6b\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tLevel: 0,\n\t\t\t\t\t\tEmail: \"love@v2fly.org\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDecryption: \"none\",\n\t\t\t\tFallbacks: []*inbound.Fallback{\n\t\t\t\t\t{\n\t\t\t\t\t\tAlpn: \"\",\n\t\t\t\t\t\tPath: \"\",\n\t\t\t\t\t\tType: \"tcp\",\n\t\t\t\t\t\tDest: \"127.0.0.1:80\",\n\t\t\t\t\t\tXver: 0,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tAlpn: \"h2\",\n\t\t\t\t\t\tPath: \"\",\n\t\t\t\t\t\tType: \"unix\",\n\t\t\t\t\t\tDest: \"@/dev/shm/domain.socket\",\n\t\t\t\t\t\tXver: 2,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tAlpn: \"\",\n\t\t\t\t\t\tPath: \"/innerws\",\n\t\t\t\t\t\tType: \"serve\",\n\t\t\t\t\t\tDest: \"serve-ws-none\",\n\t\t\t\t\t\tXver: 0,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v4/vmess.go",
    "content": "package v4\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n)\n\ntype VMessAccount struct {\n\tID          string `json:\"id\"`\n\tAlterIds    uint16 `json:\"alterId\"`\n\tSecurity    string `json:\"security\"`\n\tExperiments string `json:\"experiments\"`\n}\n\n// Build implements Buildable\nfunc (a *VMessAccount) Build() *vmess.Account {\n\tvar st protocol.SecurityType\n\tswitch strings.ToLower(a.Security) {\n\tcase \"aes-128-gcm\":\n\t\tst = protocol.SecurityType_AES128_GCM\n\tcase \"chacha20-poly1305\":\n\t\tst = protocol.SecurityType_CHACHA20_POLY1305\n\tcase \"auto\":\n\t\tst = protocol.SecurityType_AUTO\n\tcase \"none\":\n\t\tst = protocol.SecurityType_NONE\n\tcase \"zero\":\n\t\tst = protocol.SecurityType_ZERO\n\tdefault:\n\t\tst = protocol.SecurityType_AUTO\n\t}\n\treturn &vmess.Account{\n\t\tId:      a.ID,\n\t\tAlterId: uint32(a.AlterIds),\n\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\tType: st,\n\t\t},\n\t\tTestsEnabled: a.Experiments,\n\t}\n}\n\ntype VMessDetourConfig struct {\n\tToTag string `json:\"to\"`\n}\n\n// Build implements Buildable\nfunc (c *VMessDetourConfig) Build() *inbound.DetourConfig {\n\treturn &inbound.DetourConfig{\n\t\tTo: c.ToTag,\n\t}\n}\n\ntype FeaturesConfig struct {\n\tDetour *VMessDetourConfig `json:\"detour\"`\n}\n\ntype VMessDefaultConfig struct {\n\tAlterIDs uint16 `json:\"alterId\"`\n\tLevel    byte   `json:\"level\"`\n}\n\n// Build implements Buildable\nfunc (c *VMessDefaultConfig) Build() *inbound.DefaultConfig {\n\tconfig := new(inbound.DefaultConfig)\n\tconfig.AlterId = uint32(c.AlterIDs)\n\tconfig.Level = uint32(c.Level)\n\treturn config\n}\n\ntype VMessInboundConfig struct {\n\tUsers        []json.RawMessage   `json:\"clients\"`\n\tFeatures     *FeaturesConfig     `json:\"features\"`\n\tDefaults     *VMessDefaultConfig `json:\"default\"`\n\tDetourConfig *VMessDetourConfig  `json:\"detour\"`\n\tSecureOnly   bool                `json:\"disableInsecureEncryption\"`\n}\n\n// Build implements Buildable\nfunc (c *VMessInboundConfig) Build() (proto.Message, error) {\n\tconfig := &inbound.Config{\n\t\tSecureEncryptionOnly: c.SecureOnly,\n\t}\n\n\tif c.Defaults != nil {\n\t\tconfig.Default = c.Defaults.Build()\n\t}\n\n\tif c.DetourConfig != nil {\n\t\tconfig.Detour = c.DetourConfig.Build()\n\t} else if c.Features != nil && c.Features.Detour != nil {\n\t\tconfig.Detour = c.Features.Detour.Build()\n\t}\n\n\tconfig.User = make([]*protocol.User, len(c.Users))\n\tfor idx, rawData := range c.Users {\n\t\tuser := new(protocol.User)\n\t\tif err := json.Unmarshal(rawData, user); err != nil {\n\t\t\treturn nil, newError(\"invalid VMess user\").Base(err)\n\t\t}\n\t\taccount := new(VMessAccount)\n\t\tif err := json.Unmarshal(rawData, account); err != nil {\n\t\t\treturn nil, newError(\"invalid VMess user\").Base(err)\n\t\t}\n\t\tuser.Account = serial.ToTypedMessage(account.Build())\n\t\tconfig.User[idx] = user\n\t}\n\n\treturn config, nil\n}\n\ntype VMessOutboundTarget struct {\n\tAddress *cfgcommon.Address `json:\"address\"`\n\tPort    uint16             `json:\"port\"`\n\tUsers   []json.RawMessage  `json:\"users\"`\n}\n\ntype VMessOutboundConfig struct {\n\tReceivers []*VMessOutboundTarget `json:\"vnext\"`\n}\n\n// Build implements Buildable\nfunc (c *VMessOutboundConfig) Build() (proto.Message, error) {\n\tconfig := new(outbound.Config)\n\n\tif len(c.Receivers) == 0 {\n\t\treturn nil, newError(\"0 VMess receiver configured\")\n\t}\n\tserverSpecs := make([]*protocol.ServerEndpoint, len(c.Receivers))\n\tfor idx, rec := range c.Receivers {\n\t\tif len(rec.Users) == 0 {\n\t\t\treturn nil, newError(\"0 user configured for VMess outbound\")\n\t\t}\n\t\tif rec.Address == nil {\n\t\t\treturn nil, newError(\"address is not set in VMess outbound config\")\n\t\t}\n\t\tspec := &protocol.ServerEndpoint{\n\t\t\tAddress: rec.Address.Build(),\n\t\t\tPort:    uint32(rec.Port),\n\t\t}\n\t\tfor _, rawUser := range rec.Users {\n\t\t\tuser := new(protocol.User)\n\t\t\tif err := json.Unmarshal(rawUser, user); err != nil {\n\t\t\t\treturn nil, newError(\"invalid VMess user\").Base(err)\n\t\t\t}\n\t\t\taccount := new(VMessAccount)\n\t\t\tif err := json.Unmarshal(rawUser, account); err != nil {\n\t\t\t\treturn nil, newError(\"invalid VMess user\").Base(err)\n\t\t\t}\n\t\t\tuser.Account = serial.ToTypedMessage(account.Build())\n\t\t\tspec.User = append(spec.User, user)\n\t\t}\n\t\tserverSpecs[idx] = spec\n\t}\n\tconfig.Receiver = serverSpecs\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v4/vmess_test.go",
    "content": "package v4_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/testassist\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n)\n\nfunc TestVMessOutbound(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.VMessOutboundConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"vnext\": [{\n\t\t\t\t\t\"address\": \"127.0.0.1\",\n\t\t\t\t\t\"port\": 80,\n\t\t\t\t\t\"users\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"e641f5ad-9397-41e3-bf1a-e8740dfed019\",\n\t\t\t\t\t\t\t\"email\": \"love@v2fly.org\",\n\t\t\t\t\t\t\t\"level\": 255\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\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &outbound.Config{\n\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: 80,\n\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tEmail: \"love@v2fly.org\",\n\t\t\t\t\t\t\t\tLevel: 255,\n\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\tId:      \"e641f5ad-9397-41e3-bf1a-e8740dfed019\",\n\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AUTO,\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},\n\t})\n}\n\nfunc TestVMessInbound(t *testing.T) {\n\tcreator := func() cfgcommon.Buildable {\n\t\treturn new(v4.VMessInboundConfig)\n\t}\n\n\ttestassist.RunMultiTestCase(t, []testassist.TestCase{\n\t\t{\n\t\t\tInput: `{\n\t\t\t\t\"clients\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"id\": \"27848739-7e62-4138-9fd3-098a63964b6b\",\n\t\t\t\t\t\t\"level\": 0,\n\t\t\t\t\t\t\"alterId\": 16,\n\t\t\t\t\t\t\"email\": \"love@v2fly.org\",\n\t\t\t\t\t\t\"security\": \"aes-128-gcm\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"default\": {\n\t\t\t\t\t\"level\": 0,\n\t\t\t\t\t\"alterId\": 32\n\t\t\t\t},\n\t\t\t\t\"detour\": {\n\t\t\t\t\t\"to\": \"tag_to_detour\"\n\t\t\t\t},\n\t\t\t\t\"disableInsecureEncryption\": true\n\t\t\t}`,\n\t\t\tParser: testassist.LoadJSON(creator),\n\t\t\tOutput: &inbound.Config{\n\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t{\n\t\t\t\t\t\tLevel: 0,\n\t\t\t\t\t\tEmail: \"love@v2fly.org\",\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\tId:      \"27848739-7e62-4138-9fd3-098a63964b6b\",\n\t\t\t\t\t\t\tAlterId: 16,\n\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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\tDefault: &inbound.DefaultConfig{\n\t\t\t\t\tLevel:   0,\n\t\t\t\t\tAlterId: 32,\n\t\t\t\t},\n\t\t\t\tDetour: &inbound.DetourConfig{\n\t\t\t\t\tTo: \"tag_to_detour\",\n\t\t\t\t},\n\t\t\t\tSecureEncryptionOnly: true,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/common.go",
    "content": "package v5cfg\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/registry\"\n)\n\nfunc loadHeterogeneousConfigFromRawJSON(interfaceType, name string, rawJSON json.RawMessage) (proto.Message, error) {\n\tfsdef := envimpl.NewDefaultFileSystemDefaultImpl()\n\tctx := envctx.ContextWithEnvironment(context.TODO(), fsdef)\n\tif len(rawJSON) == 0 {\n\t\trawJSON = []byte(\"{}\")\n\t}\n\treturn registry.LoadImplementationByAlias(ctx, interfaceType, name, []byte(rawJSON))\n}\n\n// LoadHeterogeneousConfigFromRawJSON private API\nfunc LoadHeterogeneousConfigFromRawJSON(ctx context.Context, interfaceType, name string, rawJSON json.RawMessage) (proto.Message, error) {\n\treturn loadHeterogeneousConfigFromRawJSON(interfaceType, name, rawJSON)\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/errors.generated.go",
    "content": "package v5cfg\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/inbound.go",
    "content": "package v5cfg\n\nimport (\n\t\"context\"\n\t\"path/filepath\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc (c InboundConfig) BuildV5(ctx context.Context) (proto.Message, error) {\n\treceiverSettings := &proxyman.ReceiverConfig{}\n\n\tif c.ListenOn == nil {\n\t\t// Listen on anyip, must set PortRange\n\t\tif c.PortRange == nil {\n\t\t\treturn nil, newError(\"Listen on AnyIP but no Port(s) set in InboundDetour.\")\n\t\t}\n\t\treceiverSettings.PortRange = c.PortRange.Build()\n\t} else {\n\t\t// Listen on specific IP or Unix Domain Socket\n\t\treceiverSettings.Listen = c.ListenOn.Build()\n\t\tlistenDS := c.ListenOn.Family().IsDomain() && (filepath.IsAbs(c.ListenOn.Domain()) || c.ListenOn.Domain()[0] == '@')\n\t\tlistenIP := c.ListenOn.Family().IsIP() || (c.ListenOn.Family().IsDomain() && c.ListenOn.Domain() == \"localhost\")\n\t\tswitch {\n\t\tcase listenIP:\n\t\t\t// Listen on specific IP, must set PortRange\n\t\t\tif c.PortRange == nil {\n\t\t\t\treturn nil, newError(\"Listen on specific ip without port in InboundDetour.\")\n\t\t\t}\n\t\t\t// Listen on IP:Port\n\t\t\treceiverSettings.PortRange = c.PortRange.Build()\n\t\tcase listenDS:\n\t\t\tif c.PortRange != nil {\n\t\t\t\t// Listen on Unix Domain Socket, PortRange should be nil\n\t\t\t\treceiverSettings.PortRange = nil\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, newError(\"unable to listen on domain address: \", c.ListenOn.Domain())\n\t\t}\n\t}\n\n\tif c.StreamSetting != nil {\n\t\tss, err := c.StreamSetting.BuildV5(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treceiverSettings.StreamSettings = ss.(*internet.StreamConfig)\n\t}\n\n\tif c.SniffingConfig != nil {\n\t\ts, err := c.SniffingConfig.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to build sniffing config\").Base(err)\n\t\t}\n\t\treceiverSettings.SniffingSettings = s\n\t}\n\n\tif c.Settings == nil {\n\t\tc.Settings = []byte(\"{}\")\n\t}\n\n\tinboundConfigPack, err := loadHeterogeneousConfigFromRawJSON(\"inbound\", c.Protocol, c.Settings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to load inbound protocol config\").Base(err)\n\t}\n\n\tif content, ok := inboundConfigPack.(*dokodemo.SimplifiedConfig); ok {\n\t\treceiverSettings.ReceiveOriginalDestination = content.FollowRedirect\n\t}\n\tif content, ok := inboundConfigPack.(*dokodemo.Config); ok {\n\t\treceiverSettings.ReceiveOriginalDestination = content.FollowRedirect\n\t}\n\n\treturn &core.InboundHandlerConfig{\n\t\tTag:              c.Tag,\n\t\tReceiverSettings: serial.ToTypedMessage(receiverSettings),\n\t\tProxySettings:    serial.ToTypedMessage(inboundConfigPack),\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/init.go",
    "content": "package v5cfg\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/json\"\n)\n\nconst jsonV5 = \"jsonv5\"\n\nfunc init() {\n\tcommon.Must(core.RegisterConfigLoader(&core.ConfigFormat{\n\t\tName:      []string{jsonV5},\n\t\tExtension: []string{\".v5.json\", \".v5.jsonc\"},\n\t\tLoader: func(input interface{}) (*core.Config, error) {\n\t\t\tswitch v := input.(type) {\n\t\t\tcase string:\n\t\t\t\tr, err := cmdarg.LoadArg(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\tdata, err := buf.ReadAllToBytes(&json.Reader{\n\t\t\t\t\tReader: r,\n\t\t\t\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\treturn loadJSONConfig(data)\n\t\t\tcase []byte:\n\t\t\t\tr := &json.Reader{\n\t\t\t\t\tReader: bytes.NewReader(v),\n\t\t\t\t}\n\t\t\t\tdata, err := buf.ReadAllToBytes(r)\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 loadJSONConfig(data)\n\t\t\tcase io.Reader:\n\t\t\t\tdata, err := buf.ReadAllToBytes(&json.Reader{\n\t\t\t\t\tReader: v,\n\t\t\t\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\treturn loadJSONConfig(data)\n\t\t\tdefault:\n\t\t\t\treturn nil, newError(\"unknown type\")\n\t\t\t}\n\t\t},\n\t}))\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/outbound.go",
    "content": "package v5cfg\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc (c OutboundConfig) BuildV5(ctx context.Context) (proto.Message, error) {\n\tsenderSettings := &proxyman.SenderConfig{}\n\n\tif c.SendThrough != nil {\n\t\taddress := c.SendThrough\n\t\tif address.Family().IsDomain() {\n\t\t\treturn nil, newError(\"unable to send through: \" + address.String())\n\t\t}\n\t\tsenderSettings.Via = address.Build()\n\t}\n\n\tif c.StreamSetting != nil {\n\t\tss, err := c.StreamSetting.BuildV5(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsenderSettings.StreamSettings = ss.(*internet.StreamConfig)\n\t}\n\n\tif c.ProxySettings != nil {\n\t\tps, err := c.ProxySettings.Build()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid outbound detour proxy settings.\").Base(err)\n\t\t}\n\t\tsenderSettings.ProxySettings = ps\n\t}\n\n\tif c.MuxSettings != nil {\n\t\tsenderSettings.MultiplexSettings = c.MuxSettings.Build()\n\t}\n\n\tsenderSettings.DomainStrategy = proxyman.SenderConfig_AS_IS\n\tswitch c.DomainStrategy {\n\tcase \"UseIP\":\n\t\tsenderSettings.DomainStrategy = proxyman.SenderConfig_USE_IP\n\tcase \"UseIP4\":\n\t\tsenderSettings.DomainStrategy = proxyman.SenderConfig_USE_IP4\n\tcase \"UseIP6\":\n\t\tsenderSettings.DomainStrategy = proxyman.SenderConfig_USE_IP6\n\tcase \"AsIs\", \"\":\n\tdefault:\n\t\treturn nil, newError(\"unknown domain strategy: \", c.DomainStrategy)\n\t}\n\n\tif c.Settings == nil {\n\t\tc.Settings = []byte(\"{}\")\n\t}\n\n\toutboundConfigPack, err := loadHeterogeneousConfigFromRawJSON(\"outbound\", c.Protocol, c.Settings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to load outbound protocol config\").Base(err)\n\t}\n\n\treturn &core.OutboundHandlerConfig{\n\t\tSenderSettings: serial.ToTypedMessage(senderSettings),\n\t\tTag:            c.Tag,\n\t\tProxySettings:  serial.ToTypedMessage(outboundConfigPack),\n\t}, nil\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/root.go",
    "content": "package v5cfg\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/geodata\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/synthetic/log\"\n)\n\nfunc (c RootConfig) BuildV5(ctx context.Context) (proto.Message, error) {\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t}\n\n\tvar logConfMsg *anypb.Any\n\tif c.LogConfig != nil {\n\t\tlogConfMsgUnpacked, err := loadHeterogeneousConfigFromRawJSON(\"service\", \"log\", c.LogConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse Log config\").Base(err)\n\t\t}\n\t\tlogConfMsg = serial.ToTypedMessage(logConfMsgUnpacked)\n\t} else {\n\t\tlogConfMsg = serial.ToTypedMessage(log.DefaultLogConfig())\n\t}\n\t// let logger module be the first App to start,\n\t// so that other modules could print log during initiating\n\tconfig.App = append([]*anypb.Any{logConfMsg}, config.App...)\n\n\tif c.RouterConfig != nil {\n\t\trouterConfig, err := loadHeterogeneousConfigFromRawJSON(\"service\", \"router\", c.RouterConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse Router config\").Base(err)\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(routerConfig))\n\t}\n\n\tif c.DNSConfig != nil {\n\t\tdnsApp, err := loadHeterogeneousConfigFromRawJSON(\"service\", \"dns\", c.DNSConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse DNS config\").Base(err)\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(dnsApp))\n\t}\n\n\tfor _, rawInboundConfig := range c.Inbounds {\n\t\tic, err := rawInboundConfig.BuildV5(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Inbound = append(config.Inbound, ic.(*core.InboundHandlerConfig))\n\t}\n\n\tfor _, rawOutboundConfig := range c.Outbounds {\n\t\tic, err := rawOutboundConfig.BuildV5(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Outbound = append(config.Outbound, ic.(*core.OutboundHandlerConfig))\n\t}\n\n\tfor serviceName, service := range c.Services {\n\t\tservicePackedConfig, err := loadHeterogeneousConfigFromRawJSON(\"service\", serviceName, service)\n\t\tif err != nil {\n\t\t\treturn nil, newError(fmt.Sprintf(\"failed to parse %v config in Services\", serviceName)).Base(err)\n\t\t}\n\t\tconfig.App = append(config.App, serial.ToTypedMessage(servicePackedConfig))\n\t}\n\treturn config, nil\n}\n\nfunc loadJSONConfig(data []byte) (*core.Config, error) {\n\trootConfig := &RootConfig{}\n\n\trootConfDecoder := json.NewDecoder(bytes.NewReader(data))\n\trootConfDecoder.DisallowUnknownFields()\n\terr := rootConfDecoder.Decode(rootConfig)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to load json\").Base(err)\n\t}\n\n\tbuildctx := cfgcommon.NewConfigureLoadingContext(context.Background())\n\n\tgeoloadername := platform.NewEnvFlag(\"v2ray.conf.geoloader\").GetValue(func() string {\n\t\treturn \"standard\"\n\t})\n\n\tif loader, err := geodata.GetGeoDataLoader(geoloadername); err == nil {\n\t\tcfgcommon.SetGeoDataLoader(buildctx, loader)\n\t} else {\n\t\treturn nil, newError(\"unable to create geo data loader \").Base(err)\n\t}\n\n\tmessage, err := rootConfig.BuildV5(buildctx)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to build config\").Base(err)\n\t}\n\treturn message.(*core.Config), nil\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/skeleton.go",
    "content": "package v5cfg\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/muxcfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/proxycfg\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/sniffer\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon/socketcfg\"\n)\n\ntype RootConfig struct {\n\tLogConfig    json.RawMessage            `json:\"log\"`\n\tDNSConfig    json.RawMessage            `json:\"dns\"`\n\tRouterConfig json.RawMessage            `json:\"router\"`\n\tInbounds     []InboundConfig            `json:\"inbounds\"`\n\tOutbounds    []OutboundConfig           `json:\"outbounds\"`\n\tServices     map[string]json.RawMessage `json:\"services\"`\n\tExtensions   []json.RawMessage          `json:\"extension\"`\n}\n\ntype InboundConfig struct {\n\tProtocol       string                  `json:\"protocol\"`\n\tPortRange      *cfgcommon.PortRange    `json:\"port\"`\n\tListenOn       *cfgcommon.Address      `json:\"listen\"`\n\tSettings       json.RawMessage         `json:\"settings\"`\n\tTag            string                  `json:\"tag\"`\n\tSniffingConfig *sniffer.SniffingConfig `json:\"sniffing\"`\n\tStreamSetting  *StreamConfig           `json:\"streamSettings\"`\n}\n\ntype OutboundConfig struct {\n\tProtocol       string                `json:\"protocol\"`\n\tSendThrough    *cfgcommon.Address    `json:\"sendThrough\"`\n\tTag            string                `json:\"tag\"`\n\tSettings       json.RawMessage       `json:\"settings\"`\n\tStreamSetting  *StreamConfig         `json:\"streamSettings\"`\n\tProxySettings  *proxycfg.ProxyConfig `json:\"proxySettings\"`\n\tMuxSettings    *muxcfg.MuxConfig     `json:\"mux\"`\n\tDomainStrategy string                `json:\"domainStrategy\"`\n}\n\ntype StreamConfig struct {\n\tTransport         string                 `json:\"transport\"`\n\tTransportSettings json.RawMessage        `json:\"transportSettings\"`\n\tSecurity          string                 `json:\"security\"`\n\tSecuritySettings  json.RawMessage        `json:\"securitySettings\"`\n\tSocketSettings    socketcfg.SocketConfig `json:\"socketSettings\"`\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/stream.go",
    "content": "package v5cfg\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc (s StreamConfig) BuildV5(ctx context.Context) (proto.Message, error) {\n\tconfig := &internet.StreamConfig{}\n\n\tif s.Transport == \"\" {\n\t\ts.Transport = \"tcp\"\n\t}\n\tif s.Security == \"\" {\n\t\ts.Security = \"none\"\n\t}\n\n\tif s.TransportSettings == nil {\n\t\ts.TransportSettings = []byte(\"{}\")\n\t}\n\ttransportConfigPack, err := loadHeterogeneousConfigFromRawJSON(\"transport\", s.Transport, s.TransportSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to load transport config\").Base(err)\n\t}\n\n\tconfig.ProtocolName = s.Transport\n\tconfig.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{\n\t\tProtocolName: s.Transport,\n\t\tSettings:     serial.ToTypedMessage(transportConfigPack),\n\t})\n\n\tif s.Security != \"none\" {\n\t\tif s.SecuritySettings == nil {\n\t\t\ts.SecuritySettings = []byte(\"{}\")\n\t\t}\n\t\tsecurityConfigPack, err := loadHeterogeneousConfigFromRawJSON(\"security\", s.Security, s.SecuritySettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to load security config\").Base(err)\n\t\t}\n\t\tsecurityConfigPackTypedMessage := serial.ToTypedMessage(securityConfigPack)\n\t\tconfig.SecurityType = serial.V2Type(securityConfigPackTypedMessage)\n\t\tconfig.SecuritySettings = append(config.SecuritySettings, securityConfigPackTypedMessage)\n\t}\n\n\tconfig.SocketSettings, err = s.SocketSettings.Build()\n\tif err != nil {\n\t\treturn nil, newError(\"unable to build socket config\").Base(err)\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "infra/conf/v5cfg/v5cfg.go",
    "content": "package v5cfg\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "infra/vformat/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"go/build\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n)\n\n// envFile returns the name of the Go environment configuration file.\n// Copy from https://github.com/golang/go/blob/c4f2a9788a7be04daf931ac54382fbe2cb754938/src/cmd/go/internal/cfg/cfg.go#L150-L166\nfunc envFile() (string, error) {\n\tif file := os.Getenv(\"GOENV\"); file != \"\" {\n\t\tif file == \"off\" {\n\t\t\treturn \"\", fmt.Errorf(\"GOENV=off\")\n\t\t}\n\t\treturn file, nil\n\t}\n\tdir, err := os.UserConfigDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif dir == \"\" {\n\t\treturn \"\", fmt.Errorf(\"missing user-config dir\")\n\t}\n\treturn filepath.Join(dir, \"go\", \"env\"), nil\n}\n\n// GetRuntimeEnv returns the value of runtime environment variable,\n// that is set by running following command: `go env -w key=value`.\nfunc GetRuntimeEnv(key string) (string, error) {\n\tfile, err := envFile()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif file == \"\" {\n\t\treturn \"\", fmt.Errorf(\"missing runtime env file\")\n\t}\n\tvar data []byte\n\tvar runtimeEnv string\n\tdata, readErr := os.ReadFile(file)\n\tif readErr != nil {\n\t\treturn \"\", readErr\n\t}\n\tenvStrings := strings.Split(string(data), \"\\n\")\n\tfor _, envItem := range envStrings {\n\t\tenvItem = strings.TrimSuffix(envItem, \"\\r\")\n\t\tenvKeyValue := strings.Split(envItem, \"=\")\n\t\tif len(envKeyValue) == 2 && strings.TrimSpace(envKeyValue[0]) == key {\n\t\t\truntimeEnv = strings.TrimSpace(envKeyValue[1])\n\t\t}\n\t}\n\treturn runtimeEnv, nil\n}\n\n// GetGOBIN returns GOBIN environment variable as a string. It will NOT be empty.\nfunc GetGOBIN() string {\n\t// The one set by user explicitly by `export GOBIN=/path` or `env GOBIN=/path command`\n\tGOBIN := os.Getenv(\"GOBIN\")\n\tif GOBIN == \"\" {\n\t\tvar err error\n\t\t// The one set by user by running `go env -w GOBIN=/path`\n\t\tGOBIN, err = GetRuntimeEnv(\"GOBIN\")\n\t\tif err != nil {\n\t\t\t// The default one that Golang uses\n\t\t\treturn filepath.Join(build.Default.GOPATH, \"bin\")\n\t\t}\n\t\tif GOBIN == \"\" {\n\t\t\treturn filepath.Join(build.Default.GOPATH, \"bin\")\n\t\t}\n\t\treturn GOBIN\n\t}\n\treturn GOBIN\n}\n\nfunc Run(binary string, args []string) ([]byte, error) {\n\tcmd := exec.Command(binary, args...)\n\tcmd.Env = append(cmd.Env, os.Environ()...)\n\toutput, cmdErr := cmd.CombinedOutput()\n\tif cmdErr != nil {\n\t\treturn nil, cmdErr\n\t}\n\treturn output, nil\n}\n\nfunc RunMany(binary string, args, files []string) {\n\tfmt.Println(\"Processing...\")\n\n\tmaxTasks := make(chan struct{}, runtime.NumCPU())\n\tfor _, file := range files {\n\t\tmaxTasks <- struct{}{}\n\t\tgo func(file string) {\n\t\t\toutput, err := Run(binary, append(args, file))\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t} else if len(output) > 0 {\n\t\t\t\tfmt.Println(string(output))\n\t\t\t}\n\t\t\t<-maxTasks\n\t\t}(file)\n\t}\n}\n\nfunc main() {\n\tpwd, err := os.Getwd()\n\tif err != nil {\n\t\tfmt.Println(\"Can not get current working directory.\")\n\t\tos.Exit(1)\n\t}\n\n\tGOBIN := GetGOBIN()\n\tbinPath := os.Getenv(\"PATH\")\n\tpathSlice := []string{pwd, GOBIN, binPath}\n\tbinPath = strings.Join(pathSlice, string(os.PathListSeparator))\n\tos.Setenv(\"PATH\", binPath)\n\n\tsuffix := \"\"\n\tif runtime.GOOS == \"windows\" {\n\t\tsuffix = \".exe\"\n\t}\n\tgofmt := \"gofmt\" + suffix\n\tgoimports := \"gci\" + suffix\n\n\tif gofmtPath, err := exec.LookPath(gofmt); err != nil {\n\t\tfmt.Println(\"Can not find\", gofmt, \"in system path or current working directory.\")\n\t\tos.Exit(1)\n\t} else {\n\t\tgofmt = gofmtPath\n\t}\n\n\tif goimportsPath, err := exec.LookPath(goimports); err != nil {\n\t\tfmt.Println(\"Can not find\", goimports, \"in system path or current working directory.\")\n\t\tos.Exit(1)\n\t} else {\n\t\tgoimports = goimportsPath\n\t}\n\n\trawFilesSlice := make([]string, 0, 1000)\n\twalkErr := filepath.Walk(\"./\", func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t\treturn err\n\t\t}\n\n\t\tif info.IsDir() {\n\t\t\treturn nil\n\t\t}\n\n\t\tdir := filepath.Dir(path)\n\t\tfilename := filepath.Base(path)\n\t\tif strings.HasSuffix(filename, \".go\") &&\n\t\t\t!strings.HasSuffix(filename, \".pb.go\") &&\n\t\t\t!strings.Contains(dir, filepath.Join(\"testing\", \"mocks\")) &&\n\t\t\t!strings.Contains(path, filepath.Join(\"main\", \"distro\", \"all\", \"all.go\")) {\n\t\t\trawFilesSlice = append(rawFilesSlice, path)\n\t\t}\n\n\t\treturn nil\n\t})\n\tif walkErr != nil {\n\t\tfmt.Println(walkErr)\n\t\tos.Exit(1)\n\t}\n\n\tgofmtArgs := []string{\n\t\t\"-s\", \"-l\", \"-e\", \"-w\",\n\t}\n\n\tgoimportsArgs := []string{\n\t\t\"write\",\n\t\t\"--NoInlineComments\",\n\t\t\"--NoPrefixComments\",\n\t\t\"--Section\", \"Standard\",\n\t\t\"--Section\", \"Default\",\n\t\t\"--Section\", \"pkgPrefix(github.com/v2fly/v2ray-core)\",\n\t}\n\n\tRunMany(gofmt, gofmtArgs, rawFilesSlice)\n\tRunMany(goimports, goimportsArgs, rawFilesSlice)\n\tfmt.Println(\"Do NOT forget to commit file changes.\")\n}\n"
  },
  {
    "path": "main/commands/all/api/api.go",
    "content": "package api\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n// CmdAPI calls an API in an V2Ray process\nvar CmdAPI = &base.Command{\n\tUsageLine: \"{{.Exec}} api\",\n\tShort:     \"call V2Ray API\",\n\tLong: `{{.Exec}} {{.LongName}} provides tools to manipulate V2Ray via its API.\n`,\n\tCommands: []*base.Command{\n\t\tcmdLog,\n\t\tcmdStats,\n\t\tcmdBalancerInfo,\n\t\tcmdBalancerOverride,\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/api/balancer_info.go",
    "content": "package api\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\trouterService \"github.com/v2fly/v2ray-core/v5/app/router/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n// TODO: support \"-json\" flag for json output\nvar cmdBalancerInfo = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api bi [--server=127.0.0.1:8080] [balancer]...\",\n\tShort:       \"balancer information\",\n\tLong: `\nGet information of specified balancers, including health, strategy \nand selecting. If no balancer tag specified, get information of \nall balancers.\n\n> Make sure you have \"RoutingService\" set in \"config.api.services\" \nof server config.\n\nArguments:\n\n\t-json\n\t\tUse json output.\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}} --server=127.0.0.1:8080 balancer1 balancer2\n`,\n\tRun: executeBalancerInfo,\n}\n\nfunc executeBalancerInfo(cmd *base.Command, args []string) {\n\tsetSharedFlags(cmd)\n\tcmd.Flag.Parse(args)\n\n\tconn, ctx, close := dialAPIServer()\n\tdefer close()\n\n\tclient := routerService.NewRoutingServiceClient(conn)\n\tr := &routerService.GetBalancerInfoRequest{Tag: cmd.Flag.Arg(0)}\n\tresp, err := client.GetBalancerInfo(ctx, r)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to get health information: %s\", err)\n\t}\n\n\tif apiJSON {\n\t\tshowJSONResponse(resp)\n\t\treturn\n\t}\n\n\tshowBalancerInfo(resp.Balancer)\n}\n\nfunc showBalancerInfo(b *routerService.BalancerMsg) {\n\tconst tableIndent = 4\n\tsb := new(strings.Builder)\n\t// Override\n\tif b.Override != nil {\n\t\tsb.WriteString(\"  - Selecting Override:\\n\")\n\t\tfor i, s := range []string{b.Override.Target} {\n\t\t\twriteRow(sb, tableIndent, i+1, []string{s}, nil)\n\t\t}\n\t}\n\t// Selects\n\tsb.WriteString(\"  - Selects:\\n\")\n\n\tfor i, o := range b.PrincipleTarget.Tag {\n\t\twriteRow(sb, tableIndent, i+1, []string{o}, nil)\n\t}\n\tos.Stdout.WriteString(sb.String())\n}\n\nfunc getColumnFormats(titles []string) []string {\n\tw := make([]string, len(titles))\n\tfor i, t := range titles {\n\t\tw[i] = fmt.Sprintf(\"%%-%ds \", len(t))\n\t}\n\treturn w\n}\n\nfunc writeRow(sb *strings.Builder, indent, index int, values, formats []string) {\n\tif index == 0 {\n\t\t// title line\n\t\tsb.WriteString(strings.Repeat(\" \", indent+4))\n\t} else {\n\t\tsb.WriteString(fmt.Sprintf(\"%s%-4d\", strings.Repeat(\" \", indent), index))\n\t}\n\tfor i, v := range values {\n\t\tformat := \"%-14s\"\n\t\tif i < len(formats) {\n\t\t\tformat = formats[i]\n\t\t}\n\t\tsb.WriteString(fmt.Sprintf(format, v))\n\t}\n\tsb.WriteByte('\\n')\n}\n"
  },
  {
    "path": "main/commands/all/api/balancer_override.go",
    "content": "package api\n\nimport (\n\trouterService \"github.com/v2fly/v2ray-core/v5/app/router/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdBalancerOverride = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api bo [--server=127.0.0.1:8080] <-b balancer> outboundTag\",\n\tShort:       \"balancer override\",\n\tLong: `\nOverride a balancer's selection.\n\n> Make sure you have \"RoutingService\" set in \"config.api.services\" \nof server config.\n\nOnce a balancer's selection is overridden:\n\n- The balancer's selection result will always be outboundTag\n\nArguments:\n\n\t-b, -balancer <tag>\n\t\tTag of the target balancer. Required.\n\n\t-r, -remove\n\t\tRemove the override\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}} --server=127.0.0.1:8080 -b balancer tag\n    {{.Exec}} {{.LongName}} --server=127.0.0.1:8080 -b balancer -r\n`,\n\tRun: executeBalancerOverride,\n}\n\nfunc executeBalancerOverride(cmd *base.Command, args []string) {\n\tvar (\n\t\tbalancer string\n\t\tremove   bool\n\t)\n\tcmd.Flag.StringVar(&balancer, \"b\", \"\", \"\")\n\tcmd.Flag.StringVar(&balancer, \"balancer\", \"\", \"\")\n\tcmd.Flag.BoolVar(&remove, \"r\", false, \"\")\n\tcmd.Flag.BoolVar(&remove, \"remove\", false, \"\")\n\tsetSharedFlags(cmd)\n\tcmd.Flag.Parse(args)\n\n\tif balancer == \"\" {\n\t\tbase.Fatalf(\"balancer tag not specified\")\n\t}\n\n\tconn, ctx, close := dialAPIServer()\n\tdefer close()\n\n\tclient := routerService.NewRoutingServiceClient(conn)\n\ttarget := \"\"\n\tif !remove {\n\t\ttarget = cmd.Flag.Args()[0]\n\t}\n\tr := &routerService.OverrideBalancerTargetRequest{\n\t\tBalancerTag: balancer,\n\t\tTarget:      target,\n\t}\n\n\t_, err := client.OverrideBalancerTarget(ctx, r)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to override balancer: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/api/jsonv4/inbounds_add.go",
    "content": "package jsonv4\n\nimport (\n\t\"fmt\"\n\n\thandlerService \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/api\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/helpers\"\n)\n\nvar cmdAddInbounds = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api adi [--server=127.0.0.1:8080] [c1.json] [dir1]...\",\n\tShort:       \"add inbounds\",\n\tLong: `\nAdd inbounds to V2Ray.\n\n> Make sure you have \"HandlerService\" set in \"config.api.services\" \nof server config.\n\nArguments:\n\n\t-format <format>\n\t\tThe input format.\n\t\tAvailable values: \"auto\", \"json\", \"toml\", \"yaml\"\n\t\tDefault: \"auto\"\n\n\t-r\n\t\tLoad folders recursively.\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}} dir\n    {{.Exec}} {{.LongName}} c1.json c2.yaml\n`,\n\tRun: executeAddInbounds,\n}\n\nfunc executeAddInbounds(cmd *base.Command, args []string) {\n\tapi.SetSharedFlags(cmd)\n\tapi.SetSharedConfigFlags(cmd)\n\tcmd.Flag.Parse(args)\n\tc, err := helpers.LoadConfig(cmd.Flag.Args(), api.APIConfigFormat, api.APIConfigRecursively)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to load: %s\", err)\n\t}\n\tif len(c.InboundConfigs) == 0 {\n\t\tbase.Fatalf(\"no valid inbound found\")\n\t}\n\n\tconn, ctx, close := api.DialAPIServer()\n\tdefer close()\n\n\tclient := handlerService.NewHandlerServiceClient(conn)\n\tfor _, in := range c.InboundConfigs {\n\t\tfmt.Println(\"adding:\", in.Tag)\n\t\ti, err := in.Build()\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to build conf: %s\", err)\n\t\t}\n\t\tr := &handlerService.AddInboundRequest{\n\t\t\tInbound: i,\n\t\t}\n\t\t_, err = client.AddInbound(ctx, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to add inbound: %s\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/api/jsonv4/inbounds_remove.go",
    "content": "package jsonv4\n\nimport (\n\t\"fmt\"\n\n\thandlerService \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/api\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/helpers\"\n)\n\nvar cmdRemoveInbounds = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api rmi [--server=127.0.0.1:8080] [c1.json] [dir1]...\",\n\tShort:       \"remove inbounds\",\n\tLong: `\nRemove inbounds from V2Ray.\n\n> Make sure you have \"HandlerService\" set in \"config.api.services\" \nof server config.\n\nArguments:\n\n\t-format <format>\n\t\tThe input format.\n\t\tAvailable values: \"auto\", \"json\", \"toml\", \"yaml\"\n\t\tDefault: \"auto\"\n\n\t-r\n\t\tLoad folders recursively.\n\n\t-tags\n\t\tThe input are tags instead of config files\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}} dir\n    {{.Exec}} {{.LongName}} c1.json c2.yaml\n    {{.Exec}} {{.LongName}} -tags tag1 tag2\n`,\n\tRun: executeRemoveInbounds,\n}\n\nfunc executeRemoveInbounds(cmd *base.Command, args []string) {\n\tapi.SetSharedFlags(cmd)\n\tapi.SetSharedConfigFlags(cmd)\n\tisTags := cmd.Flag.Bool(\"tags\", false, \"\")\n\tcmd.Flag.Parse(args)\n\n\tvar tags []string\n\tif *isTags {\n\t\ttags = cmd.Flag.Args()\n\t} else {\n\t\tc, err := helpers.LoadConfig(cmd.Flag.Args(), api.APIConfigFormat, api.APIConfigRecursively)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to load: %s\", err)\n\t\t}\n\t\ttags = make([]string, 0)\n\t\tfor _, c := range c.InboundConfigs {\n\t\t\ttags = append(tags, c.Tag)\n\t\t}\n\t}\n\tif len(tags) == 0 {\n\t\tbase.Fatalf(\"no inbound to remove\")\n\t}\n\n\tconn, ctx, close := api.DialAPIServer()\n\tdefer close()\n\n\tclient := handlerService.NewHandlerServiceClient(conn)\n\tfor _, tag := range tags {\n\t\tfmt.Println(\"removing:\", tag)\n\t\tr := &handlerService.RemoveInboundRequest{\n\t\t\tTag: tag,\n\t\t}\n\t\t_, err := client.RemoveInbound(ctx, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to remove inbound: %s\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/api/jsonv4/init.go",
    "content": "package jsonv4\n\nimport \"github.com/v2fly/v2ray-core/v5/main/commands/all/api\"\n\nfunc init() {\n\tapi.CmdAPI.Commands = append(api.CmdAPI.Commands,\n\t\tcmdAddInbounds,\n\t\tcmdAddOutbounds,\n\t\tcmdRemoveInbounds,\n\t\tcmdRemoveOutbounds)\n}\n"
  },
  {
    "path": "main/commands/all/api/jsonv4/outbounds_add.go",
    "content": "package jsonv4\n\nimport (\n\t\"fmt\"\n\n\thandlerService \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/api\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/helpers\"\n)\n\nvar cmdAddOutbounds = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api ado [--server=127.0.0.1:8080] [c1.json] [dir1]...\",\n\tShort:       \"add outbounds\",\n\tLong: `\nAdd outbounds to V2Ray.\n\n> Make sure you have \"HandlerService\" set in \"config.api.services\" \nof server config.\n\nArguments:\n\n\t-format <format>\n\t\tThe input format.\n\t\tAvailable values: \"auto\", \"json\", \"toml\", \"yaml\"\n\t\tDefault: \"auto\"\n\n\t-r\n\t\tLoad folders recursively.\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}} dir\n    {{.Exec}} {{.LongName}} c1.json c2.yaml\n`,\n\tRun: executeAddOutbounds,\n}\n\nfunc executeAddOutbounds(cmd *base.Command, args []string) {\n\tapi.SetSharedFlags(cmd)\n\tapi.SetSharedConfigFlags(cmd)\n\tcmd.Flag.Parse(args)\n\tc, err := helpers.LoadConfig(cmd.Flag.Args(), api.APIConfigFormat, api.APIConfigRecursively)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to load: %s\", err)\n\t}\n\tif len(c.OutboundConfigs) == 0 {\n\t\tbase.Fatalf(\"no valid outbound found\")\n\t}\n\n\tconn, ctx, close := api.DialAPIServer()\n\tdefer close()\n\n\tclient := handlerService.NewHandlerServiceClient(conn)\n\tfor _, out := range c.OutboundConfigs {\n\t\tfmt.Println(\"adding:\", out.Tag)\n\t\to, err := out.Build()\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to build conf: %s\", err)\n\t\t}\n\t\tr := &handlerService.AddOutboundRequest{\n\t\t\tOutbound: o,\n\t\t}\n\t\t_, err = client.AddOutbound(ctx, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to add outbound: %s\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/api/jsonv4/outbounds_remove.go",
    "content": "package jsonv4\n\nimport (\n\t\"fmt\"\n\n\thandlerService \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/api\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/helpers\"\n)\n\nvar cmdRemoveOutbounds = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api rmo [--server=127.0.0.1:8080] [c1.json] [dir1]...\",\n\tShort:       \"remove outbounds\",\n\tLong: `\nRemove outbounds from V2Ray.\n\n> Make sure you have \"HandlerService\" set in \"config.api.services\" \nof server config.\n\nArguments:\n\n\t-format <format>\n\t\tThe input format.\n\t\tAvailable values: \"auto\", \"json\", \"toml\", \"yaml\"\n\t\tDefault: \"auto\"\n\n\t-r\n\t\tLoad folders recursively.\n\n\t-tags\n\t\tThe input are tags instead of config files\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}} dir\n    {{.Exec}} {{.LongName}} c1.json c2.yaml\n    {{.Exec}} {{.LongName}} -tags tag1 tag2\n`,\n\tRun: executeRemoveOutbounds,\n}\n\nfunc executeRemoveOutbounds(cmd *base.Command, args []string) {\n\tapi.SetSharedFlags(cmd)\n\tapi.SetSharedConfigFlags(cmd)\n\tisTags := cmd.Flag.Bool(\"tags\", false, \"\")\n\tcmd.Flag.Parse(args)\n\n\tvar tags []string\n\tif *isTags {\n\t\ttags = cmd.Flag.Args()\n\t} else {\n\t\tc, err := helpers.LoadConfig(cmd.Flag.Args(), api.APIConfigFormat, api.APIConfigRecursively)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to load: %s\", err)\n\t\t}\n\t\ttags = make([]string, 0)\n\t\tfor _, c := range c.OutboundConfigs {\n\t\t\ttags = append(tags, c.Tag)\n\t\t}\n\t}\n\tif len(tags) == 0 {\n\t\tbase.Fatalf(\"no outbound to remove\")\n\t}\n\n\tconn, ctx, close := api.DialAPIServer()\n\tdefer close()\n\n\tclient := handlerService.NewHandlerServiceClient(conn)\n\tfor _, tag := range tags {\n\t\tfmt.Println(\"removing:\", tag)\n\t\tr := &handlerService.RemoveOutboundRequest{\n\t\t\tTag: tag,\n\t\t}\n\t\t_, err := client.RemoveOutbound(ctx, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to remove outbound: %s\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/api/log.go",
    "content": "package api\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\n\tlogService \"github.com/v2fly/v2ray-core/v5/app/log/command\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdLog = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api log [--server=127.0.0.1:8080]\",\n\tShort:       \"log operations\",\n\tLong: `\nFollow and print logs from v2ray.\n\n> Make sure you have \"LoggerService\" set in \"config.api.services\" \nof server config.\n\n> It ignores -timeout flag while following logs\n\nArguments:\n\n\t-restart \n\t\tRestart the logger\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n    {{.Exec}} {{.LongName}}\n    {{.Exec}} {{.LongName}} --restart\n`,\n\tRun: executeLog,\n}\n\nfunc executeLog(cmd *base.Command, args []string) {\n\tvar restart bool\n\tcmd.Flag.BoolVar(&restart, \"restart\", false, \"\")\n\tsetSharedFlags(cmd)\n\tcmd.Flag.Parse(args)\n\n\tif restart {\n\t\trestartLogger()\n\t\treturn\n\t}\n\tfollowLogger()\n}\n\nfunc restartLogger() {\n\tconn, ctx, close := dialAPIServer()\n\tdefer close()\n\tclient := logService.NewLoggerServiceClient(conn)\n\tr := &logService.RestartLoggerRequest{}\n\t_, err := client.RestartLogger(ctx, r)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to restart logger: %s\", err)\n\t}\n}\n\nfunc followLogger() {\n\tconn, ctx, close := dialAPIServerWithoutTimeout()\n\tdefer close()\n\tclient := logService.NewLoggerServiceClient(conn)\n\tr := &logService.FollowLogRequest{}\n\tstream, err := client.FollowLog(ctx, r)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to follow logger: %s\", err)\n\t}\n\t// work with `v2ray api log | grep expr`\n\tlog.SetOutput(os.Stdout)\n\tfor {\n\t\tresp, err := stream.Recv()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to fetch log: %s\", err)\n\t\t}\n\t\tlog.Println(resp.Message)\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/api/shared.go",
    "content": "package api\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar (\n\tapiServerAddrPtr string\n\tapiTimeout       int\n\tapiJSON          bool\n\t// APIConfigFormat is an internal variable\n\tAPIConfigFormat string\n\t// APIConfigRecursively is an internal variable\n\tAPIConfigRecursively bool\n)\n\n// SetSharedFlags is an internal API\nfunc SetSharedFlags(cmd *base.Command) {\n\tsetSharedFlags(cmd)\n}\n\nfunc setSharedFlags(cmd *base.Command) {\n\tcmd.Flag.StringVar(&apiServerAddrPtr, \"s\", \"127.0.0.1:8080\", \"\")\n\tcmd.Flag.StringVar(&apiServerAddrPtr, \"server\", \"127.0.0.1:8080\", \"\")\n\tcmd.Flag.IntVar(&apiTimeout, \"t\", 3, \"\")\n\tcmd.Flag.IntVar(&apiTimeout, \"timeout\", 3, \"\")\n\tcmd.Flag.BoolVar(&apiJSON, \"json\", false, \"\")\n}\n\n// SetSharedConfigFlags is an internal API\nfunc SetSharedConfigFlags(cmd *base.Command) {\n\tsetSharedConfigFlags(cmd)\n}\n\nfunc setSharedConfigFlags(cmd *base.Command) {\n\tcmd.Flag.StringVar(&APIConfigFormat, \"format\", core.FormatAuto, \"\")\n\tcmd.Flag.BoolVar(&APIConfigRecursively, \"r\", false, \"\")\n}\n\n// SetSharedFlags is an internal API\nfunc DialAPIServer() (conn *grpc.ClientConn, ctx context.Context, close func()) {\n\treturn dialAPIServer()\n}\n\nfunc dialAPIServer() (conn *grpc.ClientConn, ctx context.Context, close func()) {\n\tctx, cancel := context.WithTimeout(context.Background(), time.Duration(apiTimeout)*time.Second)\n\tconn = dialAPIServerWithContext(ctx)\n\tclose = func() {\n\t\tcancel()\n\t\tconn.Close()\n\t}\n\treturn\n}\n\nfunc dialAPIServerWithoutTimeout() (conn *grpc.ClientConn, ctx context.Context, close func()) {\n\tctx = context.Background()\n\tconn = dialAPIServerWithContext(ctx)\n\tclose = func() {\n\t\tconn.Close()\n\t}\n\treturn\n}\n\nfunc dialAPIServerWithContext(ctx context.Context) (conn *grpc.ClientConn) {\n\tconn, err := grpc.DialContext(ctx, apiServerAddrPtr, grpc.WithInsecure(), grpc.WithBlock())\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to dial %s\", apiServerAddrPtr)\n\t}\n\treturn\n}\n\nfunc protoToJSONString(m proto.Message, prefix, indent string) (string, error) { // nolint: unparam\n\treturn strings.TrimSpace(protojson.MarshalOptions{Indent: indent}.Format(m)), nil\n}\n\nfunc showJSONResponse(m proto.Message) {\n\toutput, err := protoToJSONString(m, \"\", \"\")\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stdout, \"%v\\n\", m)\n\t\tbase.Fatalf(\"error encode json: %s\", err)\n\t}\n\tfmt.Println(output)\n}\n"
  },
  {
    "path": "main/commands/all/api/stats.go",
    "content": "package api\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\tstatsService \"github.com/v2fly/v2ray-core/v5/app/stats/command\"\n\t\"github.com/v2fly/v2ray-core/v5/common/units\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdStats = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} api stats [--server=127.0.0.1:8080] [pattern]...\",\n\tShort:       \"query statistics\",\n\tLong: `\nQuery statistics from V2Ray.\n\n> Make sure you have \"StatsService\" set in \"config.api.services\" \nof server config.\n\nArguments:\n\n\t-regexp\n\t\tThe patterns are using regexp.\n\n\t-reset\n\t\tReset counters to 0 after fetching their values.\n\n\t-runtime\n\t\tGet runtime statistics.\n\n\t-json\n\t\tUse json output.\n\n\t-s, -server <server:port>\n\t\tThe API server address. Default 127.0.0.1:8080\n\n\t-t, -timeout <seconds>\n\t\tTimeout seconds to call API. Default 3\n\nExample:\n\n\t{{.Exec}} {{.LongName}} -runtime\n\t{{.Exec}} {{.LongName}} node1\n\t{{.Exec}} {{.LongName}} -json node1 node2\n\t{{.Exec}} {{.LongName}} -regexp 'node1.+downlink'\n`,\n\tRun: executeStats,\n}\n\nfunc executeStats(cmd *base.Command, args []string) {\n\tsetSharedFlags(cmd)\n\tvar (\n\t\truntime bool\n\t\tregexp  bool\n\t\treset   bool\n\t)\n\tcmd.Flag.BoolVar(&runtime, \"runtime\", false, \"\")\n\tcmd.Flag.BoolVar(&regexp, \"regexp\", false, \"\")\n\tcmd.Flag.BoolVar(&reset, \"reset\", false, \"\")\n\tcmd.Flag.Parse(args)\n\tunnamed := cmd.Flag.Args()\n\tif runtime {\n\t\tgetRuntimeStats(apiJSON)\n\t\treturn\n\t}\n\tgetStats(unnamed, regexp, reset, apiJSON)\n}\n\nfunc getRuntimeStats(jsonOutput bool) {\n\tconn, ctx, close := dialAPIServer()\n\tdefer close()\n\n\tclient := statsService.NewStatsServiceClient(conn)\n\tr := &statsService.SysStatsRequest{}\n\tresp, err := client.GetSysStats(ctx, r)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to get sys stats: %s\", err)\n\t}\n\tif jsonOutput {\n\t\tshowJSONResponse(resp)\n\t\treturn\n\t}\n\tshowRuntimeStats(resp)\n}\n\nfunc showRuntimeStats(s *statsService.SysStatsResponse) {\n\tformats := []string{\"%-22s\", \"%-10s\"}\n\trows := [][]string{\n\t\t{\"Up time\", (time.Duration(s.Uptime) * time.Second).String()},\n\t\t{\"Memory obtained\", units.ByteSize(s.Sys).String()},\n\t\t{\"Number of goroutines\", fmt.Sprintf(\"%d\", s.NumGoroutine)},\n\t\t{\"Heap allocated\", units.ByteSize(s.Alloc).String()},\n\t\t{\"Live objects\", fmt.Sprintf(\"%d\", s.LiveObjects)},\n\t\t{\"Heap allocated total\", units.ByteSize(s.TotalAlloc).String()},\n\t\t{\"Heap allocate count\", fmt.Sprintf(\"%d\", s.Mallocs)},\n\t\t{\"Heap free count\", fmt.Sprintf(\"%d\", s.Frees)},\n\t\t{\"Number of GC\", fmt.Sprintf(\"%d\", s.NumGC)},\n\t\t{\"Time of GC pause\", (time.Duration(s.PauseTotalNs) * time.Nanosecond).String()},\n\t}\n\tsb := new(strings.Builder)\n\twriteRow(sb, 0, 0,\n\t\t[]string{\"Item\", \"Value\"},\n\t\tformats,\n\t)\n\tfor i, r := range rows {\n\t\twriteRow(sb, 0, i+1, r, formats)\n\t}\n\tos.Stdout.WriteString(sb.String())\n}\n\nfunc getStats(patterns []string, regexp, reset, jsonOutput bool) {\n\tconn, ctx, close := dialAPIServer()\n\tdefer close()\n\n\tclient := statsService.NewStatsServiceClient(conn)\n\tr := &statsService.QueryStatsRequest{\n\t\tPatterns: patterns,\n\t\tRegexp:   regexp,\n\t\tReset_:   reset,\n\t}\n\tresp, err := client.QueryStats(ctx, r)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to query stats: %s\", err)\n\t}\n\tif jsonOutput {\n\t\tshowJSONResponse(resp)\n\t\treturn\n\t}\n\tsort.Slice(resp.Stat, func(i, j int) bool {\n\t\treturn resp.Stat[i].Name < resp.Stat[j].Name\n\t})\n\tshowStats(resp.Stat)\n}\n\nfunc showStats(stats []*statsService.Stat) {\n\tif len(stats) == 0 {\n\t\treturn\n\t}\n\tformats := []string{\"%-12s\", \"%s\"}\n\tsum := int64(0)\n\tsb := new(strings.Builder)\n\tidx := 0\n\twriteRow(sb, 0, 0,\n\t\t[]string{\"Value\", \"Name\"},\n\t\tformats,\n\t)\n\tfor _, stat := range stats {\n\t\t// if stat.Value == 0 {\n\t\t// \tcontinue\n\t\t// }\n\t\tidx++\n\t\tsum += stat.Value\n\t\twriteRow(\n\t\t\tsb, 0, idx,\n\t\t\t[]string{units.ByteSize(stat.Value).String(), stat.Name},\n\t\t\tformats,\n\t\t)\n\t}\n\tsb.WriteString(\n\t\tfmt.Sprintf(\"\\nTotal: %s\\n\", units.ByteSize(sum)),\n\t)\n\tos.Stdout.WriteString(sb.String())\n}\n"
  },
  {
    "path": "main/commands/all/commands.go",
    "content": "package all\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/api\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n//go:generate go run v2ray.com/core/common/errors/errorgen\n\nfunc init() {\n\tbase.RootCommand.Commands = append(\n\t\tbase.RootCommand.Commands,\n\t\tapi.CmdAPI,\n\t\tcmdLove,\n\t\ttls.CmdTLS,\n\t\tcmdUUID,\n\t\tcmdVerify,\n\n\t\t// documents\n\t\tdocFormat,\n\t\tdocMerge,\n\t)\n}\n"
  },
  {
    "path": "main/commands/all/engineering/convertpb.go",
    "content": "package engineering\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar (\n\tconfigFiles          cmdarg.Arg\n\tconfigDirs           cmdarg.Arg\n\tconfigFormat         *string\n\tconfigDirRecursively *bool\n)\n\nfunc setConfigFlags(cmd *base.Command) {\n\tconfigFormat = cmd.Flag.String(\"format\", core.FormatAuto, \"\")\n\tconfigDirRecursively = cmd.Flag.Bool(\"r\", false, \"\")\n\n\tcmd.Flag.Var(&configFiles, \"config\", \"\")\n\tcmd.Flag.Var(&configFiles, \"c\", \"\")\n\tcmd.Flag.Var(&configDirs, \"confdir\", \"\")\n\tcmd.Flag.Var(&configDirs, \"d\", \"\")\n}\n\nvar cmdConvertPb = &base.Command{\n\tUsageLine:   \"{{.Exec}} engineering convertpb [-c config.json] [-d dir]\",\n\tCustomFlags: true,\n\tRun: func(cmd *base.Command, args []string) {\n\t\tsetConfigFlags(cmd)\n\t\tcmd.Flag.Parse(args)\n\t\tconfig, err := core.LoadConfig(*configFormat, configFiles)\n\t\tif err != nil {\n\t\t\tif len(configFiles) == 0 {\n\t\t\t\tbase.Fatalf(\"%s\", newError(\"failed to load config\").Base(err))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbase.Fatalf(\"%s\", newError(fmt.Sprintf(\"failed to load config: %s\", configFiles)).Base(err))\n\t\t\treturn\n\t\t}\n\t\tbytew, err := proto.Marshal(config)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", newError(\"failed to marshal config\").Base(err))\n\t\t\treturn\n\t\t}\n\t\tio.Copy(os.Stdout, bytes.NewReader(bytew))\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/engineering/encodedataurl.go",
    "content": "package engineering\n\nimport (\n\t\"flag\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/vincent-petithory/dataurl\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdEncodeDataURLContentType *string\n\nvar cmdEncodeDataURL = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering encodeDataURL\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tcmdEncodeDataURLContentType = fs.String(\"type\", \"application/vnd.v2ray.subscription-singular\", \"\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tcmd.Flag.Parse(args)\n\n\t\tcontent, err := io.ReadAll(os.Stdin)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tdataURL := dataurl.New(content, *cmdEncodeDataURLContentType)\n\t\tdataURL.WriteTo(os.Stdout)\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/engineering/engineering.go",
    "content": "package engineering\n\nimport \"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nvar cmdEngineering = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering\",\n\tCommands: []*base.Command{\n\t\tcmdConvertPb,\n\t\tcmdReversePb,\n\t\tcmdNonNativeLinkExtract,\n\t\tcmdNonNativeLinkExec,\n\t\tcmdSubscriptionEntriesExtract,\n\t\tcmdEncodeDataURL,\n\t},\n}\n\nfunc init() {\n\tbase.RegisterCommand(cmdEngineering)\n}\n\nfunc AddCommand(cmd *base.Command) {\n\tcmdEngineering.Commands = append(cmdEngineering.Commands, cmd)\n}\n"
  },
  {
    "path": "main/commands/all/engineering/errors.generated.go",
    "content": "package engineering\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "main/commands/all/engineering/generateRandomData/errors.generated.go",
    "content": "package generateRandomData\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "main/commands/all/engineering/generateRandomData/generateRandomData.go",
    "content": "package generateRandomData\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"flag\"\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nvar length *int\n\nvar cmdGenerateRandomData = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering generate-random-data\",\n\tShort:     \"generate random data and output as base64\",\n\tLong: `\nGenerate random data of specified length and output as base64 encoded string.\n\nUsage:\n\t{{.Exec}} engineering generate-random-data -length <bytes>\n\nOptions:\n\t-length <bytes>\n\t\tThe number of random bytes to generate (required)\n\nExample:\n\t{{.Exec}} engineering generate-random-data -length 32\n`,\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tlength = fs.Int(\"length\", 0, \"number of random bytes to generate\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\terr := cmd.Flag.Parse(args)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to parse flags: %v\", err)\n\t\t}\n\n\t\tif *length <= 0 {\n\t\t\tbase.Fatalf(\"length must be a positive integer, got: %d\", *length)\n\t\t}\n\n\t\t// Generate random data\n\t\trandomData := make([]byte, *length)\n\t\t_, err = rand.Read(randomData)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to generate random data: %v\", err)\n\t\t}\n\n\t\t// Encode to base64\n\t\tencoded := base64.StdEncoding.EncodeToString(randomData)\n\n\t\t// Output the result\n\t\tfmt.Println(encoded)\n\t},\n}\n\nfunc init() {\n\tengineering.AddCommand(cmdGenerateRandomData)\n}\n"
  },
  {
    "path": "main/commands/all/engineering/nonnativelinkexec.go",
    "content": "package engineering\n\nimport (\n\t\"bytes\"\n\t\"flag\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries/nonnative\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdNonNativeLinkExecInputName *string\n\nvar cmdNonNativeLinkExecTemplatePath *string\n\nvar cmdNonNativeLinkExec = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering nonnativelinkexec\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tcmdNonNativeLinkExecInputName = fs.String(\"name\", \"\", \"\")\n\t\tcmdNonNativeLinkExecTemplatePath = fs.String(\"templatePath\", \"\", \"path for template directory (WARNING: This will not stop templates from reading file outside this directory)\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tcmd.Flag.Parse(args)\n\n\t\tcontent, err := io.ReadAll(os.Stdin)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tflattenedLink := nonnative.ExtractAllValuesFromBytes(content)\n\n\t\tmatcher := nonnative.NewDefMatcher()\n\t\tif *cmdNonNativeLinkExecTemplatePath != \"\" {\n\t\t\tosFs := os.DirFS(*cmdNonNativeLinkExecTemplatePath)\n\t\t\terr = matcher.LoadDefinitions(osFs)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\terr = matcher.LoadEmbeddedDefinitions()\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t}\n\n\t\tspec, err := matcher.ExecuteNamed(flattenedLink, *cmdNonNativeLinkExecInputName)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tio.Copy(os.Stdout, bytes.NewReader(spec))\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/engineering/nonnativelinkextract.go",
    "content": "package engineering\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/entries/nonnative\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\ntype valueContainer struct {\n\tkey, value string\n}\n\ntype orderedValueContainer []valueContainer\n\nfunc (o *orderedValueContainer) Len() int {\n\treturn len(*o)\n}\n\nfunc (o *orderedValueContainer) Less(i, j int) bool {\n\treturn strings.Compare((*o)[i].key, (*o)[j].key) < 0\n}\n\nfunc (o *orderedValueContainer) Swap(i, j int) {\n\t(*o)[i], (*o)[j] = (*o)[j], (*o)[i]\n}\n\nvar cmdNonNativeLinkExtract = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering nonnativelinkextract\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tcontent, err := io.ReadAll(os.Stdin)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tflattenedLink := nonnative.ExtractAllValuesFromBytes(content)\n\t\tvar valueContainerOrdered orderedValueContainer\n\n\t\tfor key, value := range flattenedLink.Values {\n\t\t\tvalueContainerOrdered = append(valueContainerOrdered, valueContainer{key, value})\n\t\t}\n\t\tsort.Sort(&valueContainerOrdered)\n\t\tfor _, valueContainer := range valueContainerOrdered {\n\t\t\tio.WriteString(os.Stdout, fmt.Sprintf(\"%s=%s\\n\", valueContainer.key, valueContainer.value))\n\t\t}\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/engineering/reversepb.go",
    "content": "package engineering\n\nimport (\n\t\"bytes\"\n\t\"flag\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/jsonpb\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/v2jsonpb\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdReversePb = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering reversepb [-f format]\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tconfigFormat = fs.String(\"f\", \"v2jsonpb\", \"\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tcmd.Flag.Parse(args)\n\t\tconfigIn := bytes.NewBuffer(nil)\n\t\tio.Copy(configIn, os.Stdin)\n\t\tvar conf core.Config\n\t\tif err := proto.Unmarshal(configIn.Bytes(), &conf); err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tswitch *configFormat {\n\t\tcase \"jsonpb\":\n\t\t\tif err := jsonpb.DumpJSONPb(&conf, os.Stdout); err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\tcase \"v2jsonpb\":\n\t\t\tif value, err := v2jsonpb.DumpV2JsonPb(&conf); err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t} else {\n\t\t\t\tio.Copy(os.Stdout, bytes.NewReader(value))\n\t\t\t}\n\t\t}\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/engineering/subscriptionEntriesExtract.go",
    "content": "package engineering\n\nimport (\n\t\"archive/zip\"\n\t\"encoding/json\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"golang.org/x/crypto/sha3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/app/subscription/containers\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdSubscriptionEntriesExtractInputName *string\n\nvar cmdSubscriptionEntriesExtract = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering subscriptionEntriesExtract\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tcmdSubscriptionEntriesExtractInputName = fs.String(\"input\", \"\", \"\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tcmd.Flag.Parse(args)\n\t\tinputReader := os.Stdin\n\t\tif *cmdSubscriptionEntriesExtractInputName != \"\" {\n\t\t\tfile, err := os.Open(*cmdSubscriptionEntriesExtractInputName)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t\tinputReader = file\n\t\t\tdefer file.Close()\n\t\t}\n\t\tcontent, err := io.ReadAll(inputReader)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tparsed, err := containers.TryAllParsers(content, \"\")\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%s\", err)\n\t\t}\n\t\tzipWriter := zip.NewWriter(os.Stdout)\n\t\t{\n\t\t\twriter, err := zipWriter.Create(\"meta.json\")\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t\terr = json.NewEncoder(writer).Encode(parsed.Metadata)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t}\n\t\tfor k, entry := range parsed.ServerSpecs {\n\t\t\thash := sha3.Sum256(entry.Content)\n\t\t\tfileName := fmt.Sprintf(\"entry_%v_%x\", k, hash[:8])\n\t\t\twriter, err := zipWriter.Create(fileName)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t\t_, err = writer.Write(entry.Content)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"%s\", err)\n\t\t\t}\n\t\t}\n\t\tzipWriter.Close()\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/errors.generated.go",
    "content": "package all\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "main/commands/all/format_doc.go",
    "content": "package all\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar docFormat = &base.Command{\n\tUsageLine: \"{{.Exec}} format-loader\",\n\tShort:     \"config formats and loading\",\n\tLong: `\n{{.Exec}} is equipped with multiple loaders to support different \nconfig formats:\n\n\t* auto\n\t  The default loader, supports all formats listed below, with \n\t  format detecting, and mixed fomats support.\n\n\t* json (.json, .jsonc)\n\t  The json loader, multiple files support, mergeable.\n\n\t* toml (.toml)\n\t  The toml loader, multiple files support, mergeable.\n\n\t* yaml (.yml, .yaml)\n\t  The yaml loader, multiple files support, mergeable.\n\n\t* protobuf / pb (.pb)\n\t  Single file support, unmergeable.\n\n\nThe following explains how format loaders behaves.\n\nExamples:\n\n\t{{.Exec}} run -d dir                        (1)\n\t{{.Exec}} run -c c1.json -c c2.yaml         (2)\n\t{{.Exec}} run -format=json -d dir           (3)\n\t{{.Exec}} test -c c1.yml -c c2.pb           (4)\n\t{{.Exec}} test -format=pb -d dir            (5)\n\t{{.Exec}} test -format=protobuf -c c1.json  (6)\n\n(1) Load all supported files in the \"dir\".\n(2) JSON and YAML are merged and loaded.\n(3) Load all JSON files in the \"dir\".\n(4) Goes error since .pb is not mergeable to others\n(5) Works only when single .pb file found, if not, failed due to \n\tunmergeable.\n(6) Force load \"c1.json\" as protobuf, no matter its extension.\n`,\n}\n"
  },
  {
    "path": "main/commands/all/jsonv4/convert.go",
    "content": "package jsonv4\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/pelletier/go-toml\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"gopkg.in/yaml.v3\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/jsonpb\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/merge\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/v2jsonpb\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/helpers\"\n)\n\nvar cmdConvert = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} convert [c1.json] [<url>.json] [dir1] ...\",\n\tShort:       \"convert config files\",\n\tLong: `\nConvert config files between different formats. Files are merged \nbefore convert.\n\nArguments:\n\n\t-i, -input <format>\n\t\tThe input format.\n\t\tAvailable values: \"auto\", \"json\", \"toml\", \"yaml\"\n\t\tDefault: \"auto\"\n\n\t-o, -output <format>\n\t\tThe output format\n\t\tAvailable values: \"json\", \"toml\", \"yaml\", \"protobuf\" / \"pb\"\n\t\tDefault: \"json\"\n\n\t-r\n\t\tLoad folders recursively.\n\nExamples:\n\n\t{{.Exec}} {{.LongName}} -output=protobuf \"path/to/dir\"   (1)\n\t{{.Exec}} {{.LongName}} -o=yaml config.toml              (2)\n\t{{.Exec}} {{.LongName}} c1.json c2.json                  (3)\n\t{{.Exec}} {{.LongName}} -output=yaml c1.yaml <url>.yaml  (4)\n\n(1) Merge all supported files in dir and convert to protobuf\n(2) Convert toml to yaml\n(3) Merge json files\n(4) Merge yaml files\n\nUse \"{{.Exec}} help config-merge\" for more information about merge.\n`,\n}\n\nfunc init() {\n\tcmdConvert.Run = executeConvert // break init loop\n}\n\nvar (\n\tinputFormat        string\n\toutputFormat       string\n\tconfDirRecursively bool\n)\n\nfunc setConfArgs(cmd *base.Command) {\n\tcmd.Flag.StringVar(&inputFormat, \"input\", core.FormatAuto, \"\")\n\tcmd.Flag.StringVar(&inputFormat, \"i\", core.FormatAuto, \"\")\n\tcmd.Flag.StringVar(&outputFormat, \"output\", \"json\", \"\")\n\tcmd.Flag.StringVar(&outputFormat, \"o\", \"json\", \"\")\n\tcmd.Flag.BoolVar(&confDirRecursively, \"r\", false, \"\")\n}\n\nfunc executeConvert(cmd *base.Command, args []string) {\n\tsetConfArgs(cmd)\n\tcmd.Flag.Parse(args)\n\tinputFormat = strings.ToLower(inputFormat)\n\toutputFormat = strings.ToLower(outputFormat)\n\n\tinputFormatMerge := inputFormat\n\tif inputFormat == \"jsonv5\" {\n\t\tinputFormatMerge = \"json\"\n\t}\n\tm, err := helpers.LoadConfigToMap(cmd.Flag.Args(), inputFormatMerge, confDirRecursively)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to merge: %s\", err)\n\t}\n\terr = merge.ApplyRules(m)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to apply merge rules: %s\", err)\n\t}\n\n\tvar out []byte\n\tswitch outputFormat {\n\tcase core.FormatJSON:\n\t\tout, err = json.Marshal(m)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to convert to json: %s\", err)\n\t\t}\n\tcase core.FormatTOML:\n\t\tout, err = toml.Marshal(m)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to convert to toml: %s\", err)\n\t\t}\n\tcase core.FormatYAML:\n\t\tout, err = yaml.Marshal(m)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to convert to yaml: %s\", err)\n\t\t}\n\tcase core.FormatProtobuf, core.FormatProtobufShort:\n\t\tdata, err := json.Marshal(m)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to marshal json: %s\", err)\n\t\t}\n\t\tr := bytes.NewReader(data)\n\t\tpbConfig, err := core.LoadConfig(inputFormat, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%v\", err.Error())\n\t\t}\n\t\tout, err = proto.Marshal(pbConfig)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to convert to protobuf: %s\", err)\n\t\t}\n\tcase jsonpb.FormatProtobufJSONPB:\n\t\tdata, err := json.Marshal(m)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to marshal json: %s\", err)\n\t\t}\n\t\tr := bytes.NewReader(data)\n\t\tpbConfig, err := core.LoadConfig(inputFormat, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%v\", err.Error())\n\t\t}\n\t\tw := bytes.NewBuffer(nil)\n\t\terr = jsonpb.DumpJSONPb(pbConfig, w)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%v\", err.Error())\n\t\t}\n\t\tout = w.Bytes()\n\tcase v2jsonpb.FormatProtobufV2JSONPB:\n\t\tdata, err := json.Marshal(m)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to marshal json: %s\", err)\n\t\t}\n\t\tr := bytes.NewReader(data)\n\t\tpbConfig, err := core.LoadConfig(inputFormat, r)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%v\", err.Error())\n\t\t}\n\t\tout, err = v2jsonpb.DumpV2JsonPb(pbConfig)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"%v\", err.Error())\n\t\t}\n\tdefault:\n\t\tbase.Errorf(\"invalid output format: %s\", outputFormat)\n\t\tbase.Errorf(\"Run '%s help %s' for details.\", base.CommandEnv.Exec, cmd.LongName())\n\t\tbase.Exit()\n\t}\n\n\tif _, err := os.Stdout.Write(out); err != nil {\n\t\tbase.Fatalf(\"failed to write stdout: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/jsonv4/init.go",
    "content": "package jsonv4\n\nimport \"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\nfunc init() {\n\tbase.RegisterCommand(cmdConvert)\n}\n"
  },
  {
    "path": "main/commands/all/love.go",
    "content": "package all\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdLove = &base.Command{\n\tUsageLine: \"{{.Exec}} lovevictoria\",\n\tShort:     \"\", // set Short to \"\" hides the command\n\tLong:      \"\",\n\tRun:       executeLove,\n}\n\nfunc executeLove(cmd *base.Command, args []string) {\n\tconst content = \"H4sIAAAAAAAC/4SVMaskNwzH+/kUW6izcSthMGrcqLhVk0rdQS5cSMg7Xu4S0vizB8meZd57M3ta2GHX/ukvyZZmY2ZKDMzCzJyY5yOlxKII1omsf+qkBiiC6WhbYsbkjDAfySQsJqD3jtrD0EBM3sBHzG3kUsrglIQREXonpd47kYIi4AHmgI9Wcq2jlJITC6JZJ+v3ECYzBMAHyYm392yuY4zWsjACmHZSh6l3A0JETzGlWZqDsnArpTg62mhJONhOdO90p97V1BAnteoaOcuummtrrtuERQwUiJwP8a4KGKcyxdOCw1spOY+WHueFqmakAIgUSSuhwKNgobxKXSLbtg6r5cFmBiAeF6yCkYycmv+BiCIiW8ScHa3DgxAuZQbRhFNrLTFo96RBmx9jKWWG5nBsjyJzuIkftUblonppZU5t5LzwIks5L1a4lijagQxLokbIYwxfytNDC+XQqrWW9fzAunhqh5/Tg8PuaMw0d/Tcw3iDO81bHfWM/AnutMh2xqSUntMzd3wHDy9iHMQz8bmUZYvqedTJ5GgOnrNt7FIbSlwXE3wDI19n/KA38MsLaP4l89b5F8AV3ESOMIEhIBgezHBc0H6xV9KbaXwMvPcNvIHcC0C7UPZQx4JVTb35/AneSQq+bAYXsBmY7TCRupF2NTdVm/+ch22xa0pvRERKqt1oxj9DUbXzU84Gvj5hc5a81SlAUwMwgEs4T9+7sg9lb9h+908MWiKV8xtWciVTmnB3tivRjNerfXdxpfEBbq2NUvLMM5R9NLuyQg8nXT0PIh1xPd/wrcV49oJ6zbZaPlj2V87IY9T3F2XCOcW2MbZyZd49H+9m81E1N9SxlU+ff/1y+/f3719vf7788+Ugv/ffbMIH7ZNj0dsT4WMHHwLPu/Rp2O75uh99AK+N2xn7ZHq1OK6gczkN+9ngdOl1Qvki5xwSR8vFX6D+9vXA97B/+fr5rz9u/738uP328urP19vfP759e3n9Xs6jamvqlfJ/AAAA//+YAMZjDgkAAA==\"\n\tc, err := base64.StdEncoding.DecodeString(content)\n\tcommon.Must(err)\n\treader, err := gzip.NewReader(bytes.NewBuffer(c))\n\tcommon.Must(err)\n\tb := make([]byte, 4096)\n\tnBytes, _ := reader.Read(b)\n\n\tbb := bytes.NewBuffer(b[:nBytes])\n\tscanner := bufio.NewScanner(bb)\n\tfor scanner.Scan() {\n\t\ts := scanner.Text()\n\t\tfmt.Print(s + platform.LineSeparator())\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/merge_doc.go",
    "content": "package all\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar docMerge = &base.Command{\n\tUsageLine: \"{{.Exec}} config-merge\",\n\tShort:     \"config merge logic\",\n\tLong: `\nMerging of config files is applied in following commands:\n\n\t{{.Exec}} run -c c1.json -c c2.json ...\n\t{{.Exec}} test -c c1.yaml -c c2.yaml ...\n\t{{.Exec}} convert c1.json dir1 ...\n\t{{.Exec}} api ado c1.json dir1 ...\n\t{{.Exec}} api rmi c1.json dir1 ...\n\t... and more ...\n\nSupport of toml and yaml is implemented by converting them to json, \nboth merge and load. So we take json as example here.\n\nSuppose we have 2 JSON files,\n\nThe 1st one:\n\n\t{\n\t  \"log\": {\"access\": \"some_value\", \"loglevel\": \"debug\"},\n\t  \"inbounds\": [{\"tag\": \"in-1\"}],\n\t  \"outbounds\": [{\"_priority\": 100, \"tag\": \"out-1\"}],\n\t  \"routing\": {\"rules\": [\n\t\t{\"_tag\":\"default_route\",\"inboundTag\":[\"in-1\"],\"outboundTag\":\"out-1\"}\n\t  ]}\n\t}\n\nThe 2nd one:\n\n\t{\n\t  \"log\": {\"loglevel\": \"error\"},\n\t  \"inbounds\": [{\"tag\": \"in-2\"}],\n\t  \"outbounds\": [{\"_priority\": -100, \"tag\": \"out-2\"}],\n\t  \"routing\": {\"rules\": [\n\t\t{\"inboundTag\":[\"in-2\"],\"outboundTag\":\"out-2\"},\n\t\t{\"_tag\":\"default_route\",\"inboundTag\":[\"in-1.1\"],\"outboundTag\":\"out-1.1\"}\n\t  ]}\n\t}\n\nOutput:\n\n\t{\n\t  // loglevel is overwritten\n\t  \"log\": {\"access\": \"some_value\", \"loglevel\": \"error\"},\n\t  \"inbounds\": [{\"tag\": \"in-1\"}, {\"tag\": \"in-2\"}],\n\t  \"outbounds\": [\n\t\t{\"tag\": \"out-2\"}, // note the order is affected by priority\n\t\t{\"tag\": \"out-1\"}\n\t  ],\n\t  \"routing\": {\"rules\": [\n\t\t// note 3 rules are merged into 2, and outboundTag is overwritten,\n\t\t// because 2 of them has same tag\n\t\t{\"inboundTag\":[\"in-1\",\"in-1.1\"],\"outboundTag\":\"out-1.1\"}\n\t\t{\"inboundTag\":[\"in-2\"],\"outboundTag\":\"out-2\"}\n\t  ]}\n\t}\n\nExplained: \n\n- Simple values (string, number, boolean) are overwritten, others are merged\n- Elements with same \"tag\" (or \"_tag\") in an array will be merged\n- Add \"_priority\" property to array elements will help sort the array\n`,\n}\n"
  },
  {
    "path": "main/commands/all/tls/cert.go",
    "content": "package tls\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"encoding/json\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n// cmdCert is the tls cert command\nvar cmdCert = &base.Command{\n\tUsageLine: \"{{.Exec}} tls cert [--ca] [--domain=v2fly.org] [--expire=240h]\",\n\tShort:     \"Generate TLS certificates\",\n\tLong: `\nGenerate TLS certificates.\n\nArguments:\n\n\t-domain <domain_name>\n\t\tThe domain name for the certificate.\n\n\t-name <common name>\n\t\tThe common name of this certificate\n\n\t-org <organization>\n\t\tThe organization name for the certificate.\n\n\t-ca \n\t\tThe certificate is a CA\n\n\t-json \n\t\tTo output certificate to JSON\n\n\t-file <path>\n\t\tThe certificate path to save.\n\n\t-expire <days>\n\t\tExpire days of the certificate. Default 90 days.\n`,\n}\n\nfunc init() {\n\tcmdCert.Run = executeCert // break init loop\n}\n\nvar (\n\tcertDomainNames stringList\n\t_               = func() bool {\n\t\tcmdCert.Flag.Var(&certDomainNames, \"domain\", \"Domain name for the certificate\")\n\t\treturn true\n\t}()\n\n\tcertCommonName   = cmdCert.Flag.String(\"name\", \"V2Ray Inc\", \"\")\n\tcertOrganization = cmdCert.Flag.String(\"org\", \"V2Ray Inc\", \"\")\n\tcertIsCA         = cmdCert.Flag.Bool(\"ca\", false, \"\")\n\tcertJSONOutput   = cmdCert.Flag.Bool(\"json\", true, \"\")\n\tcertFileOutput   = cmdCert.Flag.String(\"file\", \"\", \"\")\n\tcertExpire       = cmdCert.Flag.Uint(\"expire\", 90, \"\")\n)\n\nfunc executeCert(cmd *base.Command, args []string) {\n\tvar opts []cert.Option\n\tif *certIsCA {\n\t\topts = append(opts, cert.Authority(*certIsCA))\n\t\topts = append(opts, cert.KeyUsage(x509.KeyUsageCertSign|x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature))\n\t}\n\n\topts = append(opts, cert.NotAfter(time.Now().Add(time.Duration(*certExpire)*time.Hour*24)))\n\topts = append(opts, cert.CommonName(*certCommonName))\n\tif len(certDomainNames) > 0 {\n\t\topts = append(opts, cert.DNSNames(certDomainNames...))\n\t}\n\topts = append(opts, cert.Organization(*certOrganization))\n\n\tcert, err := cert.Generate(nil, opts...)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to generate TLS certificate: %s\", err)\n\t}\n\n\tif *certJSONOutput {\n\t\tprintJSON(cert)\n\t}\n\n\tif len(*certFileOutput) > 0 {\n\t\tif err := printFile(cert, *certFileOutput); err != nil {\n\t\t\tbase.Fatalf(\"failed to save file: %s\", err)\n\t\t}\n\t}\n}\n\nfunc printJSON(certificate *cert.Certificate) {\n\tcertPEM, keyPEM := certificate.ToPEM()\n\tjCert := &jsonCert{\n\t\tCertificate: strings.Split(strings.TrimSpace(string(certPEM)), \"\\n\"),\n\t\tKey:         strings.Split(strings.TrimSpace(string(keyPEM)), \"\\n\"),\n\t}\n\tcontent, err := json.MarshalIndent(jCert, \"\", \"  \")\n\tcommon.Must(err)\n\tos.Stdout.Write(content)\n\tos.Stdout.WriteString(\"\\n\")\n}\n\nfunc writeFile(content []byte, name string) error {\n\tf, err := os.Create(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\treturn common.Error2(f.Write(content))\n}\n\nfunc printFile(certificate *cert.Certificate, name string) error {\n\tcertPEM, keyPEM := certificate.ToPEM()\n\treturn task.Run(context.Background(), func() error {\n\t\treturn writeFile(certPEM, name+\"_cert.pem\")\n\t}, func() error {\n\t\treturn writeFile(keyPEM, name+\"_key.pem\")\n\t})\n}\n\ntype stringList []string\n\nfunc (l *stringList) String() string {\n\treturn \"String list\"\n}\n\nfunc (l *stringList) Set(v string) error {\n\tif v == \"\" {\n\t\tbase.Fatalf(\"empty value\")\n\t}\n\t*l = append(*l, v)\n\treturn nil\n}\n\ntype jsonCert struct {\n\tCertificate []string `json:\"certificate\"`\n\tKey         []string `json:\"key\"`\n}\n"
  },
  {
    "path": "main/commands/all/tls/chainhash.go",
    "content": "package tls\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\tv2tls \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nvar cmdChainHash = &base.Command{\n\tUsageLine: \"{{.Exec}} tls certChainHash [--cert <cert.pem>]\",\n\tShort:     \"Generate certificate chain hash for given certificate bundle\",\n}\n\nfunc init() {\n\tcmdChainHash.Run = executeChainHash // break init loop\n}\n\nvar certFile = cmdChainHash.Flag.String(\"cert\", \"cert.pem\", \"\")\n\nfunc executeChainHash(cmd *base.Command, args []string) {\n\tif len(*certFile) == 0 {\n\t\tbase.Fatalf(\"cert file not specified\")\n\t}\n\tcertContent, err := os.ReadFile(*certFile)\n\tif err != nil {\n\t\tbase.Fatalf(\"Failed to read cert file: %s\", err)\n\t\treturn\n\t}\n\n\tcertChainHashB64 := v2tls.CalculatePEMCertChainSHA256Hash(certContent)\n\tfmt.Println(certChainHashB64)\n}\n"
  },
  {
    "path": "main/commands/all/tls/ping.go",
    "content": "package tls\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\tv2tls \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n// cmdPing is the tls ping command\nvar cmdPing = &base.Command{\n\tUsageLine: \"{{.Exec}} tls ping [-ip <ip>] <domain>\",\n\tShort:     \"ping the domain with TLS handshake\",\n\tLong: `\nPing the domain with TLS handshake.\n\nArguments:\n\n\t-ip <ip>\n\t\tThe IP address of the domain.\n`,\n}\n\nfunc init() {\n\tcmdPing.Run = executePing // break init loop\n}\n\nvar pingIPStr = cmdPing.Flag.String(\"ip\", \"\", \"\")\n\nfunc executePing(cmd *base.Command, args []string) {\n\tif cmdPing.Flag.NArg() < 1 {\n\t\tbase.Fatalf(\"domain not specified\")\n\t}\n\n\tdomain := cmdPing.Flag.Arg(0)\n\tfmt.Println(\"Tls ping: \", domain)\n\n\tvar ip net.IP\n\tif len(*pingIPStr) > 0 {\n\t\tv := net.ParseIP(*pingIPStr)\n\t\tif v == nil {\n\t\t\tbase.Fatalf(\"invalid IP: %s\", *pingIPStr)\n\t\t}\n\t\tip = v\n\t} else {\n\t\tv, err := net.ResolveIPAddr(\"ip\", domain)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"Failed to resolve IP: %s\", err)\n\t\t}\n\t\tip = v.IP\n\t}\n\tfmt.Println(\"Using IP: \", ip.String())\n\n\tfmt.Println(\"-------------------\")\n\tfmt.Println(\"Pinging without SNI\")\n\t{\n\t\ttcpConn, err := net.DialTCP(\"tcp\", nil, &net.TCPAddr{IP: ip, Port: 443})\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"Failed to dial tcp: %s\", err)\n\t\t}\n\t\ttlsConn := tls.Client(tcpConn, &tls.Config{\n\t\t\tInsecureSkipVerify: true,\n\t\t\tNextProtos:         []string{\"http/1.1\"},\n\t\t\tMaxVersion:         tls.VersionTLS12,\n\t\t\tMinVersion:         tls.VersionTLS12,\n\t\t\t// Do not release tool before v5's refactor\n\t\t\t// VerifyPeerCertificate: showCert(),\n\t\t})\n\t\terr = tlsConn.Handshake()\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Handshake failure: \", err)\n\t\t} else {\n\t\t\tfmt.Println(\"Handshake succeeded\")\n\t\t\tprintCertificates(tlsConn.ConnectionState().PeerCertificates)\n\t\t}\n\t\ttlsConn.Close()\n\t}\n\n\tfmt.Println(\"-------------------\")\n\tfmt.Println(\"Pinging with SNI\")\n\t{\n\t\ttcpConn, err := net.DialTCP(\"tcp\", nil, &net.TCPAddr{IP: ip, Port: 443})\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"Failed to dial tcp: %s\", err)\n\t\t}\n\t\ttlsConn := tls.Client(tcpConn, &tls.Config{\n\t\t\tServerName: domain,\n\t\t\tNextProtos: []string{\"http/1.1\"},\n\t\t\tMaxVersion: tls.VersionTLS12,\n\t\t\tMinVersion: tls.VersionTLS12,\n\t\t\t// Do not release tool before v5's refactor\n\t\t\t// VerifyPeerCertificate: showCert(),\n\t\t})\n\t\terr = tlsConn.Handshake()\n\t\tif err != nil {\n\t\t\tfmt.Println(\"handshake failure: \", err)\n\t\t} else {\n\t\t\tfmt.Println(\"handshake succeeded\")\n\t\t\tprintCertificates(tlsConn.ConnectionState().PeerCertificates)\n\t\t}\n\t\ttlsConn.Close()\n\t}\n\n\tfmt.Println(\"Tls ping finished\")\n}\n\nfunc printCertificates(certs []*x509.Certificate) {\n\tfor _, cert := range certs {\n\t\tif len(cert.DNSNames) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Println(\"Allowed domains: \", cert.DNSNames)\n\t}\n}\n\nfunc showCert() func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {\n\treturn func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {\n\t\thash := v2tls.GenerateCertChainHash(rawCerts)\n\t\tfmt.Println(\"Certificate Chain Hash: \", base64.StdEncoding.EncodeToString(hash))\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "main/commands/all/tls/tls.go",
    "content": "package tls\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n// CmdTLS holds all tls sub commands\nvar CmdTLS = &base.Command{\n\tUsageLine: \"{{.Exec}} tls\",\n\tShort:     \"TLS tools\",\n\tLong: `{{.Exec}} {{.LongName}} provides tools for TLS.\n\t`,\n\n\tCommands: []*base.Command{\n\t\tcmdCert,\n\t\tcmdPing,\n\t\tcmdChainHash,\n\t},\n}\n"
  },
  {
    "path": "main/commands/all/uuid.go",
    "content": "package all\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdUUID = &base.Command{\n\tUsageLine: \"{{.Exec}} uuid\",\n\tShort:     \"generate new UUID\",\n\tLong: `Generate new UUID.\n`,\n\tRun: executeUUID,\n}\n\nfunc executeUUID(cmd *base.Command, args []string) {\n\tu := uuid.New()\n\tfmt.Println(u.String())\n}\n"
  },
  {
    "path": "main/commands/all/verify.go",
    "content": "package all\n\nimport (\n\t\"os\"\n\n\t\"github.com/v2fly/VSign/signerVerify\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\nvar cmdVerify = &base.Command{\n\tUsageLine: \"{{.Exec}} verify [--sig=sig-file] file\",\n\tShort:     \"verify if a binary is officially signed\",\n\tLong: `\nVerify if a binary is officially signed.\n\nArguments:\n\n\t-sig <signature_file>\n\t\tThe path to the signature file\n`,\n}\n\nfunc init() {\n\tcmdVerify.Run = executeVerify // break init loop\n}\n\nvar verifySigFile = cmdVerify.Flag.String(\"sig\", \"\", \"Path to the signature file\")\n\nfunc executeVerify(cmd *base.Command, args []string) {\n\ttarget := cmdVerify.Flag.Arg(0)\n\tif target == \"\" {\n\t\tbase.Fatalf(\"empty file path.\")\n\t}\n\n\tif *verifySigFile == \"\" {\n\t\tbase.Fatalf(\"empty signature path.\")\n\t}\n\n\tsigReader, err := os.Open(os.ExpandEnv(*verifySigFile))\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to open file %s: %s \", *verifySigFile, err)\n\t}\n\n\tfiles := cmdVerify.Flag.Args()\n\n\terr = signerVerify.OutputAndJudge(signerVerify.CheckSignaturesV2Fly(sigReader, files))\n\tif err != nil {\n\t\tbase.Fatalf(\"file is not officially signed by V2Ray: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "main/commands/base/command.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 base defines shared basic pieces of the commands,\n// in particular logging and the Command structure.\npackage base\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// A Command is an implementation of a v2ray command\n// like v2ray run or v2ray version.\ntype Command struct {\n\t// Run runs the command.\n\t// The args are the arguments after the command name.\n\tRun func(cmd *Command, args []string)\n\n\t// UsageLine is the one-line usage message.\n\t// The words between the first word (the \"executable name\") and the first flag or argument in the line are taken to be the command name.\n\t//\n\t// UsageLine supports go template syntax. It's recommended to use \"{{.Exec}}\" instead of hardcoding name\n\tUsageLine string\n\n\t// Short is the short description shown in the 'go help' output.\n\t//\n\t// Note: Short does not support go template syntax.\n\tShort string\n\n\t// Long is the long message shown in the 'go help <this-command>' output.\n\t//\n\t// Long supports go template syntax. It's recommended to use \"{{.Exec}}\", \"{{.LongName}}\" instead of hardcoding strings\n\tLong string\n\n\t// Flag is a set of flags specific to this command.\n\tFlag flag.FlagSet\n\n\t// CustomFlags indicates that the command will do its own\n\t// flag parsing.\n\tCustomFlags bool\n\n\t// Commands lists the available commands and help topics.\n\t// The order here is the order in which they are printed by 'go help'.\n\t// Note that subcommands are in general best avoided.\n\tCommands []*Command\n}\n\n// LongName returns the command's long name: all the words in the usage line between first word (e.g. \"v2ray\") and a flag or argument,\nfunc (c *Command) LongName() string {\n\tname := c.UsageLine\n\tif i := strings.Index(name, \" [\"); i >= 0 {\n\t\tname = strings.TrimSpace(name[:i])\n\t}\n\tif i := strings.Index(name, \" \"); i >= 0 {\n\t\tname = name[i+1:]\n\t} else {\n\t\tname = \"\"\n\t}\n\treturn strings.TrimSpace(name)\n}\n\n// Name returns the command's short name: the last word in the usage line before a flag or argument.\nfunc (c *Command) Name() string {\n\tname := c.LongName()\n\tif i := strings.LastIndex(name, \" \"); i >= 0 {\n\t\tname = name[i+1:]\n\t}\n\treturn strings.TrimSpace(name)\n}\n\n// Usage prints usage of the Command\nfunc (c *Command) Usage() {\n\tbuildCommandText(c)\n\tfmt.Fprintf(os.Stderr, \"usage: %s\\n\", c.UsageLine)\n\tfmt.Fprintf(os.Stderr, \"Run '%s help %s' for details.\\n\", CommandEnv.Exec, c.LongName())\n\tSetExitStatus(2)\n\tExit()\n}\n\n// Runnable reports whether the command can be run; otherwise\n// it is a documentation pseudo-command such as importpath.\nfunc (c *Command) Runnable() bool {\n\treturn c.Run != nil\n}\n\n// Exit exits with code set with SetExitStatus()\nfunc Exit() {\n\tos.Exit(exitStatus)\n}\n\n// Fatalf logs error and exit with code 1\nfunc Fatalf(format string, args ...interface{}) {\n\tErrorf(format, args...)\n\tExit()\n}\n\n// Errorf logs error and set exit status to 1, but not exit\nfunc Errorf(format string, args ...interface{}) {\n\tfmt.Fprintf(os.Stderr, format, args...)\n\tfmt.Fprintln(os.Stderr)\n\tSetExitStatus(1)\n}\n\n// ExitIfErrors exits if current status is not zero\nfunc ExitIfErrors() {\n\tif exitStatus != 0 {\n\t\tExit()\n\t}\n}\n\nvar (\n\texitStatus = 0\n\texitMu     sync.Mutex\n)\n\n// SetExitStatus set exit status code\nfunc SetExitStatus(n int) {\n\texitMu.Lock()\n\tif exitStatus < n {\n\t\texitStatus = n\n\t}\n\texitMu.Unlock()\n}\n\n// GetExitStatus get exit status code\nfunc GetExitStatus() int {\n\treturn exitStatus\n}\n"
  },
  {
    "path": "main/commands/base/env.go",
    "content": "package base\n\nimport (\n\t\"os\"\n\t\"path\"\n)\n\n// CommandEnvHolder is a struct holds the environment info of commands\ntype CommandEnvHolder struct {\n\t// Excutable name of current binary\n\tExec string\n\t// commands column width of current command\n\tCommandsWidth int\n}\n\n// CommandEnv holds the environment info of commands\nvar CommandEnv CommandEnvHolder\n\nfunc init() {\n\texec, err := os.Executable()\n\tif err != nil {\n\t\treturn\n\t}\n\tCommandEnv.Exec = path.Base(exec)\n}\n"
  },
  {
    "path": "main/commands/base/execute.go",
    "content": "package base\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// copied from \"github.com/golang/go/main.go\"\n\n// Execute excute the commands\nfunc Execute() {\n\tflag.Usage = func() {\n\t\tPrintUsage(os.Stderr, RootCommand)\n\t}\n\tflag.Parse()\n\targs := flag.Args()\n\tif len(args) < 1 {\n\t\tPrintUsage(os.Stderr, RootCommand)\n\t\treturn\n\t}\n\tcmdName := args[0] // for error messages\n\tif args[0] == \"help\" {\n\t\tHelp(os.Stdout, args[1:])\n\t\treturn\n\t}\n\nBigCmdLoop:\n\tfor bigCmd := RootCommand; ; {\n\t\tfor _, cmd := range bigCmd.Commands {\n\t\t\tif cmd.Name() != args[0] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif len(cmd.Commands) > 0 {\n\t\t\t\t// test sub commands\n\t\t\t\tbigCmd = cmd\n\t\t\t\targs = args[1:]\n\t\t\t\tif len(args) == 0 {\n\t\t\t\t\tPrintUsage(os.Stderr, bigCmd)\n\t\t\t\t\tSetExitStatus(2)\n\t\t\t\t\tExit()\n\t\t\t\t}\n\t\t\t\tif args[0] == \"help\" {\n\t\t\t\t\t// Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.\n\t\t\t\t\tHelp(os.Stdout, append(strings.Split(cmdName, \" \"), args[1:]...))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcmdName += \" \" + args[0]\n\t\t\t\tcontinue BigCmdLoop\n\t\t\t}\n\t\t\tif !cmd.Runnable() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcmd.Flag.Usage = func() { cmd.Usage() }\n\t\t\tif cmd.CustomFlags {\n\t\t\t\targs = args[1:]\n\t\t\t} else {\n\t\t\t\tcmd.Flag.Parse(args[1:])\n\t\t\t\targs = cmd.Flag.Args()\n\t\t\t}\n\n\t\t\tbuildCommandText(cmd)\n\t\t\tcmd.Run(cmd, args)\n\t\t\tExit()\n\t\t\treturn\n\t\t}\n\t\thelpArg := \"\"\n\t\tif i := strings.LastIndex(cmdName, \" \"); i >= 0 {\n\t\t\thelpArg = \" \" + cmdName[:i]\n\t\t}\n\t\tfmt.Fprintf(os.Stderr, \"%s %s: unknown command\\nRun '%s help%s' for usage.\\n\", CommandEnv.Exec, cmdName, CommandEnv.Exec, helpArg)\n\t\tSetExitStatus(2)\n\t\tExit()\n\t}\n}\n\n// SortCommands sorts the first level sub commands\nfunc SortCommands() {\n\tsort.Slice(RootCommand.Commands, func(i, j int) bool {\n\t\treturn SortLessFunc(RootCommand.Commands[i], RootCommand.Commands[j])\n\t})\n}\n\n// SortLessFunc used for sort commands list, can be override from outside\nvar SortLessFunc = func(i, j *Command) bool {\n\treturn i.Name() < j.Name()\n}\n"
  },
  {
    "path": "main/commands/base/help.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 base\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"text/template\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\n// Help implements the 'help' command.\nfunc Help(w io.Writer, args []string) {\n\tcmd := RootCommand\nArgs:\n\tfor i, arg := range args {\n\t\tfor _, sub := range cmd.Commands {\n\t\t\tif sub.Name() == arg {\n\t\t\t\tcmd = sub\n\t\t\t\tcontinue Args\n\t\t\t}\n\t\t}\n\n\t\t// helpSuccess is the help command using as many args as possible that would succeed.\n\t\thelpSuccess := CommandEnv.Exec + \" help\"\n\t\tif i > 0 {\n\t\t\thelpSuccess += \" \" + strings.Join(args[:i], \" \")\n\t\t}\n\t\tfmt.Fprintf(os.Stderr, \"%s help %s: unknown help topic. Run '%s'.\\n\", CommandEnv.Exec, strings.Join(args, \" \"), helpSuccess)\n\t\tSetExitStatus(2) // failed at 'v2ray help cmd'\n\t\tExit()\n\t}\n\n\tif len(cmd.Commands) > 0 {\n\t\tPrintUsage(os.Stdout, cmd)\n\t} else {\n\t\tbuildCommandText(cmd)\n\t\ttmpl(os.Stdout, helpTemplate, makeTmplData(cmd))\n\t}\n}\n\nvar usageTemplate = `{{.Long | trim}}\n\nUsage:\n\n\t{{.UsageLine}} <command> [arguments]\n\nThe commands are:\n{{range .Commands}}{{if and (ne .Short \"\") (or (.Runnable) .Commands)}}\n\t{{.Name | width $.CommandsWidth}} {{.Short}}{{end}}{{end}}\n\nUse \"{{.Exec}} help{{with .LongName}} {{.}}{{end}} <command>\" for more information about a command.\n{{if eq (.UsageLine) (.Exec)}}\nAdditional help topics:\n{{range .Commands}}{{if and (not .Runnable) (not .Commands)}}\n\t{{.Name | width $.CommandsWidth}} {{.Short}}{{end}}{{end}}\n\nUse \"{{.Exec}} help{{with .LongName}} {{.}}{{end}} <topic>\" for more information about that topic.\n{{end}}\n`\n\nvar helpTemplate = `{{if .Runnable}}usage: {{.UsageLine}}\n\n{{end}}{{.Long | trim}}\n`\n\n// An errWriter wraps a writer, recording whether a write error occurred.\ntype errWriter struct {\n\tw   io.Writer\n\terr error\n}\n\nfunc (w *errWriter) Write(b []byte) (int, error) {\n\tn, err := w.w.Write(b)\n\tif err != nil {\n\t\tw.err = err\n\t}\n\treturn n, err\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{}) {\n\tt := template.New(\"top\")\n\tt.Funcs(template.FuncMap{\"trim\": strings.TrimSpace, \"capitalize\": capitalize, \"width\": width})\n\ttemplate.Must(t.Parse(text))\n\tew := &errWriter{w: w}\n\terr := t.Execute(ew, data)\n\tif ew.err != nil {\n\t\t// I/O error writing. Ignore write on closed pipe.\n\t\tif strings.Contains(ew.err.Error(), \"pipe\") {\n\t\t\tSetExitStatus(1)\n\t\t\tExit()\n\t\t}\n\t\tFatalf(\"writing output: %v\", ew.err)\n\t}\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\nfunc capitalize(s string) string {\n\tif s == \"\" {\n\t\treturn s\n\t}\n\tr, n := utf8.DecodeRuneInString(s)\n\treturn string(unicode.ToTitle(r)) + s[n:]\n}\n\nfunc width(width int, value string) string {\n\tformat := fmt.Sprintf(\"%%-%ds\", width)\n\treturn fmt.Sprintf(format, value)\n}\n\n// PrintUsage prints usage of cmd to w\nfunc PrintUsage(w io.Writer, cmd *Command) {\n\tbuildCommandText(cmd)\n\tbw := bufio.NewWriter(w)\n\ttmpl(bw, usageTemplate, makeTmplData(cmd))\n\tbw.Flush()\n}\n\n// buildCommandText build command text as template\nfunc buildCommandText(cmd *Command) {\n\tdata := makeTmplData(cmd)\n\tcmd.UsageLine = buildText(cmd.UsageLine, data)\n\t// DO NOT SUPPORT \".Short\":\n\t// - It's not necessary\n\t// - Or, we have to build text for all sub commands of current command, like \"v2ray help api\"\n\t// cmd.Short = buildText(cmd.Short, data)\n\tcmd.Long = buildText(cmd.Long, data)\n}\n\nfunc buildText(text string, data interface{}) string {\n\tbuf := bytes.NewBuffer([]byte{})\n\ttext = strings.ReplaceAll(text, \"\\t\", \"    \")\n\ttmpl(buf, text, data)\n\treturn buf.String()\n}\n\ntype tmplData struct {\n\t*Command\n\t*CommandEnvHolder\n}\n\nfunc makeTmplData(cmd *Command) tmplData {\n\t// Minimum width of the command column\n\twidth := 12\n\tfor _, c := range cmd.Commands {\n\t\tl := len(c.Name())\n\t\tif width < l {\n\t\t\twidth = l\n\t\t}\n\t}\n\tCommandEnv.CommandsWidth = width\n\treturn tmplData{\n\t\tCommand:          cmd,\n\t\tCommandEnvHolder: &CommandEnv,\n\t}\n}\n"
  },
  {
    "path": "main/commands/base/root.go",
    "content": "package base\n\n// RootCommand is the root command of all commands\nvar RootCommand *Command\n\nfunc init() {\n\tRootCommand = &Command{\n\t\tUsageLine: CommandEnv.Exec,\n\t\tLong:      \"The root command\",\n\t}\n}\n\n// RegisterCommand register a command to RootCommand\nfunc RegisterCommand(cmd *Command) {\n\tRootCommand.Commands = append(RootCommand.Commands, cmd)\n}\n"
  },
  {
    "path": "main/commands/errors.generated.go",
    "content": "package commands\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "main/commands/helpers/config_load.go",
    "content": "package helpers\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/merge\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/mergers\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/serial\"\n\tv4 \"github.com/v2fly/v2ray-core/v5/infra/conf/v4\"\n)\n\n// LoadConfig load config files to *conf.Config, it will:\n// - resolve folder to files\n// - try to read stdin if no file specified\nfunc LoadConfig(files []string, format string, recursively bool) (*v4.Config, error) {\n\tm, err := LoadConfigToMap(files, format, recursively)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbs, err := merge.FromMap(m)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tr := bytes.NewReader(bs)\n\treturn serial.DecodeJSONConfig(r)\n}\n\n// LoadConfigToMap load config files to map, it will:\n// - resolve folder to files\n// - try to read stdin if no file specified\nfunc LoadConfigToMap(files []string, format string, recursively bool) (map[string]interface{}, error) {\n\tvar err error\n\tif len(files) > 0 {\n\t\tvar extensions []string\n\t\textensions, err := mergers.GetExtensions(format)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfiles, err = ResolveFolderToFiles(files, extensions, recursively)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tm := make(map[string]interface{})\n\tif len(files) == 0 {\n\t\terr = mergers.MergeAs(format, os.Stdin, m)\n\t} else {\n\t\terr = mergers.MergeAs(format, files, m)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn m, nil\n}\n"
  },
  {
    "path": "main/commands/helpers/fs.go",
    "content": "package helpers\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// ReadDir finds files according to extensions in the dir\nfunc ReadDir(dir string, extensions []string) ([]string, error) {\n\tconfs, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfiles := make([]string, 0)\n\tfor _, f := range confs {\n\t\text := filepath.Ext(f.Name())\n\t\tfor _, e := range extensions {\n\t\t\tif strings.EqualFold(ext, e) {\n\t\t\t\tfiles = append(files, filepath.Join(dir, f.Name()))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn files, nil\n}\n\n// ReadDirRecursively finds files according to extensions in the dir recursively\nfunc ReadDirRecursively(dir string, extensions []string) ([]string, error) {\n\tfiles := make([]string, 0)\n\terr := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {\n\t\text := filepath.Ext(path)\n\t\tfor _, e := range extensions {\n\t\t\tif strings.EqualFold(ext, e) {\n\t\t\t\tfiles = append(files, path)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn files, nil\n}\n\n// ResolveFolderToFiles expands folder path (if any and it exists) to file paths.\n// Any other paths, like file, even URL, it returns them as is.\nfunc ResolveFolderToFiles(paths []string, extensions []string, recursively bool) ([]string, error) {\n\tdirReader := ReadDir\n\tif recursively {\n\t\tdirReader = ReadDirRecursively\n\t}\n\tfiles := make([]string, 0)\n\tfor _, p := range paths {\n\t\ti, err := os.Stat(p)\n\t\tif err == nil && i.IsDir() {\n\t\t\tfs, err := dirReader(p, extensions)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to read dir %s: %s\", p, err)\n\t\t\t}\n\t\t\tfiles = append(files, fs...)\n\t\t\tcontinue\n\t\t}\n\t\tfiles = append(files, p)\n\t}\n\treturn files, nil\n}\n"
  },
  {
    "path": "main/commands/run.go",
    "content": "package commands\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"syscall\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/cmdarg\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/plugins\"\n)\n\n// CmdRun runs V2Ray with config\nvar CmdRun = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} run [-c config.json] [-d dir]\",\n\tShort:       \"run V2Ray with config\",\n\tLong: `\nRun V2Ray with config.\n\n{{.Exec}} will also use the config directory specified by environment \nvariable \"v2ray.location.confdir\". If no config found, it tries \nto load config from one of below:\n\n\t1. The default \"config.json\" in the current directory\n\t2. The config file from ENV \"v2ray.location.config\"\n\t3. The stdin if all failed above\n\nArguments:\n\n\t-c, -config <file>\n\t\tConfig file for V2Ray. Multiple assign is accepted.\n\n\t-d, -confdir <dir>\n\t\tA directory with config files. Multiple assign is accepted.\n\n\t-r\n\t\tLoad confdir recursively.\n\n\t-format <format>\n\t\tFormat of config input. (default \"auto\")\n\nExamples:\n\n\t{{.Exec}} {{.LongName}} -c config.json\n\t{{.Exec}} {{.LongName}} -d path/to/dir\n\nUse \"{{.Exec}} help format-loader\" for more information about format.\n\t`,\n\tRun: executeRun,\n}\n\nvar (\n\tconfigFiles          cmdarg.Arg\n\tconfigDirs           cmdarg.Arg\n\tconfigFormat         *string\n\tconfigDirRecursively *bool\n)\n\nfunc setConfigFlags(cmd *base.Command) {\n\tconfigFormat = cmd.Flag.String(\"format\", core.FormatAuto, \"\")\n\tconfigDirRecursively = cmd.Flag.Bool(\"r\", false, \"\")\n\n\tcmd.Flag.Var(&configFiles, \"config\", \"\")\n\tcmd.Flag.Var(&configFiles, \"c\", \"\")\n\tcmd.Flag.Var(&configDirs, \"confdir\", \"\")\n\tcmd.Flag.Var(&configDirs, \"d\", \"\")\n}\n\nfunc executeRun(cmd *base.Command, args []string) {\n\tsetConfigFlags(cmd)\n\tvar pluginFuncs []func() error\n\tfor _, plugin := range plugins.Plugins {\n\t\tif f := plugin(cmd); f != nil {\n\t\t\tpluginFuncs = append(pluginFuncs, f)\n\t\t}\n\t}\n\tcmd.Flag.Parse(args)\n\tprintVersion()\n\tconfigFiles = getConfigFilePath()\n\tserver, err := startV2Ray()\n\tif err != nil {\n\t\tbase.Fatalf(\"Failed to start: %s\", err)\n\t}\n\n\tfor _, f := range pluginFuncs {\n\t\tgo func(f func() error) {\n\t\t\tif err := f(); err != nil {\n\t\t\t\tlog.Print(err)\n\t\t\t}\n\t\t}(f)\n\t}\n\n\tif err := server.Start(); err != nil {\n\t\tbase.Fatalf(\"Failed to start: %s\", err)\n\t}\n\tdefer server.Close()\n\n\t// Explicitly triggering GC to remove garbage from config loading.\n\truntime.GC()\n\n\t{\n\t\tosSignals := make(chan os.Signal, 1)\n\t\tsignal.Notify(osSignals, os.Interrupt, syscall.SIGTERM)\n\t\t<-osSignals\n\t}\n}\n\nfunc fileExists(file string) bool {\n\tinfo, err := os.Stat(file)\n\treturn err == nil && !info.IsDir()\n}\n\nfunc dirExists(file string) bool {\n\tif file == \"\" {\n\t\treturn false\n\t}\n\tinfo, err := os.Stat(file)\n\treturn err == nil && info.IsDir()\n}\n\nfunc readConfDir(dirPath string, extension []string) cmdarg.Arg {\n\tconfs, err := os.ReadDir(dirPath)\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to read dir %s: %s\", dirPath, err)\n\t}\n\tfiles := make(cmdarg.Arg, 0)\n\tfor _, f := range confs {\n\t\text := filepath.Ext(f.Name())\n\t\tfor _, e := range extension {\n\t\t\tif strings.EqualFold(e, ext) {\n\t\t\t\tfiles.Set(filepath.Join(dirPath, f.Name()))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn files\n}\n\n// getFolderFiles get files in the folder and it's children\nfunc readConfDirRecursively(dirPath string, extension []string) cmdarg.Arg {\n\tfiles := make(cmdarg.Arg, 0)\n\terr := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {\n\t\text := filepath.Ext(path)\n\t\tfor _, e := range extension {\n\t\t\tif strings.EqualFold(e, ext) {\n\t\t\t\tfiles.Set(path)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\tbase.Fatalf(\"failed to read dir %s: %s\", dirPath, err)\n\t}\n\treturn files\n}\n\nfunc getConfigFilePath() cmdarg.Arg {\n\textension, err := core.GetLoaderExtensions(*configFormat)\n\tif err != nil {\n\t\tbase.Fatalf(\"%v\", err.Error())\n\t}\n\tdirReader := readConfDir\n\tif *configDirRecursively {\n\t\tdirReader = readConfDirRecursively\n\t}\n\tif len(configDirs) > 0 {\n\t\tfor _, d := range configDirs {\n\t\t\tlog.Println(\"Using confdir from arg:\", d)\n\t\t\tconfigFiles = append(configFiles, dirReader(d, extension)...)\n\t\t}\n\t} else if envConfDir := platform.GetConfDirPath(); dirExists(envConfDir) {\n\t\tlog.Println(\"Using confdir from env:\", envConfDir)\n\t\tconfigFiles = append(configFiles, dirReader(envConfDir, extension)...)\n\t}\n\tif len(configFiles) > 0 {\n\t\treturn configFiles\n\t}\n\n\tif len(configFiles) == 0 && len(configDirs) > 0 {\n\t\tbase.Fatalf(\"no config file found with extension: %s\", extension)\n\t}\n\n\tif workingDir, err := os.Getwd(); err == nil {\n\t\tconfigFile := filepath.Join(workingDir, \"config.json\")\n\t\tif fileExists(configFile) {\n\t\t\tlog.Println(\"Using default config: \", configFile)\n\t\t\treturn cmdarg.Arg{configFile}\n\t\t}\n\t}\n\n\tif configFile := platform.GetConfigurationPath(); fileExists(configFile) {\n\t\tlog.Println(\"Using config from env: \", configFile)\n\t\treturn cmdarg.Arg{configFile}\n\t}\n\n\treturn nil\n}\n\nfunc startV2Ray() (core.Server, error) {\n\tconfig, err := core.LoadConfig(*configFormat, configFiles)\n\tif err != nil {\n\t\tif len(configFiles) == 0 {\n\t\t\terr = newError(\"failed to load config\").Base(err)\n\t\t} else {\n\t\t\terr = newError(fmt.Sprintf(\"failed to load config: %s\", configFiles)).Base(err)\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tserver, err := core.New(config)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create server\").Base(err)\n\t}\n\n\treturn server, nil\n}\n"
  },
  {
    "path": "main/commands/test.go",
    "content": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n// CmdTest tests config files\nvar CmdTest = &base.Command{\n\tCustomFlags: true,\n\tUsageLine:   \"{{.Exec}} test [-format=json] [-c config.json] [-d dir]\",\n\tShort:       \"test config files\",\n\tLong: `\nTest config files, without launching V2Ray server.\n\n{{.Exec}} will also use the config directory specified by environment \nvariable \"v2ray.location.confdir\". If no config found, it tries \nto load config from one of below:\n\n\t1. The default \"config.json\" in the current directory\n\t2. The config file from ENV \"v2ray.location.config\"\n\t3. The stdin if all failed above\n\nArguments:\n\n\t-c, -config <file>\n\t\tConfig file for V2Ray. Multiple assign is accepted.\n\n\t-d, -confdir <dir>\n\t\tA directory with config files. Multiple assign is accepted.\n\n\t-r\n\t\tLoad confdir recursively.\n\n\t-format <format>\n\t\tFormat of config input. (default \"auto\")\n\nExamples:\n\n\t{{.Exec}} {{.LongName}} -c config.json\n\t{{.Exec}} {{.LongName}} -d path/to/dir\n\nUse \"{{.Exec}} help format-loader\" for more information about format.\n\t`,\n\tRun: executeTest,\n}\n\nfunc executeTest(cmd *base.Command, args []string) {\n\tsetConfigFlags(cmd)\n\tcmd.Flag.Parse(args)\n\tprintVersion()\n\tconfigFiles = getConfigFilePath()\n\t_, err := startV2Ray()\n\tif err != nil {\n\t\tbase.Fatalf(\"Test failed: %s\", err)\n\t}\n\tfmt.Println(\"Configuration OK.\")\n}\n"
  },
  {
    "path": "main/commands/version.go",
    "content": "package commands\n\nimport (\n\t\"fmt\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n)\n\n// CmdVersion prints V2Ray Versions\nvar CmdVersion = &base.Command{\n\tUsageLine: \"{{.Exec}} version\",\n\tShort:     \"print V2Ray version\",\n\tLong: `Prints the build information for V2Ray.\n`,\n\tRun: executeVersion,\n}\n\nfunc executeVersion(cmd *base.Command, args []string) {\n\tprintVersion()\n}\n\nfunc printVersion() {\n\tversion := core.VersionStatement()\n\tfor _, s := range version {\n\t\tfmt.Println(s)\n\t}\n}\n"
  },
  {
    "path": "main/distro/all/all.go",
    "content": "package all\n\nimport (\n\t// The following are necessary as they register handlers in their init functions.\n\n\t// Mandatory features. Can't remove unless there are replacements.\n\t_ \"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/outbound\"\n\n\t// Default commander and all its services. This is an optional feature.\n\t_ \"github.com/v2fly/v2ray-core/v5/app/commander\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/log/command\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/stats/command\"\n\n\t// Developer preview services\n\t_ \"github.com/v2fly/v2ray-core/v5/app/instman/command\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/observatory/command\"\n\n\t// Other optional features.\n\t_ \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/dns/fakedns\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/log\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/reverse\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/router\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/stats\"\n\n\t// Fix dependency cycle caused by core import in internet package\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tagged/taggedimpl\"\n\n\t// Developer preview features\n\t_ \"github.com/v2fly/v2ray-core/v5/app/commander/webcommander\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/instman\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/observatory\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/persistentstorage/filesystemstorage\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/tun\"\n\n\t// Inbound and outbound proxies.\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/dns\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/http\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/trojan\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/vless/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/vless/outbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\n\t// Developer preview proxies\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/vlite/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/vlite/outbound\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/hysteria2\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022\"\n\n\t// Transports\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/grpc\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/http\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/quic\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tls/utls\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\"\n\n\t// Developer preview transports\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembly\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/simple\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripper/httprt\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/packetconn\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/stereotype/meek\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/stereotype/mekya\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripperreverserserver/clicommand\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/dtls\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/httpupgrade\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/server\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment/clicommand\"\n\n\t// Transport headers\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/srtp\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/tls\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/utp\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\"\n\t_ \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wireguard\"\n\n\t// Geo loaders\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/memconservative\"\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/geodata/standard\"\n\n\t// JSON, TOML, YAML config support. (jsonv4) This disable selective compile\n\t_ \"github.com/v2fly/v2ray-core/v5/main/formats\"\n\n\t// commands\n\t_ \"github.com/v2fly/v2ray-core/v5/main/commands/all\"\n\n\t// engineering commands\n\t_ \"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering\"\n\t_ \"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering/generateRandomData\"\n\n\t// Commands that rely on jsonv4 format This disable selective compile\n\t_ \"github.com/v2fly/v2ray-core/v5/main/commands/all/api/jsonv4\"\n\t_ \"github.com/v2fly/v2ray-core/v5/main/commands/all/jsonv4\"\n\n\t// V5 version of json configure file parser\n\t_ \"github.com/v2fly/v2ray-core/v5/infra/conf/v5cfg\"\n\n\t// Simplified config\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/http/simplified\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks/simplified\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/socks/simplified\"\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/trojan/simplified\"\n\n\t// Subscription Supports\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/subscriptionmanager/command\"\n\n\t// Subscription Containers: general purpose\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/containers/base64urlline\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/containers/dataurlsingle\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/containers/jsonfieldarray/jsonified\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/containers/urlline\"\n\n\t// Subscription Fetchers\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher/dataurlfetcher\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher/httpfetcher\"\n\n\t// Subscription Entries Converters\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/entries/nonnative\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/subscription/entries/outbound\" // Natively Supported Outbound Format\n)\n"
  },
  {
    "path": "main/distro/all/pion.go",
    "content": "//go:build !android\n\npackage all\n\nimport _ \"github.com/v2fly/v2ray-core/v5/common/natTraversal/stun/stuncli\"\n"
  },
  {
    "path": "main/distro/all/wireguard.go",
    "content": "//go:build !dragonfly\n\npackage all\n\nimport (\n\t// WireGuard Outbound is unreleased.\n\t_ \"github.com/v2fly/v2ray-core/v5/proxy/wireguard/outbound\"\n)\n"
  },
  {
    "path": "main/distro/debug/debug.go",
    "content": "package debug\n\nimport (\n\t\"net/http\"\n)\n\nfunc init() {\n\tgo func() {\n\t\thttp.ListenAndServe(\":6060\", nil)\n\t}()\n}\n"
  },
  {
    "path": "main/errors.generated.go",
    "content": "package main\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "main/formats/errors.generated.go",
    "content": "package formats\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "main/formats/formats.go",
    "content": "package formats\n\nimport (\n\t\"bytes\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/merge\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/mergers\"\n\t\"github.com/v2fly/v2ray-core/v5/infra/conf/serial\"\n)\n\nfunc init() {\n\tfor _, formatName := range mergers.GetAllNames() {\n\t\tloader, err := makeMergeLoader(formatName)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif formatName == core.FormatAuto {\n\t\t\tloader.Extension = nil\n\t\t}\n\t\tcommon.Must(core.RegisterConfigLoader(loader))\n\t}\n}\n\nfunc makeMergeLoader(formatName string) (*core.ConfigFormat, error) {\n\textensions, err := mergers.GetExtensions(formatName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &core.ConfigFormat{\n\t\tName:      []string{formatName},\n\t\tExtension: extensions,\n\t\tLoader:    makeLoaderFunc(formatName),\n\t}, nil\n}\n\nfunc makeLoaderFunc(formatName string) core.ConfigLoader {\n\treturn func(input interface{}) (*core.Config, error) {\n\t\tm := make(map[string]interface{})\n\t\terr := mergers.MergeAs(formatName, input, m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdata, err := merge.FromMap(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tr := bytes.NewReader(data)\n\t\tcf, err := serial.DecodeJSONConfig(r)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn cf.Build()\n\t}\n}\n"
  },
  {
    "path": "main/main.go",
    "content": "package main\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/main/commands\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n)\n\nfunc main() {\n\tbase.RootCommand.Long = \"A unified platform for anti-censorship.\"\n\tbase.RegisterCommand(commands.CmdRun)\n\tbase.RegisterCommand(commands.CmdVersion)\n\tbase.RegisterCommand(commands.CmdTest)\n\tbase.SortLessFunc = runIsTheFirst\n\tbase.SortCommands()\n\tbase.Execute()\n}\n\nfunc runIsTheFirst(i, j *base.Command) bool {\n\tleft := i.Name()\n\tright := j.Name()\n\tif left == \"run\" {\n\t\treturn true\n\t}\n\tif right == \"run\" {\n\t\treturn false\n\t}\n\treturn left < right\n}\n"
  },
  {
    "path": "main/main_test.go",
    "content": "//go:build coveragemain\n// +build coveragemain\n\npackage main\n\nimport (\n\t\"testing\"\n)\n\nfunc TestRunMainForCoverage(t *testing.T) {\n\tmain()\n}\n"
  },
  {
    "path": "main/plugins/plugin.go",
    "content": "package plugins\n\nimport \"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\nvar Plugins []Plugin\n\ntype Plugin func(*base.Command) func() error\n\nfunc RegisterPlugin(plugin Plugin) {\n\tPlugins = append(Plugins, plugin)\n}\n"
  },
  {
    "path": "main/plugins/plugin_pprof/plugin_pprof.go",
    "content": "package plugin_pprof //nolint: stylecheck\n\nimport (\n\t\"net/http\"\n\t\"net/http/pprof\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/main/plugins\"\n)\n\nvar pprofPlugin plugins.Plugin = func(cmd *base.Command) func() error {\n\taddr := cmd.Flag.String(\"pprof\", \"\", \"\")\n\treturn func() error {\n\t\tif *addr != \"\" {\n\t\t\th := http.NewServeMux()\n\t\t\th.HandleFunc(\"/debug/pprof/\", pprof.Index)\n\t\t\th.HandleFunc(\"/debug/pprof/cmdline\", pprof.Cmdline)\n\t\t\th.HandleFunc(\"/debug/pprof/profile\", pprof.Profile)\n\t\t\th.HandleFunc(\"/debug/pprof/symbol\", pprof.Symbol)\n\t\t\th.HandleFunc(\"/debug/pprof/trace\", pprof.Trace)\n\t\t\treturn (&http.Server{Addr: *addr, Handler: h}).ListenAndServe()\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc init() {\n\tplugins.RegisterPlugin(pprofPlugin)\n}\n"
  },
  {
    "path": "main/v2binding/startUp.go",
    "content": "package v2binding\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\nfunc (b *bindingInstance) setBaseDir(baseDir string) {\n\tb.baseDir = baseDir\n\tattentionFile := path.Join(baseDir, \"place your config file here.txt\")\n\t{\n\t\tf, err := os.OpenFile(attentionFile, os.O_RDONLY|os.O_CREATE, 0o666)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t_ = f.Close()\n\t}\n\t_ = os.Chdir(baseDir)\n}\n\nfunc (b *bindingInstance) loadDefaultConfigIfExists() error {\n\tconfig, err := os.ReadFile(path.Join(b.baseDir, \"config.json\"))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tinstanceManagement := b.instance.GetFeature(extension.InstanceManagementType())\n\tif instanceManagement == nil {\n\t\treturn fmt.Errorf(\"instance management type not found\")\n\t}\n\tinstance, ok := instanceManagement.(extension.InstanceManagement)\n\tif !ok {\n\t\treturn fmt.Errorf(\"instance management instance is invalid\")\n\t}\n\tctx := context.TODO()\n\terr = instance.AddInstance(ctx, \"default\", config, \"jsonv5\")\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = instance.StartInstance(ctx, \"default\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "main/v2binding/v2api/api.go",
    "content": "package main\n\nimport (\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/v2binding\"\n)\n\nfunc main() {\n\tv2binding.StartAPIInstance(\".\")\n\tfor {\n\t\ttime.Sleep(time.Minute)\n\t}\n}\n"
  },
  {
    "path": "main/v2binding/v2binding.go",
    "content": "package v2binding\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/commander\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/instman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/instman/command\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n)\n\ntype bindingInstance struct {\n\tstarted  bool\n\tinstance *core.Instance\n\tbaseDir  string\n}\n\nvar binding bindingInstance\n\nfunc (b *bindingInstance) startAPIInstance() {\n\tbindConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&instman.Config{}),\n\t\t\tserial.ToTypedMessage(&commander.Config{\n\t\t\t\tTag: \"api\",\n\t\t\t\tService: []*anypb.Any{\n\t\t\t\t\tserial.ToTypedMessage(&command.Config{}),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tInboundTag: []string{\"api\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"api\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"api\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(10999),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tPort:     uint32(10999),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag:           \"default-outbound\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\tbindConfig = withDefaultApps(bindConfig)\n\n\tinstance, err := core.New(bindConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\terr = instance.Start()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tb.instance = instance\n}\n\nfunc withDefaultApps(config *core.Config) *core.Config {\n\tconfig.App = append(config.App, serial.ToTypedMessage(&dispatcher.Config{}))\n\tconfig.App = append(config.App, serial.ToTypedMessage(&proxyman.InboundConfig{}))\n\tconfig.App = append(config.App, serial.ToTypedMessage(&proxyman.OutboundConfig{}))\n\treturn config\n}\n\nfunc StartAPIInstance(basedir string) {\n\tif binding.started {\n\t\treturn\n\t}\n\tbinding.started = true\n\tbinding.setBaseDir(basedir)\n\tbinding.startAPIInstance()\n\t{\n\t\terr := binding.loadDefaultConfigIfExists()\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t\tos.WriteFile(\"last_err.txt\", []byte(err.Error()), 0o644)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "mocks.go",
    "content": "package core\n\n//go:generate env GOBIN=$PWD go install -v github.com/golang/mock/mockgen@latest\n//go:generate ./mockgen -package mocks -destination testing/mocks/io.go -mock_names Reader=Reader,Writer=Writer io Reader,Writer\n//go:generate ./mockgen -package mocks -destination testing/mocks/log.go -mock_names Handler=LogHandler github.com/v2fly/v2ray-core/v5/common/log Handler\n//go:generate ./mockgen -package mocks -destination testing/mocks/mux.go -mock_names ClientWorkerFactory=MuxClientWorkerFactory github.com/v2fly/v2ray-core/v5/common/mux ClientWorkerFactory\n//go:generate ./mockgen -package mocks -destination testing/mocks/dns.go -mock_names Client=DNSClient github.com/v2fly/v2ray-core/v5/features/dns Client\n//go:generate ./mockgen -package mocks -destination testing/mocks/outbound.go -mock_names Manager=OutboundManager,HandlerSelector=OutboundHandlerSelector github.com/v2fly/v2ray-core/v5/features/outbound Manager,HandlerSelector\n//go:generate ./mockgen -package mocks -destination testing/mocks/proxy.go -mock_names Inbound=ProxyInbound,Outbound=ProxyOutbound github.com/v2fly/v2ray-core/v5/proxy Inbound,Outbound\n"
  },
  {
    "path": "proto.go",
    "content": "package core\n\n//go:generate go install -v google.golang.org/protobuf/cmd/protoc-gen-go@latest\n//go:generate go install -v google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n//go:generate go run ./infra/vprotogen/\n"
  },
  {
    "path": "proxy/blackhole/blackhole.go",
    "content": "// Package blackhole is an outbound handler that blocks all connections.\npackage blackhole\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// Handler is an outbound connection that silently swallow the entire payload.\ntype Handler struct {\n\tresponse ResponseConfig\n}\n\n// New creates a new blackhole handler.\nfunc New(ctx context.Context, config *Config) (*Handler, error) {\n\tresponse, err := config.GetInternalResponse()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Handler{\n\t\tresponse: response,\n\t}, nil\n}\n\n// Process implements OutboundHandler.Dispatch().\nfunc (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\tnBytes := h.response.WriteTo(link.Writer)\n\tif nBytes > 0 {\n\t\t// Sleep a little here to make sure the response is sent to client.\n\t\ttime.Sleep(time.Second)\n\t}\n\tcommon.Interrupt(link.Writer)\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*SimplifiedConfig)\n\t\t_ = simplifiedServer\n\t\tfullConfig := &Config{}\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n"
  },
  {
    "path": "proxy/blackhole/blackhole_test.go",
    "content": "package blackhole_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc TestBlackHoleHTTPResponse(t *testing.T) {\n\thandler, err := blackhole.New(context.Background(), &blackhole.Config{\n\t\tResponse: serial.ToTypedMessage(&blackhole.HTTPResponse{}),\n\t})\n\tcommon.Must(err)\n\n\treader, writer := pipe.New(pipe.WithoutSizeLimit())\n\n\treaderError := make(chan error)\n\tvar mb buf.MultiBuffer\n\tgo func() {\n\t\tb, e := reader.ReadMultiBuffer()\n\t\tmb = b\n\t\treaderError <- e\n\t}()\n\n\tlink := transport.Link{\n\t\tReader: reader,\n\t\tWriter: writer,\n\t}\n\tcommon.Must(handler.Process(context.Background(), &link, nil))\n\tcommon.Must(<-readerError)\n\tif mb.IsEmpty() {\n\t\tt.Error(\"expect http response, but nothing\")\n\t}\n}\n"
  },
  {
    "path": "proxy/blackhole/config.go",
    "content": "package blackhole\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nconst (\n\thttp403response = `HTTP/1.1 403 Forbidden\nConnection: close\nCache-Control: max-age=3600, public\nContent-Length: 0\n\n\n`\n)\n\n// ResponseConfig is the configuration for blackhole responses.\ntype ResponseConfig interface {\n\t// WriteTo writes predefined response to the give buffer.\n\tWriteTo(buf.Writer) int32\n}\n\n// WriteTo implements ResponseConfig.WriteTo().\nfunc (*NoneResponse) WriteTo(buf.Writer) int32 { return 0 }\n\n// WriteTo implements ResponseConfig.WriteTo().\nfunc (*HTTPResponse) WriteTo(writer buf.Writer) int32 {\n\tb := buf.New()\n\tcommon.Must2(b.WriteString(http403response))\n\tn := b.Len()\n\twriter.WriteMultiBuffer(buf.MultiBuffer{b})\n\treturn n\n}\n\n// GetInternalResponse converts response settings from proto to internal data structure.\nfunc (c *Config) GetInternalResponse() (ResponseConfig, error) {\n\tif c.GetResponse() == nil {\n\t\treturn new(NoneResponse), nil\n\t}\n\n\tconfig, err := serial.GetInstanceOf(c.GetResponse())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn config.(ResponseConfig), nil\n}\n"
  },
  {
    "path": "proxy/blackhole/config.pb.go",
    "content": "package blackhole\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 NoneResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *NoneResponse) Reset() {\n\t*x = NoneResponse{}\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *NoneResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NoneResponse) ProtoMessage() {}\n\nfunc (x *NoneResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[0]\n\tif 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 NoneResponse.ProtoReflect.Descriptor instead.\nfunc (*NoneResponse) Descriptor() ([]byte, []int) {\n\treturn file_proxy_blackhole_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype HTTPResponse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *HTTPResponse) Reset() {\n\t*x = HTTPResponse{}\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *HTTPResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HTTPResponse) ProtoMessage() {}\n\nfunc (x *HTTPResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[1]\n\tif 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 HTTPResponse.ProtoReflect.Descriptor instead.\nfunc (*HTTPResponse) Descriptor() ([]byte, []int) {\n\treturn file_proxy_blackhole_config_proto_rawDescGZIP(), []int{1}\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tResponse      *anypb.Any             `protobuf:\"bytes,1,opt,name=response,proto3\" json:\"response,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[2]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_blackhole_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *Config) GetResponse() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Response\n\t}\n\treturn nil\n}\n\ntype SimplifiedConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_blackhole_config_proto_msgTypes[3]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_blackhole_config_proto_rawDescGZIP(), []int{3}\n}\n\nvar File_proxy_blackhole_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_blackhole_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1cproxy/blackhole/config.proto\\x12\\x1av2ray.core.proxy.blackhole\\x1a\\x19google/protobuf/any.proto\\x1a common/protoext/extensions.proto\\\"\\x0e\\n\" +\n\t\"\\fNoneResponse\\\"\\x0e\\n\" +\n\t\"\\fHTTPResponse\\\":\\n\" +\n\t\"\\x06Config\\x120\\n\" +\n\t\"\\bresponse\\x18\\x01 \\x01(\\v2\\x14.google.protobuf.AnyR\\bresponse\\\"-\\n\" +\n\t\"\\x10SimplifiedConfig:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\boutbound\\x12\\tblackholeBo\\n\" +\n\t\"\\x1ecom.v2ray.core.proxy.blackholeP\\x01Z.github.com/v2fly/v2ray-core/v5/proxy/blackhole\\xaa\\x02\\x1aV2Ray.Core.Proxy.Blackholeb\\x06proto3\"\n\nvar (\n\tfile_proxy_blackhole_config_proto_rawDescOnce sync.Once\n\tfile_proxy_blackhole_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_blackhole_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_blackhole_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_blackhole_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_blackhole_config_proto_rawDesc), len(file_proxy_blackhole_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_blackhole_config_proto_rawDescData\n}\n\nvar file_proxy_blackhole_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_proxy_blackhole_config_proto_goTypes = []any{\n\t(*NoneResponse)(nil),     // 0: v2ray.core.proxy.blackhole.NoneResponse\n\t(*HTTPResponse)(nil),     // 1: v2ray.core.proxy.blackhole.HTTPResponse\n\t(*Config)(nil),           // 2: v2ray.core.proxy.blackhole.Config\n\t(*SimplifiedConfig)(nil), // 3: v2ray.core.proxy.blackhole.SimplifiedConfig\n\t(*anypb.Any)(nil),        // 4: google.protobuf.Any\n}\nvar file_proxy_blackhole_config_proto_depIdxs = []int32{\n\t4, // 0: v2ray.core.proxy.blackhole.Config.response:type_name -> google.protobuf.Any\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_blackhole_config_proto_init() }\nfunc file_proxy_blackhole_config_proto_init() {\n\tif File_proxy_blackhole_config_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: unsafe.Slice(unsafe.StringData(file_proxy_blackhole_config_proto_rawDesc), len(file_proxy_blackhole_config_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_proxy_blackhole_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_blackhole_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_blackhole_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_blackhole_config_proto = out.File\n\tfile_proxy_blackhole_config_proto_goTypes = nil\n\tfile_proxy_blackhole_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/blackhole/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.blackhole;\noption csharp_namespace = \"V2Ray.Core.Proxy.Blackhole\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/blackhole\";\noption java_package = \"com.v2ray.core.proxy.blackhole\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage NoneResponse {}\n\nmessage HTTPResponse {}\n\nmessage Config {\n  google.protobuf.Any response = 1;\n}\n\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"blackhole\";\n}"
  },
  {
    "path": "proxy/blackhole/config_test.go",
    "content": "package blackhole_test\n\nimport (\n\t\"bufio\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n)\n\nfunc TestHTTPResponse(t *testing.T) {\n\tbuffer := buf.New()\n\n\thttpResponse := new(HTTPResponse)\n\thttpResponse.WriteTo(buf.NewWriter(buffer))\n\n\treader := bufio.NewReader(buffer)\n\tresponse, err := http.ReadResponse(reader, nil)\n\tcommon.Must(err)\n\tdefer response.Body.Close()\n\n\tif response.StatusCode != 403 {\n\t\tt.Error(\"expected status code 403, but got \", response.StatusCode)\n\t}\n}\n"
  },
  {
    "path": "proxy/blackhole/errors.generated.go",
    "content": "package blackhole\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/dns/config.pb.go",
    "content": "package dns\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Server is the DNS server address. If specified, this address overrides the\n\t// original one.\n\tServer              *net.Endpoint `protobuf:\"bytes,1,opt,name=server,proto3\" json:\"server,omitempty\"`\n\tUserLevel           uint32        `protobuf:\"varint,2,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tOverrideResponseTtl bool          `protobuf:\"varint,4,opt,name=override_response_ttl,json=overrideResponseTtl,proto3\" json:\"override_response_ttl,omitempty\"`\n\tResponseTtl         uint32        `protobuf:\"varint,3,opt,name=response_ttl,json=responseTtl,proto3\" json:\"response_ttl,omitempty\"`\n\tNon_IPQuery         string        `protobuf:\"bytes,5,opt,name=non_IP_query,json=nonIPQuery,proto3\" json:\"non_IP_query,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_dns_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_dns_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_dns_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetServer() *net.Endpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetOverrideResponseTtl() bool {\n\tif x != nil {\n\t\treturn x.OverrideResponseTtl\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetResponseTtl() uint32 {\n\tif x != nil {\n\t\treturn x.ResponseTtl\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetNon_IPQuery() string {\n\tif x != nil {\n\t\treturn x.Non_IPQuery\n\t}\n\treturn \"\"\n}\n\ntype SimplifiedConfig struct {\n\tstate               protoimpl.MessageState `protogen:\"open.v1\"`\n\tOverrideResponseTtl bool                   `protobuf:\"varint,4,opt,name=override_response_ttl,json=overrideResponseTtl,proto3\" json:\"override_response_ttl,omitempty\"`\n\tResponseTtl         uint32                 `protobuf:\"varint,3,opt,name=response_ttl,json=responseTtl,proto3\" json:\"response_ttl,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_dns_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_dns_config_proto_msgTypes[1]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_dns_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SimplifiedConfig) GetOverrideResponseTtl() bool {\n\tif x != nil {\n\t\treturn x.OverrideResponseTtl\n\t}\n\treturn false\n}\n\nfunc (x *SimplifiedConfig) GetResponseTtl() uint32 {\n\tif x != nil {\n\t\treturn x.ResponseTtl\n\t}\n\treturn 0\n}\n\nvar File_proxy_dns_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_dns_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x16proxy/dns/config.proto\\x12\\x14v2ray.core.proxy.dns\\x1a\\x1ccommon/net/destination.proto\\x1a common/protoext/extensions.proto\\\"\\xd9\\x01\\n\" +\n\t\"\\x06Config\\x127\\n\" +\n\t\"\\x06server\\x18\\x01 \\x01(\\v2\\x1f.v2ray.core.common.net.EndpointR\\x06server\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x02 \\x01(\\rR\\tuserLevel\\x122\\n\" +\n\t\"\\x15override_response_ttl\\x18\\x04 \\x01(\\bR\\x13overrideResponseTtl\\x12!\\n\" +\n\t\"\\fresponse_ttl\\x18\\x03 \\x01(\\rR\\vresponseTtl\\x12 \\n\" +\n\t\"\\fnon_IP_query\\x18\\x05 \\x01(\\tR\\n\" +\n\t\"nonIPQuery\\\"~\\n\" +\n\t\"\\x10SimplifiedConfig\\x122\\n\" +\n\t\"\\x15override_response_ttl\\x18\\x04 \\x01(\\bR\\x13overrideResponseTtl\\x12!\\n\" +\n\t\"\\fresponse_ttl\\x18\\x03 \\x01(\\rR\\vresponseTtl:\\x13\\x82\\xb5\\x18\\x0f\\n\" +\n\t\"\\boutbound\\x12\\x03dnsB]\\n\" +\n\t\"\\x18com.v2ray.core.proxy.dnsP\\x01Z(github.com/v2fly/v2ray-core/v5/proxy/dns\\xaa\\x02\\x14V2Ray.Core.Proxy.Dnsb\\x06proto3\"\n\nvar (\n\tfile_proxy_dns_config_proto_rawDescOnce sync.Once\n\tfile_proxy_dns_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_dns_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_dns_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_dns_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_dns_config_proto_rawDesc), len(file_proxy_dns_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_dns_config_proto_rawDescData\n}\n\nvar file_proxy_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_dns_config_proto_goTypes = []any{\n\t(*Config)(nil),           // 0: v2ray.core.proxy.dns.Config\n\t(*SimplifiedConfig)(nil), // 1: v2ray.core.proxy.dns.SimplifiedConfig\n\t(*net.Endpoint)(nil),     // 2: v2ray.core.common.net.Endpoint\n}\nvar file_proxy_dns_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.dns.Config.server:type_name -> v2ray.core.common.net.Endpoint\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_dns_config_proto_init() }\nfunc file_proxy_dns_config_proto_init() {\n\tif File_proxy_dns_config_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: unsafe.Slice(unsafe.StringData(file_proxy_dns_config_proto_rawDesc), len(file_proxy_dns_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_dns_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_dns_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_dns_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_dns_config_proto = out.File\n\tfile_proxy_dns_config_proto_goTypes = nil\n\tfile_proxy_dns_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/dns/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.dns;\noption csharp_namespace = \"V2Ray.Core.Proxy.Dns\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/dns\";\noption java_package = \"com.v2ray.core.proxy.dns\";\noption java_multiple_files = true;\n\nimport \"common/net/destination.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  // Server is the DNS server address. If specified, this address overrides the\n  // original one.\n  v2ray.core.common.net.Endpoint server = 1;\n  uint32 user_level = 2;\n  bool override_response_ttl = 4;\n  uint32 response_ttl = 3;\n  string non_IP_query = 5;\n}\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"dns\";\n\n  bool override_response_ttl = 4;\n  uint32 response_ttl = 3;\n}\n"
  },
  {
    "path": "proxy/dns/dns.go",
    "content": "package dns\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/dns/dnsmessage\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\tdns_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/strmatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\th := new(Handler)\n\t\tif err := core.RequireFeatures(ctx, func(dnsClient dns.Client, policyManager policy.Manager) error {\n\t\t\treturn h.Init(config.(*Config), dnsClient, policyManager)\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn h, nil\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*SimplifiedConfig)\n\t\t_ = simplifiedServer\n\t\tfullConfig := &Config{}\n\t\tfullConfig.OverrideResponseTtl = simplifiedServer.OverrideResponseTtl\n\t\tfullConfig.ResponseTtl = simplifiedServer.ResponseTtl\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n\ntype ownLinkVerifier interface {\n\tIsOwnLink(ctx context.Context) bool\n}\n\ntype Handler struct {\n\tclient          dns.Client\n\tipv4Lookup      dns.IPv4Lookup\n\tipv6Lookup      dns.IPv6Lookup\n\townLinkVerifier ownLinkVerifier\n\tserver          net.Destination\n\ttimeout         time.Duration\n\n\tconfig *Config\n\n\tnonIPQuery string\n}\n\nfunc (h *Handler) Init(config *Config, dnsClient dns.Client, policyManager policy.Manager) error {\n\t// Enable FakeDNS for DNS outbound\n\tif clientWithFakeDNS, ok := dnsClient.(dns.ClientWithFakeDNS); ok {\n\t\tdnsClient = clientWithFakeDNS.AsFakeDNSClient()\n\t}\n\th.client = dnsClient\n\th.timeout = policyManager.ForLevel(config.UserLevel).Timeouts.ConnectionIdle\n\n\tif ipv4lookup, ok := dnsClient.(dns.IPv4Lookup); ok {\n\t\th.ipv4Lookup = ipv4lookup\n\t} else {\n\t\treturn newError(\"dns.Client doesn't implement IPv4Lookup\")\n\t}\n\n\tif ipv6lookup, ok := dnsClient.(dns.IPv6Lookup); ok {\n\t\th.ipv6Lookup = ipv6lookup\n\t} else {\n\t\treturn newError(\"dns.Client doesn't implement IPv6Lookup\")\n\t}\n\n\tif v, ok := dnsClient.(ownLinkVerifier); ok {\n\t\th.ownLinkVerifier = v\n\t}\n\n\tif config.Server != nil {\n\t\th.server = config.Server.AsDestination()\n\t}\n\n\th.config = config\n\n\th.nonIPQuery = config.Non_IPQuery\n\treturn nil\n}\n\nfunc (h *Handler) isOwnLink(ctx context.Context) bool {\n\treturn h.ownLinkVerifier != nil && h.ownLinkVerifier.IsOwnLink(ctx)\n}\n\nfunc parseIPQuery(b []byte) (r bool, domain string, id uint16, qType dnsmessage.Type) {\n\tvar parser dnsmessage.Parser\n\theader, err := parser.Start(b)\n\tif err != nil {\n\t\tnewError(\"parser start\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\n\tid = header.ID\n\tq, err := parser.Question()\n\tif err != nil {\n\t\tnewError(\"question\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\tqType = q.Type\n\tif qType != dnsmessage.TypeA && qType != dnsmessage.TypeAAAA {\n\t\treturn\n\t}\n\n\tdomain = q.Name.String()\n\tr = true\n\treturn\n}\n\n// Process implements proxy.Outbound.\nfunc (h *Handler) Process(ctx context.Context, link *transport.Link, d internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"invalid outbound\")\n\t}\n\n\tsrcNetwork := outbound.Target.Network\n\n\tdest := outbound.Target\n\tif h.server.Network != net.Network_Unknown {\n\t\tdest.Network = h.server.Network\n\t}\n\tif h.server.Address != nil {\n\t\tdest.Address = h.server.Address\n\t}\n\tif h.server.Port != 0 {\n\t\tdest.Port = h.server.Port\n\t}\n\n\tnewError(\"handling DNS traffic to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tconn := &outboundConn{\n\t\tdialer: func() (internet.Connection, error) {\n\t\t\treturn d.Dial(ctx, dest)\n\t\t},\n\t\tconnReady: make(chan struct{}, 1),\n\t}\n\n\tvar reader dns_proto.MessageReader\n\tvar writer dns_proto.MessageWriter\n\tif srcNetwork == net.Network_TCP {\n\t\treader = dns_proto.NewTCPReader(link.Reader)\n\t\twriter = &dns_proto.TCPWriter{\n\t\t\tWriter: link.Writer,\n\t\t}\n\t} else {\n\t\treader = &dns_proto.UDPReader{\n\t\t\tReader: link.Reader,\n\t\t}\n\t\twriter = &dns_proto.UDPWriter{\n\t\t\tWriter: link.Writer,\n\t\t}\n\t}\n\n\tvar connReader dns_proto.MessageReader\n\tvar connWriter dns_proto.MessageWriter\n\tif dest.Network == net.Network_TCP {\n\t\tconnReader = dns_proto.NewTCPReader(buf.NewReader(conn))\n\t\tconnWriter = &dns_proto.TCPWriter{\n\t\t\tWriter: buf.NewWriter(conn),\n\t\t}\n\t} else {\n\t\tconnReader = &dns_proto.UDPReader{\n\t\t\tReader: buf.NewPacketReader(conn),\n\t\t}\n\t\tconnWriter = &dns_proto.UDPWriter{\n\t\t\tWriter: buf.NewWriter(conn),\n\t\t}\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, h.timeout)\n\n\trequest := func() error {\n\t\tdefer conn.Close()\n\n\t\tfor {\n\t\t\tb, err := reader.ReadMessage()\n\t\t\tif err == io.EOF {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\ttimer.Update()\n\n\t\t\tif !h.isOwnLink(ctx) {\n\t\t\t\tisIPQuery, domain, id, qType := parseIPQuery(b.Bytes())\n\t\t\t\tif isIPQuery || h.nonIPQuery != \"drop\" {\n\t\t\t\t\tif domain, err := strmatcher.ToDomain(domain); err == nil {\n\t\t\t\t\t\tgo h.handleIPQuery(id, qType, domain, writer)\n\t\t\t\t\t} else {\n\t\t\t\t\t\th.handleDNSError(id, dnsmessage.RCodeFormatError, writer)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\th.handleDNSError(id, dnsmessage.RCodeNotImplemented, writer)\n\t\t\t\t}\n\t\t\t} else if err := connWriter.WriteMessage(b); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tresponse := func() error {\n\t\tfor {\n\t\t\tb, err := connReader.ReadMessage()\n\t\t\tif err == io.EOF {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\ttimer.Update()\n\n\t\t\tif err := writer.WriteMessage(b); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := task.Run(ctx, request, response); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (h *Handler) handleIPQuery(id uint16, qType dnsmessage.Type, domain string, writer dns_proto.MessageWriter) {\n\tvar ips []net.IP\n\tvar err error\n\n\tvar ttl uint32 = 600\n\tif h.config.OverrideResponseTtl {\n\t\tttl = h.config.ResponseTtl\n\t}\n\n\tswitch qType {\n\tcase dnsmessage.TypeA:\n\t\tips, err = h.ipv4Lookup.LookupIPv4(domain)\n\tcase dnsmessage.TypeAAAA:\n\t\tips, err = h.ipv6Lookup.LookupIPv6(domain)\n\t}\n\n\trcode := dns.RCodeFromError(err)\n\tif rcode == 0 && len(ips) == 0 && err != dns.ErrEmptyResponse {\n\t\tnewError(\"ip query\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\n\tb := buf.New()\n\trawBytes := b.Extend(buf.Size)\n\tbuilder := dnsmessage.NewBuilder(rawBytes[:0], dnsmessage.Header{\n\t\tID:                 id,\n\t\tRCode:              dnsmessage.RCode(rcode),\n\t\tRecursionAvailable: true,\n\t\tRecursionDesired:   true,\n\t\tResponse:           true,\n\t})\n\tbuilder.EnableCompression()\n\tcommon.Must(builder.StartQuestions())\n\tcommon.Must(builder.Question(dnsmessage.Question{\n\t\tName:  dnsmessage.MustNewName(domain),\n\t\tClass: dnsmessage.ClassINET,\n\t\tType:  qType,\n\t}))\n\tcommon.Must(builder.StartAnswers())\n\n\trHeader := dnsmessage.ResourceHeader{Name: dnsmessage.MustNewName(domain), Class: dnsmessage.ClassINET, TTL: ttl}\n\tfor _, ip := range ips {\n\t\tif len(ip) == net.IPv4len {\n\t\t\tvar r dnsmessage.AResource\n\t\t\tcopy(r.A[:], ip)\n\t\t\tcommon.Must(builder.AResource(rHeader, r))\n\t\t} else {\n\t\t\tvar r dnsmessage.AAAAResource\n\t\t\tcopy(r.AAAA[:], ip)\n\t\t\tcommon.Must(builder.AAAAResource(rHeader, r))\n\t\t}\n\t}\n\tmsgBytes, err := builder.Finish()\n\tif err != nil {\n\t\tnewError(\"pack message\").Base(err).WriteToLog()\n\t\tb.Release()\n\t\treturn\n\t}\n\tb.Resize(0, int32(len(msgBytes)))\n\n\tif err := writer.WriteMessage(b); err != nil {\n\t\tnewError(\"write IP answer\").Base(err).WriteToLog()\n\t}\n}\n\nfunc (h *Handler) handleDNSError(id uint16, rCode dnsmessage.RCode, writer dns_proto.MessageWriter) {\n\tvar err error\n\n\tb := buf.New()\n\trawBytes := b.Extend(buf.Size)\n\tbuilder := dnsmessage.NewBuilder(rawBytes[:0], dnsmessage.Header{\n\t\tID:                 id,\n\t\tRCode:              rCode,\n\t\tRecursionAvailable: true,\n\t\tRecursionDesired:   true,\n\t\tResponse:           true,\n\t})\n\tbuilder.EnableCompression()\n\tcommon.Must(builder.StartQuestions())\n\tcommon.Must(builder.StartAnswers())\n\n\tmsgBytes, err := builder.Finish()\n\tif err != nil {\n\t\tnewError(\"pack message\").Base(err).WriteToLog()\n\t\tb.Release()\n\t\treturn\n\t}\n\tb.Resize(0, int32(len(msgBytes)))\n\n\tif err := writer.WriteMessage(b); err != nil {\n\t\tnewError(\"write IP answer\").Base(err).WriteToLog()\n\t}\n}\n\ntype outboundConn struct {\n\taccess sync.Mutex\n\tdialer func() (internet.Connection, error)\n\n\tconn      net.Conn\n\tconnReady chan struct{}\n}\n\nfunc (c *outboundConn) dial() error {\n\tconn, err := c.dialer()\n\tif err != nil {\n\t\treturn err\n\t}\n\tc.conn = conn\n\tc.connReady <- struct{}{}\n\treturn nil\n}\n\nfunc (c *outboundConn) Write(b []byte) (int, error) {\n\tc.access.Lock()\n\n\tif c.conn == nil {\n\t\tif err := c.dial(); err != nil {\n\t\t\tc.access.Unlock()\n\t\t\tnewError(\"failed to dial outbound connection\").Base(err).AtWarning().WriteToLog()\n\t\t\treturn len(b), nil\n\t\t}\n\t}\n\n\tc.access.Unlock()\n\n\treturn c.conn.Write(b)\n}\n\nfunc (c *outboundConn) Read(b []byte) (int, error) {\n\tvar conn net.Conn\n\tc.access.Lock()\n\tconn = c.conn\n\tc.access.Unlock()\n\n\tif conn == nil {\n\t\t_, open := <-c.connReady\n\t\tif !open {\n\t\t\treturn 0, io.EOF\n\t\t}\n\t\tconn = c.conn\n\t}\n\n\treturn conn.Read(b)\n}\n\nfunc (c *outboundConn) Close() error {\n\tc.access.Lock()\n\tclose(c.connReady)\n\tif c.conn != nil {\n\t\tc.conn.Close()\n\t}\n\tc.access.Unlock()\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/dns/dns_test.go",
    "content": "package dns_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/miekg/dns\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\tdnsapp \"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\tdns_proxy \"github.com/v2fly/v2ray-core/v5/proxy/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\ntype staticHandler struct{}\n\nfunc (*staticHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {\n\tans := new(dns.Msg)\n\tans.Id = r.Id\n\n\tvar clientIP net.IP\n\n\topt := r.IsEdns0()\n\tif opt != nil {\n\t\tfor _, o := range opt.Option {\n\t\t\tif o.Option() == dns.EDNS0SUBNET {\n\t\t\t\tsubnet := o.(*dns.EDNS0_SUBNET)\n\t\t\t\tclientIP = subnet.Address\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, q := range r.Question {\n\t\tswitch {\n\t\tcase q.Name == \"google.com.\" && q.Qtype == dns.TypeA:\n\t\t\tif clientIP == nil {\n\t\t\t\trr, _ := dns.NewRR(\"google.com. IN A 8.8.8.8\")\n\t\t\t\tans.Answer = append(ans.Answer, rr)\n\t\t\t} else {\n\t\t\t\trr, _ := dns.NewRR(\"google.com. IN A 8.8.4.4\")\n\t\t\t\tans.Answer = append(ans.Answer, rr)\n\t\t\t}\n\n\t\tcase q.Name == \"facebook.com.\" && q.Qtype == dns.TypeA:\n\t\t\trr, _ := dns.NewRR(\"facebook.com. IN A 9.9.9.9\")\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"ipv6.google.com.\" && q.Qtype == dns.TypeA:\n\t\t\trr, err := dns.NewRR(\"ipv6.google.com. IN A 8.8.8.7\")\n\t\t\tcommon.Must(err)\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"ipv6.google.com.\" && q.Qtype == dns.TypeAAAA:\n\t\t\trr, err := dns.NewRR(\"ipv6.google.com. IN AAAA 2001:4860:4860::8888\")\n\t\t\tcommon.Must(err)\n\t\t\tans.Answer = append(ans.Answer, rr)\n\n\t\tcase q.Name == \"notexist.google.com.\" && q.Qtype == dns.TypeAAAA:\n\t\t\tans.MsgHdr.Rcode = dns.RcodeNameError\n\t\t}\n\t}\n\tw.WriteMsg(ans)\n}\n\nfunc TestUDPDNSTunnel(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t\tUDPSize: 1200,\n\t}\n\tdefer dnsServer.Shutdown()\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tserverPort := udp.PickPort()\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dnsapp.Config{\n\t\t\t\tNameServers: []*net.Endpoint{\n\t\t\t\t\t{\n\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPort: uint32(port),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tPort:     uint32(port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_UDP},\n\t\t\t\t}),\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dns_proxy.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\tcommon.Must(v.Start())\n\tdefer v.Close()\n\n\t{\n\t\tm1 := new(dns.Msg)\n\t\tm1.Id = dns.Id()\n\t\tm1.RecursionDesired = true\n\t\tm1.Question = make([]dns.Question, 1)\n\t\tm1.Question[0] = dns.Question{Name: \"google.com.\", Qtype: dns.TypeA, Qclass: dns.ClassINET}\n\n\t\tc := new(dns.Client)\n\t\tin, _, err := c.Exchange(m1, \"127.0.0.1:\"+strconv.Itoa(int(serverPort)))\n\t\tcommon.Must(err)\n\n\t\tif len(in.Answer) != 1 {\n\t\t\tt.Fatal(\"len(answer): \", len(in.Answer))\n\t\t}\n\n\t\trr, ok := in.Answer[0].(*dns.A)\n\t\tif !ok {\n\t\t\tt.Fatal(\"not A record\")\n\t\t}\n\t\tif r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != \"\" {\n\t\t\tt.Error(r)\n\t\t}\n\t}\n\n\t{\n\t\tm1 := new(dns.Msg)\n\t\tm1.Id = dns.Id()\n\t\tm1.RecursionDesired = true\n\t\tm1.Question = make([]dns.Question, 1)\n\t\tm1.Question[0] = dns.Question{Name: \"ipv4only.google.com.\", Qtype: dns.TypeAAAA, Qclass: dns.ClassINET}\n\n\t\tc := new(dns.Client)\n\t\tc.Timeout = 10 * time.Second\n\t\tin, _, err := c.Exchange(m1, \"127.0.0.1:\"+strconv.Itoa(int(serverPort)))\n\t\tcommon.Must(err)\n\n\t\tif len(in.Answer) != 0 {\n\t\t\tt.Fatal(\"len(answer): \", len(in.Answer))\n\t\t}\n\t}\n\n\t{\n\t\tm1 := new(dns.Msg)\n\t\tm1.Id = dns.Id()\n\t\tm1.RecursionDesired = true\n\t\tm1.Question = make([]dns.Question, 1)\n\t\tm1.Question[0] = dns.Question{Name: \"notexist.google.com.\", Qtype: dns.TypeAAAA, Qclass: dns.ClassINET}\n\n\t\tc := new(dns.Client)\n\t\tin, _, err := c.Exchange(m1, \"127.0.0.1:\"+strconv.Itoa(int(serverPort)))\n\t\tcommon.Must(err)\n\n\t\tif in.Rcode != dns.RcodeNameError {\n\t\t\tt.Error(\"expected NameError, but got \", in.Rcode)\n\t\t}\n\t}\n}\n\nfunc TestTCPDNSTunnel(t *testing.T) {\n\tport := udp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"udp\",\n\t\tHandler: &staticHandler{},\n\t}\n\tdefer dnsServer.Shutdown()\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tserverPort := tcp.PickPort()\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dnsapp.Config{\n\t\t\t\tNameServer: []*dnsapp.NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\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\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tPort:     uint32(port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dns_proxy.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\tcommon.Must(v.Start())\n\tdefer v.Close()\n\n\tm1 := new(dns.Msg)\n\tm1.Id = dns.Id()\n\tm1.RecursionDesired = true\n\tm1.Question = make([]dns.Question, 1)\n\tm1.Question[0] = dns.Question{Name: \"google.com.\", Qtype: dns.TypeA, Qclass: dns.ClassINET}\n\n\tc := &dns.Client{\n\t\tNet: \"tcp\",\n\t}\n\tin, _, err := c.Exchange(m1, \"127.0.0.1:\"+serverPort.String())\n\tcommon.Must(err)\n\n\tif len(in.Answer) != 1 {\n\t\tt.Fatal(\"len(answer): \", len(in.Answer))\n\t}\n\n\trr, ok := in.Answer[0].(*dns.A)\n\tif !ok {\n\t\tt.Fatal(\"not A record\")\n\t}\n\tif r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestUDP2TCPDNSTunnel(t *testing.T) {\n\tport := tcp.PickPort()\n\n\tdnsServer := dns.Server{\n\t\tAddr:    \"127.0.0.1:\" + port.String(),\n\t\tNet:     \"tcp\",\n\t\tHandler: &staticHandler{},\n\t}\n\tdefer dnsServer.Shutdown()\n\n\tgo dnsServer.ListenAndServe()\n\ttime.Sleep(time.Second)\n\n\tserverPort := tcp.PickPort()\n\tconfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dnsapp.Config{\n\t\t\t\tNameServer: []*dnsapp.NameServer{\n\t\t\t\t\t{\n\t\t\t\t\t\tAddress: &net.Endpoint{\n\t\t\t\t\t\t\tNetwork: net.Network_UDP,\n\t\t\t\t\t\t\tAddress: &net.IPOrDomain{\n\t\t\t\t\t\t\t\tAddress: &net.IPOrDomain_Ip{\n\t\t\t\t\t\t\t\t\tIp: []byte{127, 0, 0, 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\tPort: uint32(port),\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\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&policy.Config{}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tPort:     uint32(port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dns_proxy.Config{\n\t\t\t\t\tServer: &net.Endpoint{\n\t\t\t\t\t\tNetwork: net.Network_TCP,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t}\n\n\tv, err := core.New(config)\n\tcommon.Must(err)\n\tcommon.Must(v.Start())\n\tdefer v.Close()\n\n\tm1 := new(dns.Msg)\n\tm1.Id = dns.Id()\n\tm1.RecursionDesired = true\n\tm1.Question = make([]dns.Question, 1)\n\tm1.Question[0] = dns.Question{Name: \"google.com.\", Qtype: dns.TypeA, Qclass: dns.ClassINET}\n\n\tc := &dns.Client{\n\t\tNet: \"tcp\",\n\t}\n\tin, _, err := c.Exchange(m1, \"127.0.0.1:\"+serverPort.String())\n\tcommon.Must(err)\n\n\tif len(in.Answer) != 1 {\n\t\tt.Fatal(\"len(answer): \", len(in.Answer))\n\t}\n\n\trr, ok := in.Answer[0].(*dns.A)\n\tif !ok {\n\t\tt.Fatal(\"not A record\")\n\t}\n\tif r := cmp.Diff(rr.A[:], net.IP{8, 8, 8, 8}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "proxy/dns/errors.generated.go",
    "content": "package dns\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/dokodemo/config.go",
    "content": "package dokodemo\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n// GetPredefinedAddress returns the defined address from proto config. Null if address is not valid.\nfunc (v *Config) GetPredefinedAddress() net.Address {\n\taddr := v.Address.AsAddress()\n\tif addr == nil {\n\t\treturn nil\n\t}\n\treturn addr\n}\n"
  },
  {
    "path": "proxy/dokodemo/config.pb.go",
    "content": "package dokodemo\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate   protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort    uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\t// List of networks that the Dokodemo accepts.\n\t// Deprecated. Use networks.\n\t//\n\t// Deprecated: Marked as deprecated in proxy/dokodemo/config.proto.\n\tNetworkList *net.NetworkList `protobuf:\"bytes,3,opt,name=network_list,json=networkList,proto3\" json:\"network_list,omitempty\"`\n\t// List of networks that the Dokodemo accepts.\n\tNetworks []net.Network `protobuf:\"varint,7,rep,packed,name=networks,proto3,enum=v2ray.core.common.net.Network\" json:\"networks,omitempty\"`\n\t// Deprecated: Marked as deprecated in proxy/dokodemo/config.proto.\n\tTimeout        uint32 `protobuf:\"varint,4,opt,name=timeout,proto3\" json:\"timeout,omitempty\"`\n\tFollowRedirect bool   `protobuf:\"varint,5,opt,name=follow_redirect,json=followRedirect,proto3\" json:\"follow_redirect,omitempty\"`\n\tUserLevel      uint32 `protobuf:\"varint,6,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_dokodemo_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_dokodemo_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_dokodemo_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\n// Deprecated: Marked as deprecated in proxy/dokodemo/config.proto.\nfunc (x *Config) GetNetworkList() *net.NetworkList {\n\tif x != nil {\n\t\treturn x.NetworkList\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetNetworks() []net.Network {\n\tif x != nil {\n\t\treturn x.Networks\n\t}\n\treturn nil\n}\n\n// Deprecated: Marked as deprecated in proxy/dokodemo/config.proto.\nfunc (x *Config) GetTimeout() uint32 {\n\tif x != nil {\n\t\treturn x.Timeout\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetFollowRedirect() bool {\n\tif x != nil {\n\t\treturn x.FollowRedirect\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\ntype SimplifiedConfig struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress        *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort           uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tNetworks       *net.NetworkList       `protobuf:\"bytes,3,opt,name=networks,proto3\" json:\"networks,omitempty\"`\n\tFollowRedirect bool                   `protobuf:\"varint,4,opt,name=follow_redirect,json=followRedirect,proto3\" json:\"follow_redirect,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_dokodemo_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_dokodemo_config_proto_msgTypes[1]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_dokodemo_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SimplifiedConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *SimplifiedConfig) GetNetworks() *net.NetworkList {\n\tif x != nil {\n\t\treturn x.Networks\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetFollowRedirect() bool {\n\tif x != nil {\n\t\treturn x.FollowRedirect\n\t}\n\treturn false\n}\n\nvar File_proxy_dokodemo_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_dokodemo_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1bproxy/dokodemo/config.proto\\x12\\x19v2ray.core.proxy.dokodemo\\x1a\\x18common/net/address.proto\\x1a\\x18common/net/network.proto\\x1a common/protoext/extensions.proto\\\"\\xc6\\x02\\n\" +\n\t\"\\x06Config\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12I\\n\" +\n\t\"\\fnetwork_list\\x18\\x03 \\x01(\\v2\\\".v2ray.core.common.net.NetworkListB\\x02\\x18\\x01R\\vnetworkList\\x12:\\n\" +\n\t\"\\bnetworks\\x18\\a \\x03(\\x0e2\\x1e.v2ray.core.common.net.NetworkR\\bnetworks\\x12\\x1c\\n\" +\n\t\"\\atimeout\\x18\\x04 \\x01(\\rB\\x02\\x18\\x01R\\atimeout\\x12'\\n\" +\n\t\"\\x0ffollow_redirect\\x18\\x05 \\x01(\\bR\\x0efollowRedirect\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x06 \\x01(\\rR\\tuserLevel\\\"\\xea\\x01\\n\" +\n\t\"\\x10SimplifiedConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12>\\n\" +\n\t\"\\bnetworks\\x18\\x03 \\x01(\\v2\\\".v2ray.core.common.net.NetworkListR\\bnetworks\\x12'\\n\" +\n\t\"\\x0ffollow_redirect\\x18\\x04 \\x01(\\bR\\x0efollowRedirect:\\x1c\\x82\\xb5\\x18\\x18\\n\" +\n\t\"\\ainbound\\x12\\rdokodemo-doorBl\\n\" +\n\t\"\\x1dcom.v2ray.core.proxy.dokodemoP\\x01Z-github.com/v2fly/v2ray-core/v5/proxy/dokodemo\\xaa\\x02\\x19V2Ray.Core.Proxy.Dokodemob\\x06proto3\"\n\nvar (\n\tfile_proxy_dokodemo_config_proto_rawDescOnce sync.Once\n\tfile_proxy_dokodemo_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_dokodemo_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_dokodemo_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_dokodemo_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_dokodemo_config_proto_rawDesc), len(file_proxy_dokodemo_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_dokodemo_config_proto_rawDescData\n}\n\nvar file_proxy_dokodemo_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_dokodemo_config_proto_goTypes = []any{\n\t(*Config)(nil),           // 0: v2ray.core.proxy.dokodemo.Config\n\t(*SimplifiedConfig)(nil), // 1: v2ray.core.proxy.dokodemo.SimplifiedConfig\n\t(*net.IPOrDomain)(nil),   // 2: v2ray.core.common.net.IPOrDomain\n\t(*net.NetworkList)(nil),  // 3: v2ray.core.common.net.NetworkList\n\t(net.Network)(0),         // 4: v2ray.core.common.net.Network\n}\nvar file_proxy_dokodemo_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.dokodemo.Config.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t3, // 1: v2ray.core.proxy.dokodemo.Config.network_list:type_name -> v2ray.core.common.net.NetworkList\n\t4, // 2: v2ray.core.proxy.dokodemo.Config.networks:type_name -> v2ray.core.common.net.Network\n\t2, // 3: v2ray.core.proxy.dokodemo.SimplifiedConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t3, // 4: v2ray.core.proxy.dokodemo.SimplifiedConfig.networks:type_name -> v2ray.core.common.net.NetworkList\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_dokodemo_config_proto_init() }\nfunc file_proxy_dokodemo_config_proto_init() {\n\tif File_proxy_dokodemo_config_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: unsafe.Slice(unsafe.StringData(file_proxy_dokodemo_config_proto_rawDesc), len(file_proxy_dokodemo_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_dokodemo_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_dokodemo_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_dokodemo_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_dokodemo_config_proto = out.File\n\tfile_proxy_dokodemo_config_proto_goTypes = nil\n\tfile_proxy_dokodemo_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/dokodemo/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.dokodemo;\noption csharp_namespace = \"V2Ray.Core.Proxy.Dokodemo\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\";\noption java_package = \"com.v2ray.core.proxy.dokodemo\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/net/network.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n\n  // List of networks that the Dokodemo accepts.\n  // Deprecated. Use networks.\n  v2ray.core.common.net.NetworkList network_list = 3 [deprecated = true];\n  // List of networks that the Dokodemo accepts.\n  repeated v2ray.core.common.net.Network networks = 7;\n\n  uint32 timeout = 4 [deprecated = true];\n  bool follow_redirect = 5;\n  uint32 user_level = 6;\n}\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"dokodemo-door\";\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  v2ray.core.common.net.NetworkList networks = 3;\n  bool follow_redirect = 4;\n}\n"
  },
  {
    "path": "proxy/dokodemo/dokodemo.go",
    "content": "package dokodemo\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\td := new(Door)\n\t\terr := core.RequireFeatures(ctx, func(pm policy.Manager) error {\n\t\t\treturn d.Init(config.(*Config), pm, session.SockoptFromContext(ctx))\n\t\t})\n\t\treturn d, err\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*SimplifiedConfig)\n\t\tfullConfig := &Config{\n\t\t\tAddress:        simplifiedServer.Address,\n\t\t\tPort:           simplifiedServer.Port,\n\t\t\tNetworks:       simplifiedServer.Networks.Network,\n\t\t\tFollowRedirect: simplifiedServer.FollowRedirect,\n\t\t}\n\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n\ntype Door struct {\n\tpolicyManager policy.Manager\n\tconfig        *Config\n\taddress       net.Address\n\tport          net.Port\n\tsockopt       *session.Sockopt\n}\n\n// Init initializes the Door instance with necessary parameters.\nfunc (d *Door) Init(config *Config, pm policy.Manager, sockopt *session.Sockopt) error {\n\tif (config.NetworkList == nil || len(config.NetworkList.Network) == 0) && len(config.Networks) == 0 {\n\t\treturn newError(\"no network specified\")\n\t}\n\td.config = config\n\td.address = config.GetPredefinedAddress()\n\td.port = net.Port(config.Port)\n\td.policyManager = pm\n\td.sockopt = sockopt\n\n\treturn nil\n}\n\n// Network implements proxy.Inbound.\nfunc (d *Door) Network() []net.Network {\n\tif len(d.config.Networks) > 0 {\n\t\treturn d.config.Networks\n\t}\n\n\treturn d.config.NetworkList.GetNetwork()\n}\n\nfunc (d *Door) policy() policy.Session {\n\tconfig := d.config\n\tp := d.policyManager.ForLevel(config.UserLevel)\n\tif config.Timeout > 0 && config.UserLevel == 0 {\n\t\tp.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second\n\t}\n\treturn p\n}\n\ntype hasHandshakeAddress interface {\n\tHandshakeAddress() net.Address\n}\n\n// Process implements proxy.Inbound.\nfunc (d *Door) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tnewError(\"processing connection from: \", conn.RemoteAddr()).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\tdest := net.Destination{\n\t\tNetwork: network,\n\t\tAddress: d.address,\n\t\tPort:    d.port,\n\t}\n\n\tdestinationOverridden := false\n\tif d.config.FollowRedirect {\n\t\tif outbound := session.OutboundFromContext(ctx); outbound != nil && outbound.Target.IsValid() {\n\t\t\tdest = outbound.Target\n\t\t\tdestinationOverridden = true\n\t\t} else if handshake, ok := conn.(hasHandshakeAddress); ok {\n\t\t\taddr := handshake.HandshakeAddress()\n\t\t\tif addr != nil {\n\t\t\t\tdest.Address = addr\n\t\t\t\tdestinationOverridden = true\n\t\t\t}\n\t\t}\n\t}\n\tif !dest.IsValid() || dest.Address == nil {\n\t\treturn newError(\"unable to get destination\")\n\t}\n\n\tif inbound := session.InboundFromContext(ctx); inbound != nil {\n\t\tinbound.User = &protocol.MemoryUser{\n\t\t\tLevel: d.config.UserLevel,\n\t\t}\n\t}\n\n\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\tFrom:   conn.RemoteAddr(),\n\t\tTo:     dest,\n\t\tStatus: log.AccessAccepted,\n\t\tReason: \"\",\n\t})\n\tnewError(\"received request for \", conn.RemoteAddr()).WriteToLog(session.ExportIDToError(ctx))\n\n\tplcy := d.policy()\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, plcy.Timeouts.ConnectionIdle)\n\n\tctx = policy.ContextWithBufferPolicy(ctx, plcy.Buffer)\n\tlink, err := dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn newError(\"failed to dispatch request\").Base(err)\n\t}\n\n\trequestCount := int32(1)\n\trequestDone := func() error {\n\t\tdefer func() {\n\t\t\tif atomic.AddInt32(&requestCount, -1) == 0 {\n\t\t\t\ttimer.SetTimeout(plcy.Timeouts.DownlinkOnly)\n\t\t\t}\n\t\t}()\n\n\t\tvar reader buf.Reader\n\t\tif dest.Network == net.Network_UDP {\n\t\t\treader = buf.NewPacketReader(conn)\n\t\t} else {\n\t\t\treader = buf.NewReader(conn)\n\t\t}\n\t\tif err := buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport request\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\ttproxyRequest := func() error {\n\t\treturn nil\n\t}\n\n\tvar writer buf.Writer\n\tif network == net.Network_TCP {\n\t\twriter = buf.NewWriter(conn)\n\t} else {\n\t\t// if we are in TPROXY mode, use linux's udp forging functionality\n\t\tif !destinationOverridden {\n\t\t\twriter = &buf.SequentialWriter{Writer: conn}\n\t\t} else {\n\t\t\tsockopt := &internet.SocketConfig{\n\t\t\t\tTproxy: internet.SocketConfig_TProxy,\n\t\t\t}\n\t\t\tif dest.Address.Family().IsIP() {\n\t\t\t\tsockopt.BindAddress = dest.Address.IP()\n\t\t\t\tsockopt.BindPort = uint32(dest.Port)\n\t\t\t}\n\t\t\tif d.sockopt != nil {\n\t\t\t\tsockopt.Mark = d.sockopt.Mark\n\t\t\t}\n\t\t\ttConn, err := internet.DialSystem(ctx, net.DestinationFromAddr(conn.RemoteAddr()), sockopt)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer tConn.Close()\n\n\t\t\twriter = &buf.SequentialWriter{Writer: tConn}\n\t\t\ttReader := buf.NewPacketReader(tConn)\n\t\t\trequestCount++\n\t\t\ttproxyRequest = func() error {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif atomic.AddInt32(&requestCount, -1) == 0 {\n\t\t\t\t\t\ttimer.SetTimeout(plcy.Timeouts.DownlinkOnly)\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\tif err := buf.Copy(tReader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\t\treturn newError(\"failed to transport request (TPROXY conn)\").Base(err)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.UplinkOnly)\n\n\t\tif err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport response\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, task.OnSuccess(func() error {\n\t\treturn task.Run(ctx, requestDone, tproxyRequest)\n\t}, task.Close(link.Writer)), responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/dokodemo/errors.generated.go",
    "content": "package dokodemo\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/freedom/config.go",
    "content": "package freedom\n\nfunc (c *Config) useIP() bool {\n\treturn c.DomainStrategy == Config_USE_IP || c.DomainStrategy == Config_USE_IP4 || c.DomainStrategy == Config_USE_IP6\n}\n"
  },
  {
    "path": "proxy/freedom/config.pb.go",
    "content": "package freedom\n\nimport (\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ProtocolReplacement int32\n\nconst (\n\tProtocolReplacement_IDENTITY  ProtocolReplacement = 0\n\tProtocolReplacement_FORCE_TCP ProtocolReplacement = 1\n\tProtocolReplacement_FORCE_UDP ProtocolReplacement = 2\n)\n\n// Enum value maps for ProtocolReplacement.\nvar (\n\tProtocolReplacement_name = map[int32]string{\n\t\t0: \"IDENTITY\",\n\t\t1: \"FORCE_TCP\",\n\t\t2: \"FORCE_UDP\",\n\t}\n\tProtocolReplacement_value = map[string]int32{\n\t\t\"IDENTITY\":  0,\n\t\t\"FORCE_TCP\": 1,\n\t\t\"FORCE_UDP\": 2,\n\t}\n)\n\nfunc (x ProtocolReplacement) Enum() *ProtocolReplacement {\n\tp := new(ProtocolReplacement)\n\t*p = x\n\treturn p\n}\n\nfunc (x ProtocolReplacement) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (ProtocolReplacement) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_proxy_freedom_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (ProtocolReplacement) Type() protoreflect.EnumType {\n\treturn &file_proxy_freedom_config_proto_enumTypes[0]\n}\n\nfunc (x ProtocolReplacement) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use ProtocolReplacement.Descriptor instead.\nfunc (ProtocolReplacement) EnumDescriptor() ([]byte, []int) {\n\treturn file_proxy_freedom_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Config_DomainStrategy int32\n\nconst (\n\tConfig_AS_IS   Config_DomainStrategy = 0\n\tConfig_USE_IP  Config_DomainStrategy = 1\n\tConfig_USE_IP4 Config_DomainStrategy = 2\n\tConfig_USE_IP6 Config_DomainStrategy = 3\n)\n\n// Enum value maps for Config_DomainStrategy.\nvar (\n\tConfig_DomainStrategy_name = map[int32]string{\n\t\t0: \"AS_IS\",\n\t\t1: \"USE_IP\",\n\t\t2: \"USE_IP4\",\n\t\t3: \"USE_IP6\",\n\t}\n\tConfig_DomainStrategy_value = map[string]int32{\n\t\t\"AS_IS\":   0,\n\t\t\"USE_IP\":  1,\n\t\t\"USE_IP4\": 2,\n\t\t\"USE_IP6\": 3,\n\t}\n)\n\nfunc (x Config_DomainStrategy) Enum() *Config_DomainStrategy {\n\tp := new(Config_DomainStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x Config_DomainStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Config_DomainStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_proxy_freedom_config_proto_enumTypes[1].Descriptor()\n}\n\nfunc (Config_DomainStrategy) Type() protoreflect.EnumType {\n\treturn &file_proxy_freedom_config_proto_enumTypes[1]\n}\n\nfunc (x Config_DomainStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Config_DomainStrategy.Descriptor instead.\nfunc (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_proxy_freedom_config_proto_rawDescGZIP(), []int{1, 0}\n}\n\ntype DestinationOverride struct {\n\tstate         protoimpl.MessageState   `protogen:\"open.v1\"`\n\tServer        *protocol.ServerEndpoint `protobuf:\"bytes,1,opt,name=server,proto3\" json:\"server,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *DestinationOverride) Reset() {\n\t*x = DestinationOverride{}\n\tmi := &file_proxy_freedom_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *DestinationOverride) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DestinationOverride) ProtoMessage() {}\n\nfunc (x *DestinationOverride) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_freedom_config_proto_msgTypes[0]\n\tif 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 DestinationOverride.ProtoReflect.Descriptor instead.\nfunc (*DestinationOverride) Descriptor() ([]byte, []int) {\n\treturn file_proxy_freedom_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *DestinationOverride) GetServer() *protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\ntype Config struct {\n\tstate          protoimpl.MessageState `protogen:\"open.v1\"`\n\tDomainStrategy Config_DomainStrategy  `protobuf:\"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.proxy.freedom.Config_DomainStrategy\" json:\"domain_strategy,omitempty\"`\n\t// Deprecated: Marked as deprecated in proxy/freedom/config.proto.\n\tTimeout             uint32               `protobuf:\"varint,2,opt,name=timeout,proto3\" json:\"timeout,omitempty\"`\n\tDestinationOverride *DestinationOverride `protobuf:\"bytes,3,opt,name=destination_override,json=destinationOverride,proto3\" json:\"destination_override,omitempty\"`\n\tUserLevel           uint32               `protobuf:\"varint,4,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tProtocolReplacement ProtocolReplacement  `protobuf:\"varint,5,opt,name=protocol_replacement,json=protocolReplacement,proto3,enum=v2ray.core.proxy.freedom.ProtocolReplacement\" json:\"protocol_replacement,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_freedom_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_freedom_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_freedom_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetDomainStrategy() Config_DomainStrategy {\n\tif x != nil {\n\t\treturn x.DomainStrategy\n\t}\n\treturn Config_AS_IS\n}\n\n// Deprecated: Marked as deprecated in proxy/freedom/config.proto.\nfunc (x *Config) GetTimeout() uint32 {\n\tif x != nil {\n\t\treturn x.Timeout\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetDestinationOverride() *DestinationOverride {\n\tif x != nil {\n\t\treturn x.DestinationOverride\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetProtocolReplacement() ProtocolReplacement {\n\tif x != nil {\n\t\treturn x.ProtocolReplacement\n\t}\n\treturn ProtocolReplacement_IDENTITY\n}\n\ntype SimplifiedConfig struct {\n\tstate               protoimpl.MessageState `protogen:\"open.v1\"`\n\tDestinationOverride *DestinationOverride   `protobuf:\"bytes,3,opt,name=destination_override,json=destinationOverride,proto3\" json:\"destination_override,omitempty\"`\n\tProtocolReplacement ProtocolReplacement    `protobuf:\"varint,5,opt,name=protocol_replacement,json=protocolReplacement,proto3,enum=v2ray.core.proxy.freedom.ProtocolReplacement\" json:\"protocol_replacement,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_freedom_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_freedom_config_proto_msgTypes[2]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_freedom_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SimplifiedConfig) GetDestinationOverride() *DestinationOverride {\n\tif x != nil {\n\t\treturn x.DestinationOverride\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetProtocolReplacement() ProtocolReplacement {\n\tif x != nil {\n\t\treturn x.ProtocolReplacement\n\t}\n\treturn ProtocolReplacement_IDENTITY\n}\n\nvar File_proxy_freedom_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_freedom_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1aproxy/freedom/config.proto\\x12\\x18v2ray.core.proxy.freedom\\x1a!common/protocol/server_spec.proto\\x1a common/protoext/extensions.proto\\\"Y\\n\" +\n\t\"\\x13DestinationOverride\\x12B\\n\" +\n\t\"\\x06server\\x18\\x01 \\x01(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x06server\\\"\\xa6\\x03\\n\" +\n\t\"\\x06Config\\x12X\\n\" +\n\t\"\\x0fdomain_strategy\\x18\\x01 \\x01(\\x0e2/.v2ray.core.proxy.freedom.Config.DomainStrategyR\\x0edomainStrategy\\x12\\x1c\\n\" +\n\t\"\\atimeout\\x18\\x02 \\x01(\\rB\\x02\\x18\\x01R\\atimeout\\x12`\\n\" +\n\t\"\\x14destination_override\\x18\\x03 \\x01(\\v2-.v2ray.core.proxy.freedom.DestinationOverrideR\\x13destinationOverride\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x04 \\x01(\\rR\\tuserLevel\\x12`\\n\" +\n\t\"\\x14protocol_replacement\\x18\\x05 \\x01(\\x0e2-.v2ray.core.proxy.freedom.ProtocolReplacementR\\x13protocolReplacement\\\"A\\n\" +\n\t\"\\x0eDomainStrategy\\x12\\t\\n\" +\n\t\"\\x05AS_IS\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06USE_IP\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aUSE_IP4\\x10\\x02\\x12\\v\\n\" +\n\t\"\\aUSE_IP6\\x10\\x03\\\"\\xef\\x01\\n\" +\n\t\"\\x10SimplifiedConfig\\x12`\\n\" +\n\t\"\\x14destination_override\\x18\\x03 \\x01(\\v2-.v2ray.core.proxy.freedom.DestinationOverrideR\\x13destinationOverride\\x12`\\n\" +\n\t\"\\x14protocol_replacement\\x18\\x05 \\x01(\\x0e2-.v2ray.core.proxy.freedom.ProtocolReplacementR\\x13protocolReplacement:\\x17\\x82\\xb5\\x18\\x13\\n\" +\n\t\"\\boutbound\\x12\\afreedom*A\\n\" +\n\t\"\\x13ProtocolReplacement\\x12\\f\\n\" +\n\t\"\\bIDENTITY\\x10\\x00\\x12\\r\\n\" +\n\t\"\\tFORCE_TCP\\x10\\x01\\x12\\r\\n\" +\n\t\"\\tFORCE_UDP\\x10\\x02Bi\\n\" +\n\t\"\\x1ccom.v2ray.core.proxy.freedomP\\x01Z,github.com/v2fly/v2ray-core/v5/proxy/freedom\\xaa\\x02\\x18V2Ray.Core.Proxy.Freedomb\\x06proto3\"\n\nvar (\n\tfile_proxy_freedom_config_proto_rawDescOnce sync.Once\n\tfile_proxy_freedom_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_freedom_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_freedom_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_freedom_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_freedom_config_proto_rawDesc), len(file_proxy_freedom_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_freedom_config_proto_rawDescData\n}\n\nvar file_proxy_freedom_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)\nvar file_proxy_freedom_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_proxy_freedom_config_proto_goTypes = []any{\n\t(ProtocolReplacement)(0),        // 0: v2ray.core.proxy.freedom.ProtocolReplacement\n\t(Config_DomainStrategy)(0),      // 1: v2ray.core.proxy.freedom.Config.DomainStrategy\n\t(*DestinationOverride)(nil),     // 2: v2ray.core.proxy.freedom.DestinationOverride\n\t(*Config)(nil),                  // 3: v2ray.core.proxy.freedom.Config\n\t(*SimplifiedConfig)(nil),        // 4: v2ray.core.proxy.freedom.SimplifiedConfig\n\t(*protocol.ServerEndpoint)(nil), // 5: v2ray.core.common.protocol.ServerEndpoint\n}\nvar file_proxy_freedom_config_proto_depIdxs = []int32{\n\t5, // 0: v2ray.core.proxy.freedom.DestinationOverride.server:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t1, // 1: v2ray.core.proxy.freedom.Config.domain_strategy:type_name -> v2ray.core.proxy.freedom.Config.DomainStrategy\n\t2, // 2: v2ray.core.proxy.freedom.Config.destination_override:type_name -> v2ray.core.proxy.freedom.DestinationOverride\n\t0, // 3: v2ray.core.proxy.freedom.Config.protocol_replacement:type_name -> v2ray.core.proxy.freedom.ProtocolReplacement\n\t2, // 4: v2ray.core.proxy.freedom.SimplifiedConfig.destination_override:type_name -> v2ray.core.proxy.freedom.DestinationOverride\n\t0, // 5: v2ray.core.proxy.freedom.SimplifiedConfig.protocol_replacement:type_name -> v2ray.core.proxy.freedom.ProtocolReplacement\n\t6, // [6:6] is the sub-list for method output_type\n\t6, // [6:6] is the sub-list for method input_type\n\t6, // [6:6] is the sub-list for extension type_name\n\t6, // [6:6] is the sub-list for extension extendee\n\t0, // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_freedom_config_proto_init() }\nfunc file_proxy_freedom_config_proto_init() {\n\tif File_proxy_freedom_config_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: unsafe.Slice(unsafe.StringData(file_proxy_freedom_config_proto_rawDesc), len(file_proxy_freedom_config_proto_rawDesc)),\n\t\t\tNumEnums:      2,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_freedom_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_freedom_config_proto_depIdxs,\n\t\tEnumInfos:         file_proxy_freedom_config_proto_enumTypes,\n\t\tMessageInfos:      file_proxy_freedom_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_freedom_config_proto = out.File\n\tfile_proxy_freedom_config_proto_goTypes = nil\n\tfile_proxy_freedom_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/freedom/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.freedom;\noption csharp_namespace = \"V2Ray.Core.Proxy.Freedom\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/freedom\";\noption java_package = \"com.v2ray.core.proxy.freedom\";\noption java_multiple_files = true;\n\nimport \"common/protocol/server_spec.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage DestinationOverride {\n  v2ray.core.common.protocol.ServerEndpoint server = 1;\n}\n\nenum ProtocolReplacement {\n  IDENTITY = 0;\n  FORCE_TCP = 1;\n  FORCE_UDP = 2;\n}\n\nmessage Config {\n  enum DomainStrategy {\n    AS_IS = 0;\n    USE_IP = 1;\n    USE_IP4 = 2;\n    USE_IP6 = 3;\n  }\n  DomainStrategy domain_strategy = 1;\n  uint32 timeout = 2 [deprecated = true];\n  DestinationOverride destination_override = 3;\n  uint32 user_level = 4;\n  ProtocolReplacement protocol_replacement = 5;\n}\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"freedom\";\n\n  DestinationOverride destination_override = 3;\n  ProtocolReplacement protocol_replacement = 5;\n}"
  },
  {
    "path": "proxy/freedom/errors.generated.go",
    "content": "package freedom\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/freedom/freedom.go",
    "content": "package freedom\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\th := new(Handler)\n\t\tif err := core.RequireFeatures(ctx, func(pm policy.Manager, d dns.Client) error {\n\t\t\treturn h.Init(config.(*Config), pm, d)\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn h, nil\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*SimplifiedConfig)\n\t\t_ = simplifiedServer\n\t\tfullConfig := &Config{\n\t\t\tDestinationOverride: simplifiedServer.DestinationOverride,\n\t\t\tProtocolReplacement: simplifiedServer.ProtocolReplacement,\n\t\t}\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n\n// Handler handles Freedom connections.\ntype Handler struct {\n\tpolicyManager policy.Manager\n\tdns           dns.Client\n\tconfig        *Config\n}\n\n// Init initializes the Handler with necessary parameters.\nfunc (h *Handler) Init(config *Config, pm policy.Manager, d dns.Client) error {\n\th.config = config\n\th.policyManager = pm\n\th.dns = d\n\n\treturn nil\n}\n\nfunc (h *Handler) policy() policy.Session {\n\tp := h.policyManager.ForLevel(h.config.UserLevel)\n\tif h.config.Timeout > 0 && h.config.UserLevel == 0 {\n\t\tp.Timeouts.ConnectionIdle = time.Duration(h.config.Timeout) * time.Second\n\t}\n\treturn p\n}\n\nfunc (h *Handler) resolveIP(ctx context.Context, domain string, localAddr net.Address) net.Address {\n\tips, err := dns.LookupIPWithOption(h.dns, domain, dns.IPOption{\n\t\tIPv4Enable: h.config.DomainStrategy == Config_USE_IP || h.config.DomainStrategy == Config_USE_IP4 || (localAddr != nil && localAddr.Family().IsIPv4()),\n\t\tIPv6Enable: h.config.DomainStrategy == Config_USE_IP || h.config.DomainStrategy == Config_USE_IP6 || (localAddr != nil && localAddr.Family().IsIPv6()),\n\t\tFakeEnable: false,\n\t})\n\tif err != nil {\n\t\tnewError(\"failed to get IP address for domain \", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\tif len(ips) == 0 {\n\t\treturn nil\n\t}\n\treturn net.IPAddress(ips[dice.Roll(len(ips))])\n}\n\nfunc isValidAddress(addr *net.IPOrDomain) bool {\n\tif addr == nil {\n\t\treturn false\n\t}\n\n\ta := addr.AsAddress()\n\treturn a != net.AnyIP\n}\n\n// Process implements proxy.Outbound.\nfunc (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified.\")\n\t}\n\tdestination := outbound.Target\n\tif h.config.DestinationOverride != nil {\n\t\tserver := h.config.DestinationOverride.Server\n\t\tif isValidAddress(server.Address) {\n\t\t\tdestination.Address = server.Address.AsAddress()\n\t\t}\n\t\tif server.Port != 0 {\n\t\t\tdestination.Port = net.Port(server.Port)\n\t\t}\n\t}\n\tif h.config.ProtocolReplacement != ProtocolReplacement_IDENTITY {\n\t\tif h.config.ProtocolReplacement == ProtocolReplacement_FORCE_TCP {\n\t\t\tdestination.Network = net.Network_TCP\n\t\t}\n\t\tif h.config.ProtocolReplacement == ProtocolReplacement_FORCE_UDP {\n\t\t\tdestination.Network = net.Network_UDP\n\t\t}\n\t}\n\tif h.config.useIP() {\n\t\toutbound.Resolver = func(ctx context.Context, domain string) net.Address {\n\t\t\treturn h.resolveIP(ctx, domain, dialer.Address())\n\t\t}\n\t}\n\tnewError(\"opening connection to \", destination).WriteToLog(session.ExportIDToError(ctx))\n\n\tinput := link.Reader\n\toutput := link.Writer\n\n\tvar conn internet.Connection\n\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\trawConn, err := dialer.Dial(ctx, destination)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconn = rawConn\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to open connection to \", destination).Base(err)\n\t}\n\tdefer conn.Close()\n\n\tplcy := h.policy()\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, plcy.Timeouts.ConnectionIdle)\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.DownlinkOnly)\n\n\t\tvar writer buf.Writer\n\t\tif destination.Network == net.Network_TCP {\n\t\t\twriter = buf.NewWriter(conn)\n\t\t} else {\n\t\t\twriter = &buf.SequentialWriter{Writer: conn}\n\t\t}\n\n\t\tif err := buf.Copy(input, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to process request\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.UplinkOnly)\n\n\t\tvar reader buf.Reader\n\t\tif destination.Network == net.Network_TCP && h.config.ProtocolReplacement == ProtocolReplacement_IDENTITY {\n\t\t\treader = buf.NewReader(conn)\n\t\t} else {\n\t\t\treader = buf.NewPacketReader(conn)\n\t\t}\n\t\tif err := buf.Copy(reader, output, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to process response\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, requestDone, task.OnSuccess(responseDone, task.Close(output))); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/http/client.go",
    "content": "package http\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/http2\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/bytespool\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n)\n\ntype Client struct {\n\tserverPicker       protocol.ServerPicker\n\tpolicyManager      policy.Manager\n\th1SkipWaitForReply bool\n}\n\ntype h2Conn struct {\n\trawConn net.Conn\n\th2Conn  *http2.ClientConn\n}\n\nvar (\n\tcachedH2Mutex sync.Mutex\n\tcachedH2Conns map[net.Destination]h2Conn\n)\n\n// NewClient create a new http client based on the given config.\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Server {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get server spec\").Base(err)\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\tif serverList.Size() == 0 {\n\t\treturn nil, newError(\"0 target server\")\n\t}\n\n\tv := core.MustFromContext(ctx)\n\treturn &Client{\n\t\tserverPicker:       protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager:      v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t\th1SkipWaitForReply: config.H1SkipWaitForReply,\n\t}, nil\n}\n\n// Process implements proxy.Outbound.Process. We first create a socket tunnel via HTTP CONNECT method, then redirect all inbound traffic to that tunnel.\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified.\")\n\t}\n\ttarget := outbound.Target\n\ttargetAddr := target.NetAddr()\n\n\tif target.Network == net.Network_UDP {\n\t\treturn newError(\"UDP is not supported by HTTP outbound\")\n\t}\n\n\tvar user *protocol.MemoryUser\n\tvar conn internet.Connection\n\n\tvar firstPayload []byte\n\n\tif reader, ok := link.Reader.(buf.TimeoutReader); ok {\n\t\t// 0-RTT optimization for HTTP/2: If the payload comes very soon, it can be\n\t\t// transmitted together. Note we should not get stuck here, as the payload may\n\t\t// not exist (considering to access MySQL database via a HTTP proxy, where the\n\t\t// server sends hello to the client first).\n\t\twaitTime := proxy.FirstPayloadTimeout\n\t\tif c.h1SkipWaitForReply {\n\t\t\t// Some server require first write to be present in client hello.\n\t\t\t// Increase timeout to if the client have explicitly requested to skip waiting for reply.\n\t\t\twaitTime = time.Second\n\t\t}\n\t\tif mbuf, _ := reader.ReadMultiBufferTimeout(waitTime); mbuf != nil {\n\t\t\tmlen := mbuf.Len()\n\t\t\tfirstPayload = bytespool.Alloc(mlen)\n\t\t\tmbuf, _ = buf.SplitBytes(mbuf, firstPayload)\n\t\t\tfirstPayload = firstPayload[:mlen]\n\n\t\t\tbuf.ReleaseMulti(mbuf)\n\t\t\tdefer bytespool.Free(firstPayload)\n\t\t}\n\t}\n\n\tif err := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tserver := c.serverPicker.PickServer()\n\t\tdest := server.Destination()\n\t\tuser = server.PickUser()\n\n\t\tnetConn, firstResp, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer, firstPayload, c.h1SkipWaitForReply)\n\t\tif netConn != nil {\n\t\t\tif _, ok := netConn.(*http2Conn); !ok && !c.h1SkipWaitForReply {\n\t\t\t\tif _, err := netConn.Write(firstPayload); err != nil {\n\t\t\t\t\tnetConn.Close()\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tif firstResp != nil {\n\t\t\t\tif err := link.Writer.WriteMultiBuffer(firstResp); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tconn = internet.Connection(netConn)\n\t\t}\n\t\treturn err\n\t}); err != nil {\n\t\treturn newError(\"failed to find an available destination\").Base(err)\n\t}\n\n\tdefer func() {\n\t\tif err := conn.Close(); err != nil {\n\t\t\tnewError(\"failed to closed connection\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t}()\n\n\tp := c.policyManager.ForLevel(0)\n\tif user != nil {\n\t\tp = c.policyManager.ForLevel(user.Level)\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, p.Timeouts.ConnectionIdle)\n\n\trequestFunc := func() error {\n\t\tdefer timer.SetTimeout(p.Timeouts.DownlinkOnly)\n\t\treturn buf.Copy(link.Reader, buf.NewWriter(conn), buf.UpdateActivity(timer))\n\t}\n\tresponseFunc := func() error {\n\t\tdefer timer.SetTimeout(p.Timeouts.UplinkOnly)\n\t\treturn buf.Copy(buf.NewReader(conn), link.Writer, buf.UpdateActivity(timer))\n\t}\n\n\tresponseDonePost := task.OnSuccess(responseFunc, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestFunc, responseDonePost); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\n// setUpHTTPTunnel will create a socket tunnel via HTTP CONNECT method\nfunc setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, user *protocol.MemoryUser, dialer internet.Dialer, firstPayload []byte, writeFirstPayloadInH1 bool,\n) (net.Conn, buf.MultiBuffer, error) {\n\treq := &http.Request{\n\t\tMethod: http.MethodConnect,\n\t\tURL:    &url.URL{Host: target},\n\t\tHeader: make(http.Header),\n\t\tHost:   target,\n\t}\n\n\tif user != nil && user.Account != nil {\n\t\taccount := user.Account.(*Account)\n\t\tauth := account.GetUsername() + \":\" + account.GetPassword()\n\t\treq.Header.Set(\"Proxy-Authorization\", \"Basic \"+base64.StdEncoding.EncodeToString([]byte(auth)))\n\t}\n\n\tconnectHTTP1 := func(rawConn net.Conn) (net.Conn, buf.MultiBuffer, error) {\n\t\treq.Header.Set(\"Proxy-Connection\", \"Keep-Alive\")\n\n\t\tif !writeFirstPayloadInH1 {\n\t\t\terr := req.Write(rawConn)\n\t\t\tif err != nil {\n\t\t\t\trawConn.Close()\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer := bytes.NewBuffer(nil)\n\t\t\terr := req.Write(buffer)\n\t\t\tif err != nil {\n\t\t\t\trawConn.Close()\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t\t_, err = io.Copy(buffer, bytes.NewReader(firstPayload))\n\t\t\tif err != nil {\n\t\t\t\trawConn.Close()\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t\t_, err = rawConn.Write(buffer.Bytes())\n\t\t\tif err != nil {\n\t\t\t\trawConn.Close()\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t}\n\t\tbufferedReader := bufio.NewReader(rawConn)\n\t\tresp, err := http.ReadResponse(bufferedReader, req)\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\trawConn.Close()\n\t\t\treturn nil, nil, newError(\"Proxy responded with non 200 code: \" + resp.Status)\n\t\t}\n\t\tif bufferedReader.Buffered() > 0 {\n\t\t\tpayload, err := buf.ReadFrom(io.LimitReader(bufferedReader, int64(bufferedReader.Buffered())))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, newError(\"unable to drain buffer: \").Base(err)\n\t\t\t}\n\t\t\treturn rawConn, payload, nil\n\t\t}\n\t\treturn rawConn, nil, nil\n\t}\n\n\tconnectHTTP2 := func(rawConn net.Conn, h2clientConn *http2.ClientConn) (net.Conn, error) {\n\t\tpr, pw := io.Pipe()\n\t\treq.Body = pr\n\n\t\tvar pErr error\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(1)\n\n\t\tgo func() {\n\t\t\t_, pErr = pw.Write(firstPayload)\n\t\t\twg.Done()\n\t\t}()\n\n\t\tresp, err := h2clientConn.RoundTrip(req) // nolint: bodyclose\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, err\n\t\t}\n\n\t\twg.Wait()\n\t\tif pErr != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, pErr\n\t\t}\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\trawConn.Close()\n\t\t\treturn nil, newError(\"Proxy responded with non 200 code: \" + resp.Status)\n\t\t}\n\t\treturn newHTTP2Conn(rawConn, pw, resp.Body), nil\n\t}\n\n\tcachedH2Mutex.Lock()\n\tcachedConn, cachedConnFound := cachedH2Conns[dest]\n\tcachedH2Mutex.Unlock()\n\n\tif cachedConnFound {\n\t\trc, cc := cachedConn.rawConn, cachedConn.h2Conn\n\t\tif cc.CanTakeNewRequest() {\n\t\t\tproxyConn, err := connectHTTP2(rc, cc)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\n\t\t\treturn proxyConn, nil, nil\n\t\t}\n\t}\n\n\trawConn, err := dialer.Dial(ctx, dest)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tiConn := rawConn\n\tif statConn, ok := iConn.(*internet.StatCouterConnection); ok {\n\t\tiConn = statConn.Connection\n\t}\n\n\tnextProto := \"\"\n\tif connALPNGetter, ok := iConn.(security.ConnectionApplicationProtocol); ok {\n\t\tnextProto, err = connALPNGetter.GetConnectionApplicationProtocol()\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\n\tswitch nextProto {\n\tcase \"\", \"http/1.1\":\n\t\treturn connectHTTP1(rawConn)\n\tcase \"h2\":\n\t\tt := http2.Transport{}\n\t\th2clientConn, err := t.NewClientConn(rawConn)\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tproxyConn, err := connectHTTP2(rawConn, h2clientConn)\n\t\tif err != nil {\n\t\t\trawConn.Close()\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tcachedH2Mutex.Lock()\n\t\tif cachedH2Conns == nil {\n\t\t\tcachedH2Conns = make(map[net.Destination]h2Conn)\n\t\t}\n\n\t\tcachedH2Conns[dest] = h2Conn{\n\t\t\trawConn: rawConn,\n\t\t\th2Conn:  h2clientConn,\n\t\t}\n\t\tcachedH2Mutex.Unlock()\n\n\t\treturn proxyConn, nil, err\n\tdefault:\n\t\treturn nil, nil, newError(\"negotiated unsupported application layer protocol: \" + nextProto)\n\t}\n}\n\nfunc newHTTP2Conn(c net.Conn, pipedReqBody *io.PipeWriter, respBody io.ReadCloser) net.Conn {\n\treturn &http2Conn{Conn: c, in: pipedReqBody, out: respBody}\n}\n\ntype http2Conn struct {\n\tnet.Conn\n\tin  *io.PipeWriter\n\tout io.ReadCloser\n}\n\nfunc (h *http2Conn) Read(p []byte) (n int, err error) {\n\treturn h.out.Read(p)\n}\n\nfunc (h *http2Conn) Write(p []byte) (n int, err error) {\n\treturn h.in.Write(p)\n}\n\nfunc (h *http2Conn) Close() error {\n\th.in.Close()\n\treturn h.out.Close()\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewClient(ctx, config.(*ClientConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/http/config.go",
    "content": "package http\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nfunc (a *Account) Equals(another protocol.Account) bool {\n\tif account, ok := another.(*Account); ok {\n\t\treturn a.Username == account.Username\n\t}\n\treturn false\n}\n\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\treturn a, nil\n}\n\nfunc (sc *ServerConfig) HasAccount(username, password string) bool {\n\tif sc.Accounts == nil {\n\t\treturn false\n\t}\n\n\tp, found := sc.Accounts[username]\n\tif !found {\n\t\treturn false\n\t}\n\treturn p == password\n}\n"
  },
  {
    "path": "proxy/http/config.pb.go",
    "content": "package http\n\nimport (\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Account struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUsername      string                 `protobuf:\"bytes,1,opt,name=username,proto3\" json:\"username,omitempty\"`\n\tPassword      string                 `protobuf:\"bytes,2,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_http_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_http_config_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_http_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Account) GetUsername() string {\n\tif x != nil {\n\t\treturn x.Username\n\t}\n\treturn \"\"\n}\n\nfunc (x *Account) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\n// Config for HTTP proxy server.\ntype ServerConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Deprecated: Marked as deprecated in proxy/http/config.proto.\n\tTimeout          uint32            `protobuf:\"varint,1,opt,name=timeout,proto3\" json:\"timeout,omitempty\"`\n\tAccounts         map[string]string `protobuf:\"bytes,2,rep,name=accounts,proto3\" json:\"accounts,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tAllowTransparent bool              `protobuf:\"varint,3,opt,name=allow_transparent,json=allowTransparent,proto3\" json:\"allow_transparent,omitempty\"`\n\tUserLevel        uint32            `protobuf:\"varint,4,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_http_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_http_config_proto_msgTypes[1]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_http_config_proto_rawDescGZIP(), []int{1}\n}\n\n// Deprecated: Marked as deprecated in proxy/http/config.proto.\nfunc (x *ServerConfig) GetTimeout() uint32 {\n\tif x != nil {\n\t\treturn x.Timeout\n\t}\n\treturn 0\n}\n\nfunc (x *ServerConfig) GetAccounts() map[string]string {\n\tif x != nil {\n\t\treturn x.Accounts\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetAllowTransparent() bool {\n\tif x != nil {\n\t\treturn x.AllowTransparent\n\t}\n\treturn false\n}\n\nfunc (x *ServerConfig) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\n// ClientConfig is the protobuf config for HTTP proxy client.\ntype ClientConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Sever is a list of HTTP server addresses.\n\tServer             []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=server,proto3\" json:\"server,omitempty\"`\n\tH1SkipWaitForReply bool                       `protobuf:\"varint,2,opt,name=h1_skip_wait_for_reply,json=h1SkipWaitForReply,proto3\" json:\"h1_skip_wait_for_reply,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_http_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_http_config_proto_msgTypes[2]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_http_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetH1SkipWaitForReply() bool {\n\tif x != nil {\n\t\treturn x.H1SkipWaitForReply\n\t}\n\treturn false\n}\n\nvar File_proxy_http_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_http_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x17proxy/http/config.proto\\x12\\x15v2ray.core.proxy.http\\x1a!common/protocol/server_spec.proto\\\"A\\n\" +\n\t\"\\aAccount\\x12\\x1a\\n\" +\n\t\"\\busername\\x18\\x01 \\x01(\\tR\\busername\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x02 \\x01(\\tR\\bpassword\\\"\\x84\\x02\\n\" +\n\t\"\\fServerConfig\\x12\\x1c\\n\" +\n\t\"\\atimeout\\x18\\x01 \\x01(\\rB\\x02\\x18\\x01R\\atimeout\\x12M\\n\" +\n\t\"\\baccounts\\x18\\x02 \\x03(\\v21.v2ray.core.proxy.http.ServerConfig.AccountsEntryR\\baccounts\\x12+\\n\" +\n\t\"\\x11allow_transparent\\x18\\x03 \\x01(\\bR\\x10allowTransparent\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x04 \\x01(\\rR\\tuserLevel\\x1a;\\n\" +\n\t\"\\rAccountsEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01\\\"\\x86\\x01\\n\" +\n\t\"\\fClientConfig\\x12B\\n\" +\n\t\"\\x06server\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x06server\\x122\\n\" +\n\t\"\\x16h1_skip_wait_for_reply\\x18\\x02 \\x01(\\bR\\x12h1SkipWaitForReplyB`\\n\" +\n\t\"\\x19com.v2ray.core.proxy.httpP\\x01Z)github.com/v2fly/v2ray-core/v5/proxy/http\\xaa\\x02\\x15V2Ray.Core.Proxy.Httpb\\x06proto3\"\n\nvar (\n\tfile_proxy_http_config_proto_rawDescOnce sync.Once\n\tfile_proxy_http_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_http_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_http_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_http_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_http_config_proto_rawDesc), len(file_proxy_http_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_http_config_proto_rawDescData\n}\n\nvar file_proxy_http_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_proxy_http_config_proto_goTypes = []any{\n\t(*Account)(nil),                 // 0: v2ray.core.proxy.http.Account\n\t(*ServerConfig)(nil),            // 1: v2ray.core.proxy.http.ServerConfig\n\t(*ClientConfig)(nil),            // 2: v2ray.core.proxy.http.ClientConfig\n\tnil,                             // 3: v2ray.core.proxy.http.ServerConfig.AccountsEntry\n\t(*protocol.ServerEndpoint)(nil), // 4: v2ray.core.common.protocol.ServerEndpoint\n}\nvar file_proxy_http_config_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.proxy.http.ServerConfig.accounts:type_name -> v2ray.core.proxy.http.ServerConfig.AccountsEntry\n\t4, // 1: v2ray.core.proxy.http.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_http_config_proto_init() }\nfunc file_proxy_http_config_proto_init() {\n\tif File_proxy_http_config_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: unsafe.Slice(unsafe.StringData(file_proxy_http_config_proto_rawDesc), len(file_proxy_http_config_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_proxy_http_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_http_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_http_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_http_config_proto = out.File\n\tfile_proxy_http_config_proto_goTypes = nil\n\tfile_proxy_http_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/http/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.http;\noption csharp_namespace = \"V2Ray.Core.Proxy.Http\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/http\";\noption java_package = \"com.v2ray.core.proxy.http\";\noption java_multiple_files = true;\n\nimport \"common/protocol/server_spec.proto\";\n\nmessage Account {\n  string username = 1;\n  string password = 2;\n}\n\n// Config for HTTP proxy server.\nmessage ServerConfig {\n  uint32 timeout = 1 [deprecated = true];\n  map<string, string> accounts = 2;\n  bool allow_transparent = 3;\n  uint32 user_level = 4;\n}\n\n// ClientConfig is the protobuf config for HTTP proxy client.\nmessage ClientConfig {\n  // Sever is a list of HTTP server addresses.\n  repeated v2ray.core.common.protocol.ServerEndpoint server = 1;\n  bool h1_skip_wait_for_reply = 2;\n}\n"
  },
  {
    "path": "proxy/http/errors.generated.go",
    "content": "package http\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/http/http.go",
    "content": "package http\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/http/server.go",
    "content": "package http\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\thttp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// Server is an HTTP proxy server.\ntype Server struct {\n\tconfig        *ServerConfig\n\tpolicyManager policy.Manager\n}\n\n// NewServer creates a new HTTP inbound handler.\nfunc NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {\n\tv := core.MustFromContext(ctx)\n\ts := &Server{\n\t\tconfig:        config,\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\n\treturn s, nil\n}\n\nfunc (s *Server) policy() policy.Session {\n\tconfig := s.config\n\tp := s.policyManager.ForLevel(config.UserLevel)\n\tif config.Timeout > 0 && config.UserLevel == 0 {\n\t\tp.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second\n\t}\n\treturn p\n}\n\n// Network implements proxy.Inbound.\nfunc (*Server) Network() []net.Network {\n\treturn []net.Network{net.Network_TCP, net.Network_UNIX}\n}\n\nfunc isTimeout(err error) bool {\n\tnerr, ok := errors.Cause(err).(net.Error)\n\treturn ok && nerr.Timeout()\n}\n\nfunc parseBasicAuth(auth string) (username, password string, ok bool) {\n\tconst prefix = \"Basic \"\n\tif !strings.HasPrefix(auth, prefix) {\n\t\treturn\n\t}\n\tc, err := base64.StdEncoding.DecodeString(auth[len(prefix):])\n\tif err != nil {\n\t\treturn\n\t}\n\tcs := string(c)\n\ts := strings.IndexByte(cs, ':')\n\tif s < 0 {\n\t\treturn\n\t}\n\treturn cs[:s], cs[s+1:], true\n}\n\ntype readerOnly struct {\n\tio.Reader\n}\n\nfunc (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound != nil {\n\t\tinbound.User = &protocol.MemoryUser{\n\t\t\tLevel: s.config.UserLevel,\n\t\t}\n\t}\n\n\treader := bufio.NewReaderSize(readerOnly{conn}, buf.Size)\n\nStart:\n\tif err := conn.SetReadDeadline(time.Now().Add(s.policy().Timeouts.Handshake)); err != nil {\n\t\tnewError(\"failed to set read deadline\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\trequest, err := http.ReadRequest(reader)\n\tif err != nil {\n\t\ttrace := newError(\"failed to read http request\").Base(err)\n\t\tif errors.Cause(err) != io.EOF && !isTimeout(errors.Cause(err)) {\n\t\t\ttrace.AtWarning()\n\t\t}\n\t\treturn trace\n\t}\n\n\tif len(s.config.Accounts) > 0 {\n\t\tuser, pass, ok := parseBasicAuth(request.Header.Get(\"Proxy-Authorization\"))\n\t\tif !ok || !s.config.HasAccount(user, pass) {\n\t\t\treturn common.Error2(conn.Write([]byte(\"HTTP/1.1 407 Proxy Authentication Required\\r\\nProxy-Authenticate: Basic realm=\\\"proxy\\\"\\r\\n\\r\\n\")))\n\t\t}\n\t\tif inbound != nil {\n\t\t\tinbound.User.Email = user\n\t\t}\n\t}\n\n\tnewError(\"request to Method [\", request.Method, \"] Host [\", request.Host, \"] with URL [\", request.URL, \"]\").WriteToLog(session.ExportIDToError(ctx))\n\tif err := conn.SetReadDeadline(time.Time{}); err != nil {\n\t\tnewError(\"failed to clear read deadline\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tdefaultPort := net.Port(80)\n\tif strings.EqualFold(request.URL.Scheme, \"https\") {\n\t\tdefaultPort = net.Port(443)\n\t}\n\thost := request.Host\n\tif host == \"\" {\n\t\thost = request.URL.Host\n\t}\n\tdest, err := http_proto.ParseHost(host, defaultPort)\n\tif err != nil {\n\t\treturn newError(\"malformed proxy host: \", host).AtWarning().Base(err)\n\t}\n\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\tFrom:   conn.RemoteAddr(),\n\t\tTo:     request.URL,\n\t\tStatus: log.AccessAccepted,\n\t\tReason: \"\",\n\t})\n\n\tif strings.EqualFold(request.Method, \"CONNECT\") {\n\t\treturn s.handleConnect(ctx, request, reader, conn, dest, dispatcher)\n\t}\n\n\tkeepAlive := (strings.TrimSpace(strings.ToLower(request.Header.Get(\"Proxy-Connection\"))) == \"keep-alive\")\n\n\terr = s.handlePlainHTTP(ctx, request, conn, dest, dispatcher)\n\tif err == errWaitAnother {\n\t\tif keepAlive {\n\t\t\tgoto Start\n\t\t}\n\t\terr = nil\n\t}\n\n\treturn err\n}\n\nfunc (s *Server) handleConnect(ctx context.Context, _ *http.Request, reader *bufio.Reader, conn internet.Connection, dest net.Destination, dispatcher routing.Dispatcher) error {\n\t_, err := conn.Write([]byte(\"HTTP/1.1 200 Connection established\\r\\n\\r\\n\"))\n\tif err != nil {\n\t\treturn newError(\"failed to write back OK response\").Base(err)\n\t}\n\n\tplcy := s.policy()\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, plcy.Timeouts.ConnectionIdle)\n\n\tctx = policy.ContextWithBufferPolicy(ctx, plcy.Buffer)\n\tlink, err := dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif reader.Buffered() > 0 {\n\t\tpayload, err := buf.ReadFrom(io.LimitReader(reader, int64(reader.Buffered())))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := link.Writer.WriteMultiBuffer(payload); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treader = nil\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.DownlinkOnly)\n\n\t\treturn buf.Copy(buf.NewReader(conn), link.Writer, buf.UpdateActivity(timer))\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.UplinkOnly)\n\n\t\tv2writer := buf.NewWriter(conn)\n\t\tif err := buf.Copy(link.Reader, v2writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tcloseWriter := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, closeWriter, responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nvar errWaitAnother = newError(\"keep alive\")\n\nfunc (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, writer io.Writer, dest net.Destination, dispatcher routing.Dispatcher) error {\n\tif !s.config.AllowTransparent && request.URL.Host == \"\" {\n\t\t// RFC 2068 (HTTP/1.1) requires URL to be absolute URL in HTTP proxy.\n\t\tresponse := &http.Response{\n\t\t\tStatus:        \"Bad Request\",\n\t\t\tStatusCode:    400,\n\t\t\tProto:         \"HTTP/1.1\",\n\t\t\tProtoMajor:    1,\n\t\t\tProtoMinor:    1,\n\t\t\tHeader:        http.Header(make(map[string][]string)),\n\t\t\tBody:          nil,\n\t\t\tContentLength: 0,\n\t\t\tClose:         true,\n\t\t}\n\t\tresponse.Header.Set(\"Proxy-Connection\", \"close\")\n\t\tresponse.Header.Set(\"Connection\", \"close\")\n\t\treturn response.Write(writer)\n\t}\n\n\tif len(request.URL.Host) > 0 {\n\t\trequest.Host = request.URL.Host\n\t}\n\thttp_proto.RemoveHopByHopHeaders(request.Header)\n\n\t// Prevent UA from being set to golang's default ones\n\tif request.Header.Get(\"User-Agent\") == \"\" {\n\t\trequest.Header.Set(\"User-Agent\", \"\")\n\t}\n\n\tcontent := &session.Content{}\n\n\tcontent.SetAttribute(\":method\", strings.ToUpper(request.Method))\n\tcontent.SetAttribute(\":path\", request.URL.Path)\n\tfor key := range request.Header {\n\t\tvalue := request.Header.Get(key)\n\t\tcontent.SetAttribute(strings.ToLower(key), value)\n\t}\n\n\tctx = session.ContextWithContent(ctx, content)\n\n\tlink, err := dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Plain HTTP request is not a stream. The request always finishes before response. Hence, request has to be closed later.\n\tdefer common.Close(link.Writer)\n\tvar result error = errWaitAnother\n\n\trequestDone := func() error {\n\t\trequest.Header.Set(\"Connection\", \"close\")\n\n\t\trequestWriter := buf.NewBufferedWriter(link.Writer)\n\t\tcommon.Must(requestWriter.SetBuffered(false))\n\t\tif err := request.Write(requestWriter); err != nil {\n\t\t\treturn newError(\"failed to write whole request\").Base(err).AtWarning()\n\t\t}\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tresponseReader := bufio.NewReaderSize(&buf.BufferedReader{Reader: link.Reader}, buf.Size)\n\t\tresponse, err := readResponseAndHandle100Continue(responseReader, request, writer)\n\t\tif err == nil {\n\t\t\thttp_proto.RemoveHopByHopHeaders(response.Header)\n\t\t\tif response.ContentLength >= 0 {\n\t\t\t\tresponse.Header.Set(\"Proxy-Connection\", \"keep-alive\")\n\t\t\t\tresponse.Header.Set(\"Connection\", \"keep-alive\")\n\t\t\t\tresponse.Header.Set(\"Keep-Alive\", \"timeout=4\")\n\t\t\t\tresponse.Close = false\n\t\t\t} else {\n\t\t\t\tresponse.Close = true\n\t\t\t\tresult = nil\n\t\t\t}\n\t\t\tdefer response.Body.Close()\n\t\t} else {\n\t\t\tnewError(\"failed to read response from \", request.Host).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t\tresponse = &http.Response{\n\t\t\t\tStatus:        \"Service Unavailable\",\n\t\t\t\tStatusCode:    503,\n\t\t\t\tProto:         \"HTTP/1.1\",\n\t\t\t\tProtoMajor:    1,\n\t\t\t\tProtoMinor:    1,\n\t\t\t\tHeader:        http.Header(make(map[string][]string)),\n\t\t\t\tBody:          nil,\n\t\t\t\tContentLength: 0,\n\t\t\t\tClose:         true,\n\t\t\t}\n\t\t\tresponse.Header.Set(\"Connection\", \"close\")\n\t\t\tresponse.Header.Set(\"Proxy-Connection\", \"close\")\n\t\t}\n\t\tif err := response.Write(writer); err != nil {\n\t\t\treturn newError(\"failed to write response\").Base(err).AtWarning()\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, requestDone, responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn result\n}\n\n// Sometimes, server might send 1xx response to client\n// it should not be processed by http proxy handler, just forward it to client\nfunc readResponseAndHandle100Continue(r *bufio.Reader, req *http.Request, writer io.Writer) (*http.Response, error) {\n\t// have a little look of response\n\tpeekBytes, err := r.Peek(56)\n\tif err == nil || err == bufio.ErrBufferFull {\n\t\tstr := string(peekBytes)\n\t\tResponseLine := strings.Split(str, \"\\r\\n\")[0]\n\t\t_, status, _ := strings.Cut(ResponseLine, \" \")\n\t\t// only handle 1xx response\n\t\tif strings.HasPrefix(status, \"1\") {\n\t\t\tResponseHeader1xx := []byte{}\n\t\t\t// read until \\r\\n\\r\\n (end of http response header)\n\t\t\tfor {\n\t\t\t\tdata, err := r.ReadSlice('\\n')\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, newError(\"failed to read http 1xx response\").Base(err).AtError()\n\t\t\t\t}\n\t\t\t\tResponseHeader1xx = append(ResponseHeader1xx, data...)\n\t\t\t\tif bytes.Equal(ResponseHeader1xx[len(ResponseHeader1xx)-4:], []byte{'\\r', '\\n', '\\r', '\\n'}) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif len(ResponseHeader1xx) > 1024 {\n\t\t\t\t\treturn nil, newError(\"too big http 1xx response\").AtError()\n\t\t\t\t}\n\t\t\t}\n\t\t\twriter.Write(ResponseHeader1xx)\n\t\t}\n\t}\n\treturn http.ReadResponse(r, req)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServer(ctx, config.(*ServerConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/http/simplified/config.go",
    "content": "package simplified\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/http\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*ServerConfig)\n\t\t_ = simplifiedServer\n\t\tfullServer := &http.ServerConfig{}\n\t\treturn common.CreateObject(ctx, fullServer)\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedClient := config.(*ClientConfig)\n\t\tfullClient := &http.ClientConfig{\n\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t{\n\t\t\t\t\tAddress: simplifiedClient.Address,\n\t\t\t\t\tPort:    simplifiedClient.Port,\n\t\t\t\t},\n\t\t\t},\n\t\t\tH1SkipWaitForReply: simplifiedClient.H1SkipWaitForReply,\n\t\t}\n\t\treturn common.CreateObject(ctx, fullClient)\n\t}))\n}\n"
  },
  {
    "path": "proxy/http/simplified/config.pb.go",
    "content": "package simplified\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ServerConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_http_simplified_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_http_simplified_config_proto_msgTypes[0]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_http_simplified_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype ClientConfig struct {\n\tstate              protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress            *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort               uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tH1SkipWaitForReply bool                   `protobuf:\"varint,3,opt,name=h1_skip_wait_for_reply,json=h1SkipWaitForReply,proto3\" json:\"h1_skip_wait_for_reply,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_http_simplified_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_http_simplified_config_proto_msgTypes[1]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_http_simplified_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ClientConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetH1SkipWaitForReply() bool {\n\tif x != nil {\n\t\treturn x.H1SkipWaitForReply\n\t}\n\treturn false\n}\n\nvar File_proxy_http_simplified_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_http_simplified_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\\"proxy/http/simplified/config.proto\\x12 v2ray.core.proxy.http.simplified\\x1a common/protoext/extensions.proto\\x1a\\x18common/net/address.proto\\\"#\\n\" +\n\t\"\\fServerConfig:\\x13\\x82\\xb5\\x18\\x0f\\n\" +\n\t\"\\ainbound\\x12\\x04http\\\"\\xad\\x01\\n\" +\n\t\"\\fClientConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x122\\n\" +\n\t\"\\x16h1_skip_wait_for_reply\\x18\\x03 \\x01(\\bR\\x12h1SkipWaitForReply:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\boutbound\\x12\\x04http\\x90\\xff)\\x01B\\x81\\x01\\n\" +\n\t\"$com.v2ray.core.proxy.http.simplifiedP\\x01Z4github.com/v2fly/v2ray-core/v5/proxy/http/simplified\\xaa\\x02 V2Ray.Core.Proxy.Http.Simplifiedb\\x06proto3\"\n\nvar (\n\tfile_proxy_http_simplified_config_proto_rawDescOnce sync.Once\n\tfile_proxy_http_simplified_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_http_simplified_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_http_simplified_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_http_simplified_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_http_simplified_config_proto_rawDesc), len(file_proxy_http_simplified_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_http_simplified_config_proto_rawDescData\n}\n\nvar file_proxy_http_simplified_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_http_simplified_config_proto_goTypes = []any{\n\t(*ServerConfig)(nil),   // 0: v2ray.core.proxy.http.simplified.ServerConfig\n\t(*ClientConfig)(nil),   // 1: v2ray.core.proxy.http.simplified.ClientConfig\n\t(*net.IPOrDomain)(nil), // 2: v2ray.core.common.net.IPOrDomain\n}\nvar file_proxy_http_simplified_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.http.simplified.ClientConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_http_simplified_config_proto_init() }\nfunc file_proxy_http_simplified_config_proto_init() {\n\tif File_proxy_http_simplified_config_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: unsafe.Slice(unsafe.StringData(file_proxy_http_simplified_config_proto_rawDesc), len(file_proxy_http_simplified_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_http_simplified_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_http_simplified_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_http_simplified_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_http_simplified_config_proto = out.File\n\tfile_proxy_http_simplified_config_proto_goTypes = nil\n\tfile_proxy_http_simplified_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/http/simplified/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.http.simplified;\noption csharp_namespace = \"V2Ray.Core.Proxy.Http.Simplified\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/http/simplified\";\noption java_package = \"com.v2ray.core.proxy.http.simplified\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"common/net/address.proto\";\n\nmessage ServerConfig{\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"http\";\n}\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"http\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  bool h1_skip_wait_for_reply = 3;\n}"
  },
  {
    "path": "proxy/hysteria2/client.go",
    "content": "package hysteria2\n\nimport (\n\t\"context\"\n\n\thyProtocol \"github.com/v2fly/hysteria/core/v2/international/protocol\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\thyTransport \"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// Client is an inbound handler\ntype Client struct {\n\tserverPicker  protocol.ServerPicker\n\tpolicyManager policy.Manager\n}\n\n// NewClient create a new client.\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Server {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse server spec\").Base(err)\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\tif serverList.Size() == 0 {\n\t\treturn nil, newError(\"0 server\")\n\t}\n\n\tv := core.MustFromContext(ctx)\n\tclient := &Client{\n\t\tserverPicker:  protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\treturn client, nil\n}\n\n// Process implements OutboundHandler.Process().\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\")\n\t}\n\tdestination := outbound.Target\n\tnetwork := destination.Network\n\n\tvar server *protocol.ServerSpec\n\tvar conn internet.Connection\n\n\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tserver = c.serverPicker.PickServer()\n\t\trawConn, err := dialer.Dial(ctx, server.Destination())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tconn = rawConn\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to find an available destination\").AtWarning().Base(err)\n\t}\n\tnewError(\"tunneling request to \", destination, \" via \", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx))\n\n\tdefer conn.Close()\n\n\tiConn := conn\n\tif statConn, ok := conn.(*internet.StatCouterConnection); ok {\n\t\tiConn = statConn.Connection // will not count the UDP traffic.\n\t}\n\thyConn, IsHy2Transport := iConn.(*hyTransport.HyConn)\n\n\tif !IsHy2Transport && network == net.Network_UDP {\n\t\t// hysteria2 need to use udp extension to proxy UDP.\n\t\treturn newError(hyTransport.CanNotUseUDPExtension)\n\t}\n\n\tuser := server.PickUser()\n\tuserLevel := uint32(0)\n\tif user != nil {\n\t\tuserLevel = user.Level\n\t}\n\tsessionPolicy := c.policyManager.ForLevel(userLevel)\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\tpostRequest := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\t\tvar buffer [2048]byte\n\t\t\tn, addr, err := packetConn.ReadFrom(buffer[:])\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to read a packet\").Base(err)\n\t\t\t}\n\t\t\tdest := net.DestinationFromAddr(addr)\n\n\t\t\tbufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\t\tconnWriter := &ConnWriter{Writer: bufferWriter, Target: dest}\n\t\t\tpacketWriter := &PacketWriter{Writer: connWriter, Target: dest, HyConn: hyConn}\n\n\t\t\t// write some request payload to buffer\n\t\t\tif _, err := packetWriter.WriteTo(buffer[:n], addr); err != nil {\n\t\t\t\treturn newError(\"failed to write a request payload\").Base(err)\n\t\t\t}\n\n\t\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\t\tif err = bufferWriter.SetBuffered(false); err != nil {\n\t\t\t\treturn newError(\"failed to flush payload\").Base(err).AtWarning()\n\t\t\t}\n\n\t\t\treturn udp.CopyPacketConn(packetWriter, packetConn, udp.UpdateActivity(timer))\n\t\t}\n\n\t\tgetResponse := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\t\tpacketReader := &PacketReader{Reader: conn, HyConn: hyConn}\n\t\t\tpacketConnectionReader := &PacketConnectionReader{reader: packetReader}\n\n\t\t\treturn udp.CopyPacketConn(packetConn, packetConnectionReader, udp.UpdateActivity(timer))\n\t\t}\n\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tpostRequest := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tvar bodyWriter buf.Writer\n\t\tbufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\tconnWriter := &ConnWriter{Writer: bufferWriter, Target: destination}\n\t\tbodyWriter = connWriter\n\n\t\tif network == net.Network_UDP {\n\t\t\tbodyWriter = &PacketWriter{Writer: connWriter, Target: destination, HyConn: hyConn}\n\t\t} else {\n\t\t\t// write some request payload to buffer\n\t\t\terr = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout)\n\t\t\tswitch err {\n\t\t\tcase buf.ErrNotTimeoutReader, buf.ErrReadTimeout:\n\t\t\t\tif err := connWriter.WriteTCPHeader(); err != nil {\n\t\t\t\t\treturn newError(\"failed to write request header\").Base(err).AtWarning()\n\t\t\t\t}\n\t\t\tcase nil:\n\t\t\tdefault:\n\t\t\t\treturn newError(\"failed to write a request payload\").Base(err).AtWarning()\n\t\t\t}\n\t\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\t\tif err = bufferWriter.SetBuffered(false); err != nil {\n\t\t\t\treturn newError(\"failed to flush payload\").Base(err).AtWarning()\n\t\t\t}\n\t\t}\n\n\t\tif err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tvar reader buf.Reader\n\t\tif network == net.Network_UDP {\n\t\t\treader = &PacketReader{\n\t\t\t\tReader: conn, HyConn: hyConn,\n\t\t\t}\n\t\t} else {\n\t\t\tok, msg, err := hyProtocol.ReadTCPResponse(conn)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\treturn newError(msg)\n\t\t\t}\n\t\t\treader = buf.NewReader(conn)\n\t\t}\n\t\treturn buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))\n\t}\n\n\tresponseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))\n\tif err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewClient(ctx, config.(*ClientConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/hysteria2/config.go",
    "content": "package hysteria2\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n// MemoryAccount is an account type converted from Account.\ntype MemoryAccount struct{}\n\n// AsAccount implements protocol.AsAccount.\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\treturn &MemoryAccount{}, nil\n}\n\n// Equals implements protocol.Account.Equals().\nfunc (a *MemoryAccount) Equals(another protocol.Account) bool {\n\treturn false\n}\n"
  },
  {
    "path": "proxy/hysteria2/config.pb.go",
    "content": "package hysteria2\n\nimport (\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Account struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_hysteria2_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_hysteria2_config_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype ClientConfig struct {\n\tstate         protoimpl.MessageState     `protogen:\"open.v1\"`\n\tServer        []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=server,proto3\" json:\"server,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_hysteria2_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_hysteria2_config_proto_msgTypes[1]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\ntype ServerConfig struct {\n\tstate          protoimpl.MessageState    `protogen:\"open.v1\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,1,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_hysteria2_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_hysteria2_config_proto_msgTypes[2]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\nvar File_proxy_hysteria2_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_hysteria2_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1cproxy/hysteria2/config.proto\\x12\\x1av2ray.core.proxy.hysteria2\\x1a\\\"common/net/packetaddr/config.proto\\x1a!common/protocol/server_spec.proto\\x1a common/protoext/extensions.proto\\\"\\t\\n\" +\n\t\"\\aAccount\\\"m\\n\" +\n\t\"\\fClientConfig\\x12B\\n\" +\n\t\"\\x06server\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x06server:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\boutbound\\x12\\thysteria2\\\"|\\n\" +\n\t\"\\fServerConfig\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\x01 \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\ainbound\\x12\\thysteria2Bo\\n\" +\n\t\"\\x1ecom.v2ray.core.proxy.hysteria2P\\x01Z.github.com/v2fly/v2ray-core/v5/proxy/hysteria2\\xaa\\x02\\x1aV2Ray.Core.Proxy.Hysteria2b\\x06proto3\"\n\nvar (\n\tfile_proxy_hysteria2_config_proto_rawDescOnce sync.Once\n\tfile_proxy_hysteria2_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_hysteria2_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_hysteria2_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_hysteria2_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_hysteria2_config_proto_rawDesc), len(file_proxy_hysteria2_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_hysteria2_config_proto_rawDescData\n}\n\nvar file_proxy_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_proxy_hysteria2_config_proto_goTypes = []any{\n\t(*Account)(nil),                 // 0: v2ray.core.proxy.hysteria2.Account\n\t(*ClientConfig)(nil),            // 1: v2ray.core.proxy.hysteria2.ClientConfig\n\t(*ServerConfig)(nil),            // 2: v2ray.core.proxy.hysteria2.ServerConfig\n\t(*protocol.ServerEndpoint)(nil), // 3: v2ray.core.common.protocol.ServerEndpoint\n\t(packetaddr.PacketAddrType)(0),  // 4: v2ray.core.net.packetaddr.PacketAddrType\n}\nvar file_proxy_hysteria2_config_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.proxy.hysteria2.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t4, // 1: v2ray.core.proxy.hysteria2.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_hysteria2_config_proto_init() }\nfunc file_proxy_hysteria2_config_proto_init() {\n\tif File_proxy_hysteria2_config_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: unsafe.Slice(unsafe.StringData(file_proxy_hysteria2_config_proto_rawDesc), len(file_proxy_hysteria2_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_hysteria2_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_hysteria2_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_hysteria2_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_hysteria2_config_proto = out.File\n\tfile_proxy_hysteria2_config_proto_goTypes = nil\n\tfile_proxy_hysteria2_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/hysteria2/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.hysteria2;\noption csharp_namespace = \"V2Ray.Core.Proxy.Hysteria2\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/hysteria2\";\noption java_package = \"com.v2ray.core.proxy.hysteria2\";\noption java_multiple_files = true;\n\nimport \"common/net/packetaddr/config.proto\";\nimport \"common/protocol/server_spec.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Account {\n}\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"hysteria2\";\n\n  repeated v2ray.core.common.protocol.ServerEndpoint server = 1;\n}\n\nmessage ServerConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"hysteria2\";\n\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 1;\n}\n"
  },
  {
    "path": "proxy/hysteria2/errors.generated.go",
    "content": "package hysteria2\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/hysteria2/hysteria2.go",
    "content": "package hysteria2\n"
  },
  {
    "path": "proxy/hysteria2/protocol.go",
    "content": "package hysteria2\n\nimport (\n\t\"io\"\n\t\"math/rand\"\n\n\t\"github.com/apernet/quic-go/quicvarint\"\n\thyProtocol \"github.com/v2fly/hysteria/core/v2/international/protocol\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\thyTransport \"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n)\n\nconst (\n\tpaddingChars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n)\n\n// ConnWriter is TCP Connection Writer Wrapper\ntype ConnWriter struct {\n\tio.Writer\n\tTarget        net.Destination\n\tTCPHeaderSent bool\n}\n\n// Write implements io.Writer\nfunc (c *ConnWriter) Write(p []byte) (n int, err error) {\n\tif !c.TCPHeaderSent {\n\t\tif err := c.writeTCPHeader(); err != nil {\n\t\t\treturn 0, newError(\"failed to write request header\").Base(err)\n\t\t}\n\t}\n\n\treturn c.Writer.Write(p)\n}\n\n// WriteMultiBuffer implements buf.Writer\nfunc (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tdefer buf.ReleaseMulti(mb)\n\n\tfor _, b := range mb {\n\t\tif !b.IsEmpty() {\n\t\t\tif _, err := c.Write(b.Bytes()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *ConnWriter) WriteTCPHeader() error {\n\tif !c.TCPHeaderSent {\n\t\tif err := c.writeTCPHeader(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc QuicLen(s int) int {\n\treturn quicvarint.Len(uint64(s))\n}\n\nfunc (c *ConnWriter) writeTCPHeader() error {\n\tc.TCPHeaderSent = true\n\n\tpaddingLen := 64 + rand.Intn(512-64)\n\tpadding := make([]byte, paddingLen)\n\tfor i := range padding {\n\t\tpadding[i] = paddingChars[rand.Intn(len(paddingChars))]\n\t}\n\taddressAndPort := c.Target.NetAddr()\n\taddressLen := len(addressAndPort)\n\tif addressLen > hyProtocol.MaxAddressLength {\n\t\treturn newError(\"address length too large: \", addressLen)\n\t}\n\tsize := QuicLen(addressLen) + addressLen + QuicLen(paddingLen) + paddingLen\n\n\tbuf := make([]byte, size)\n\ti := hyProtocol.VarintPut(buf, uint64(addressLen))\n\ti += copy(buf[i:], addressAndPort)\n\ti += hyProtocol.VarintPut(buf[i:], uint64(paddingLen))\n\tcopy(buf[i:], padding)\n\n\t_, err := c.Writer.Write(buf)\n\treturn err\n}\n\n// PacketWriter UDP Connection Writer Wrapper\ntype PacketWriter struct {\n\tio.Writer\n\tHyConn *hyTransport.HyConn\n\tTarget net.Destination\n}\n\n// WriteMultiBuffer implements buf.Writer\nfunc (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tfor _, b := range mb {\n\t\tif b.IsEmpty() {\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := w.writePacket(b.Bytes(), w.Target); err != nil {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// WriteMultiBufferWithMetadata writes udp packet with destination specified\nfunc (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {\n\tfor _, b := range mb {\n\t\tif b.IsEmpty() {\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := w.writePacket(b.Bytes(), dest); err != nil {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (w *PacketWriter) WriteTo(payload []byte, addr net.Addr) (int, error) {\n\tdest := net.DestinationFromAddr(addr)\n\n\treturn w.writePacket(payload, dest)\n}\n\nfunc (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) {\n\treturn w.HyConn.WritePacket(payload, dest)\n}\n\n// ConnReader is TCP Connection Reader Wrapper\ntype ConnReader struct {\n\tio.Reader\n\tTarget net.Destination\n}\n\n// Read implements io.Reader\nfunc (c *ConnReader) Read(p []byte) (int, error) {\n\treturn c.Reader.Read(p)\n}\n\n// ReadMultiBuffer implements buf.Reader\nfunc (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tb := buf.New()\n\t_, err := b.ReadFrom(c)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf.MultiBuffer{b}, nil\n}\n\n// PacketPayload combines udp payload and destination\ntype PacketPayload struct {\n\tTarget net.Destination\n\tBuffer buf.MultiBuffer\n}\n\n// PacketReader is UDP Connection Reader Wrapper\ntype PacketReader struct {\n\tio.Reader\n\tHyConn *hyTransport.HyConn\n}\n\n// ReadMultiBuffer implements buf.Reader\nfunc (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tp, err := r.ReadMultiBufferWithMetadata()\n\tif p != nil {\n\t\treturn p.Buffer, err\n\t}\n\treturn nil, err\n}\n\n// ReadMultiBufferWithMetadata reads udp packet with destination\nfunc (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {\n\t_, data, dest, err := r.HyConn.ReadPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tb := buf.FromBytes(data)\n\treturn &PacketPayload{Target: *dest, Buffer: buf.MultiBuffer{b}}, nil\n}\n\ntype PacketConnectionReader struct {\n\treader  *PacketReader\n\tpayload *PacketPayload\n}\n\nfunc (r *PacketConnectionReader) ReadFrom(p []byte) (n int, addr net.Addr, err error) {\n\tif r.payload == nil || r.payload.Buffer.IsEmpty() {\n\t\tr.payload, err = r.reader.ReadMultiBufferWithMetadata()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\taddr = &net.UDPAddr{\n\t\tIP:   r.payload.Target.Address.IP(),\n\t\tPort: int(r.payload.Target.Port),\n\t}\n\n\tr.payload.Buffer, n = buf.SplitFirstBytes(r.payload.Buffer, p)\n\n\treturn\n}\n"
  },
  {
    "path": "proxy/hysteria2/server.go",
    "content": "package hysteria2\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"time\"\n\n\thyProtocol \"github.com/v2fly/hysteria/core/v2/international/protocol\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tudp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\thyTransport \"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServer(ctx, config.(*ServerConfig))\n\t}))\n}\n\n// Server is an inbound connection handler that handles messages in protocol.\ntype Server struct {\n\tpolicyManager  policy.Manager\n\tpacketEncoding packetaddr.PacketAddrType\n}\n\n// NewServer creates a new inbound handler.\nfunc NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {\n\tv := core.MustFromContext(ctx)\n\tserver := &Server{\n\t\tpolicyManager:  v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t\tpacketEncoding: config.PacketEncoding,\n\t}\n\treturn server, nil\n}\n\n// Network implements proxy.Inbound.Network().\nfunc (s *Server) Network() []net.Network {\n\treturn []net.Network{net.Network_TCP, net.Network_UNIX}\n}\n\n// Process implements proxy.Inbound.Process().\nfunc (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tsid := session.ExportIDToError(ctx)\n\n\tiConn := conn\n\tif statConn, ok := conn.(*internet.StatCouterConnection); ok {\n\t\tiConn = statConn.Connection // will not count the UDP traffic.\n\t}\n\thyConn, IsHy2Transport := iConn.(*hyTransport.HyConn)\n\n\tif IsHy2Transport && hyConn.IsUDPExtension {\n\t\tnetwork = net.Network_UDP\n\t}\n\n\tif !IsHy2Transport && network == net.Network_UDP {\n\t\treturn newError(hyTransport.CanNotUseUDPExtension)\n\t}\n\n\tsessionPolicy := s.policyManager.ForLevel(0)\n\tif err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {\n\t\treturn newError(\"unable to set read deadline\").Base(err).AtWarning()\n\t}\n\n\tbufferedReader := &buf.BufferedReader{\n\t\tReader: buf.NewReader(conn),\n\t}\n\tclientReader := &ConnReader{Reader: bufferedReader}\n\n\tif err := conn.SetReadDeadline(time.Time{}); err != nil {\n\t\treturn newError(\"unable to set read deadline\").Base(err).AtWarning()\n\t}\n\n\tif network == net.Network_UDP { // handle udp request\n\t\treturn s.handleUDPPayload(ctx,\n\t\t\t&PacketReader{Reader: clientReader, HyConn: hyConn},\n\t\t\t&PacketWriter{Writer: conn, HyConn: hyConn}, dispatcher)\n\t}\n\n\tvar reqAddr string\n\tvar err error\n\treqAddr, err = hyProtocol.ReadTCPRequest(conn)\n\tif err != nil {\n\t\treturn newError(\"failed to parse header\").Base(err)\n\t}\n\terr = hyProtocol.WriteTCPResponse(conn, true, \"\")\n\tif err != nil {\n\t\treturn newError(\"failed to send response\").Base(err)\n\t}\n\n\taddress, stringPort, err := net.SplitHostPort(reqAddr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tport, err := net.PortFromString(stringPort)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdestination := net.Destination{Network: network, Address: net.ParseAddress(address), Port: port}\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil {\n\t\tpanic(\"no inbound metadata\")\n\t}\n\tsessionPolicy = s.policyManager.ForLevel(0)\n\n\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\tFrom:   conn.RemoteAddr(),\n\t\tTo:     destination,\n\t\tStatus: log.AccessAccepted,\n\t\tReason: \"\",\n\t})\n\n\tnewError(\"received request for \", destination).WriteToLog(sid)\n\treturn s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher)\n}\n\nfunc (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session,\n\tdestination net.Destination,\n\tclientReader buf.Reader,\n\tclientWriter buf.Writer, dispatcher routing.Dispatcher,\n) error {\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\n\tlink, err := dispatcher.Dispatch(ctx, destination)\n\tif err != nil {\n\t\treturn newError(\"failed to dispatch request to \", destination).Base(err)\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tif err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tif err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to write response\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\trequestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestDonePost, responseDone); err != nil {\n\t\tcommon.Must(common.Interrupt(link.Reader))\n\t\tcommon.Must(common.Interrupt(link.Writer))\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error {\n\tudpDispatcherConstructor := udp.NewSplitDispatcher\n\tswitch s.packetEncoding {\n\tcase packetaddr.PacketAddrType_None:\n\tcase packetaddr.PacketAddrType_Packet:\n\t\tpacketAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)\n\t\tudpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher\n\t}\n\n\tudpServer := udpDispatcherConstructor(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {\n\t\tif err := clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source); err != nil {\n\t\t\tnewError(\"failed to write response\").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t})\n\n\tinbound := session.InboundFromContext(ctx)\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil\n\t\tdefault:\n\t\t\tp, err := clientReader.ReadMultiBufferWithMetadata()\n\t\t\tif err != nil {\n\t\t\t\tif errors.Cause(err) != io.EOF {\n\t\t\t\t\treturn newError(\"unexpected EOF\").Base(err)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tcurrentPacketCtx := ctx\n\t\t\tcurrentPacketCtx = log.ContextWithAccessMessage(currentPacketCtx, &log.AccessMessage{\n\t\t\t\tFrom:   inbound.Source,\n\t\t\t\tTo:     p.Target,\n\t\t\t\tStatus: log.AccessAccepted,\n\t\t\t\tReason: \"\",\n\t\t\t})\n\t\t\tnewError(\"tunnelling request to \", p.Target).WriteToLog(session.ExportIDToError(ctx))\n\n\t\t\tfor _, b := range p.Buffer {\n\t\t\t\tudpServer.Dispatch(currentPacketCtx, p.Target, b)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "proxy/loopback/config.go",
    "content": "package loopback\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/loopback/config.pb.go",
    "content": "package loopback\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tInboundTag    string                 `protobuf:\"bytes,1,opt,name=inbound_tag,json=inboundTag,proto3\" json:\"inbound_tag,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_loopback_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_loopback_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_loopback_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetInboundTag() string {\n\tif x != nil {\n\t\treturn x.InboundTag\n\t}\n\treturn \"\"\n}\n\nvar File_proxy_loopback_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_loopback_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1bproxy/loopback/config.proto\\x12\\x19v2ray.core.proxy.loopback\\x1a common/protoext/extensions.proto\\\"C\\n\" +\n\t\"\\x06Config\\x12\\x1f\\n\" +\n\t\"\\vinbound_tag\\x18\\x01 \\x01(\\tR\\n\" +\n\t\"inboundTag:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\boutbound\\x12\\bloopbackBl\\n\" +\n\t\"\\x1dcom.v2ray.core.proxy.loopbackP\\x01Z-github.com/v2fly/v2ray-core/v5/proxy/loopback\\xaa\\x02\\x19V2Ray.Core.Proxy.Loopbackb\\x06proto3\"\n\nvar (\n\tfile_proxy_loopback_config_proto_rawDescOnce sync.Once\n\tfile_proxy_loopback_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_loopback_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_loopback_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_loopback_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_loopback_config_proto_rawDesc), len(file_proxy_loopback_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_loopback_config_proto_rawDescData\n}\n\nvar file_proxy_loopback_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_loopback_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.proxy.loopback.Config\n}\nvar file_proxy_loopback_config_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_proxy_loopback_config_proto_init() }\nfunc file_proxy_loopback_config_proto_init() {\n\tif File_proxy_loopback_config_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: unsafe.Slice(unsafe.StringData(file_proxy_loopback_config_proto_rawDesc), len(file_proxy_loopback_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_loopback_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_loopback_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_loopback_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_loopback_config_proto = out.File\n\tfile_proxy_loopback_config_proto_goTypes = nil\n\tfile_proxy_loopback_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/loopback/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.loopback;\noption csharp_namespace = \"V2Ray.Core.Proxy.Loopback\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/loopback\";\noption java_package = \"com.v2ray.core.proxy.loopback\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"loopback\";\n\n  string inbound_tag = 1;\n}\n"
  },
  {
    "path": "proxy/loopback/errors.generated.go",
    "content": "package loopback\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/loopback/loopback.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage loopback\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype Loopback struct {\n\tconfig             *Config\n\tdispatcherInstance routing.Dispatcher\n}\n\nfunc (l *Loopback) Process(ctx context.Context, link *transport.Link, _ internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified.\")\n\t}\n\tdestination := outbound.Target\n\n\tnewError(\"opening connection to \", destination).WriteToLog(session.ExportIDToError(ctx))\n\n\tinput := link.Reader\n\toutput := link.Writer\n\n\tvar conn internet.Connection\n\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tdialDest := destination\n\n\t\tcontent := new(session.Content)\n\t\tcontent.SkipDNSResolve = true\n\n\t\tctx = session.ContextWithContent(ctx, content)\n\n\t\tinbound := session.InboundFromContext(ctx)\n\n\t\tinbound.Tag = l.config.InboundTag\n\n\t\tctx = session.ContextWithInbound(ctx, inbound)\n\n\t\trawConn, err := l.dispatcherInstance.Dispatch(ctx, dialDest)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvar readerOpt net.ConnectionOption\n\t\tif dialDest.Network == net.Network_TCP {\n\t\t\treaderOpt = net.ConnectionOutputMulti(rawConn.Reader)\n\t\t} else {\n\t\t\treaderOpt = net.ConnectionOutputMultiUDP(rawConn.Reader)\n\t\t}\n\n\t\tconn = net.NewConnection(net.ConnectionInputMulti(rawConn.Writer), readerOpt)\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to open connection to \", destination).Base(err)\n\t}\n\tdefer conn.Close()\n\n\trequestDone := func() error {\n\t\tvar writer buf.Writer\n\t\tif destination.Network == net.Network_TCP {\n\t\t\twriter = buf.NewWriter(conn)\n\t\t} else {\n\t\t\twriter = &buf.SequentialWriter{Writer: conn}\n\t\t}\n\n\t\tif err := buf.Copy(input, writer); err != nil {\n\t\t\treturn newError(\"failed to process request\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tvar reader buf.Reader\n\t\tif destination.Network == net.Network_TCP {\n\t\t\treader = buf.NewReader(conn)\n\t\t} else {\n\t\t\treader = buf.NewPacketReader(conn)\n\t\t}\n\t\tif err := buf.Copy(reader, output); err != nil {\n\t\t\treturn newError(\"failed to process response\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, requestDone, task.OnSuccess(responseDone, task.Close(output))); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (l *Loopback) init(config *Config, dispatcherInstance routing.Dispatcher) error {\n\tl.dispatcherInstance = dispatcherInstance\n\tl.config = config\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tl := new(Loopback)\n\t\terr := core.RequireFeatures(ctx, func(dispatcherInstance routing.Dispatcher) error {\n\t\t\treturn l.init(config.(*Config), dispatcherInstance)\n\t\t})\n\t\treturn l, err\n\t}))\n}\n"
  },
  {
    "path": "proxy/proxy.go",
    "content": "// Package proxy contains all proxies used by V2Ray.\n//\n// To implement an inbound or outbound proxy, one needs to do the following:\n// 1. Implement the interface(s) below.\n// 2. Register a config creator through common.RegisterConfig.\npackage proxy\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// A timeout for reading the first payload from the client, used in 0-RTT optimizations.\nconst FirstPayloadTimeout = 100 * time.Millisecond\n\n// An Inbound processes inbound connections.\ntype Inbound interface {\n\t// Network returns a list of networks that this inbound supports. Connections with not-supported networks will not be passed into Process().\n\tNetwork() []net.Network\n\n\t// Process processes a connection of given network. If necessary, the Inbound can dispatch the connection to an Outbound.\n\tProcess(context.Context, net.Network, internet.Connection, routing.Dispatcher) error\n}\n\n// An Outbound process outbound connections.\ntype Outbound interface {\n\t// Process processes the given connection. The given dialer may be used to dial a system outbound connection.\n\tProcess(context.Context, *transport.Link, internet.Dialer) error\n}\n\n// UserManager is the interface for Inbounds and Outbounds that can manage their users.\ntype UserManager interface {\n\t// AddUser adds a new user.\n\tAddUser(context.Context, *protocol.MemoryUser) error\n\n\t// RemoveUser removes a user by email.\n\tRemoveUser(context.Context, string) error\n}\n\ntype GetInbound interface {\n\tGetInbound() Inbound\n}\n\ntype GetOutbound interface {\n\tGetOutbound() Outbound\n}\n"
  },
  {
    "path": "proxy/shadowsocks/client.go",
    "content": "package shadowsocks\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// Client is a inbound handler for Shadowsocks protocol\ntype Client struct {\n\tserverPicker  protocol.ServerPicker\n\tpolicyManager policy.Manager\n}\n\n// NewClient create a new Shadowsocks client.\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Server {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse server spec\").Base(err)\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\tif serverList.Size() == 0 {\n\t\treturn nil, newError(\"0 server\")\n\t}\n\n\tv := core.MustFromContext(ctx)\n\tclient := &Client{\n\t\tserverPicker:  protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\treturn client, nil\n}\n\n// Process implements OutboundHandler.Process().\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\")\n\t}\n\tdestination := outbound.Target\n\tnetwork := destination.Network\n\n\tvar server *protocol.ServerSpec\n\tvar conn internet.Connection\n\n\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tserver = c.serverPicker.PickServer()\n\t\tdest := server.Destination()\n\t\tdest.Network = network\n\t\trawConn, err := dialer.Dial(ctx, dest)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconn = rawConn\n\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to find an available destination\").AtWarning().Base(err)\n\t}\n\tnewError(\"tunneling request to \", destination, \" via \", network, \":\", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx))\n\n\tdefer conn.Close()\n\n\trequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tAddress: destination.Address,\n\t\tPort:    destination.Port,\n\t}\n\tif destination.Network == net.Network_TCP {\n\t\trequest.Command = protocol.RequestCommandTCP\n\t} else {\n\t\trequest.Command = protocol.RequestCommandUDP\n\t}\n\n\tuser := server.PickUser()\n\t_, ok := user.Account.(*MemoryAccount)\n\tif !ok {\n\t\treturn newError(\"user account is not valid\")\n\t}\n\trequest.User = user\n\n\tsessionPolicy := c.policyManager.ForLevel(user.Level)\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\trequestDone := func() error {\n\t\t\tprotocolWriter := &UDPWriter{\n\t\t\t\tWriter:  conn,\n\t\t\t\tRequest: request,\n\t\t\t}\n\t\t\treturn udp.CopyPacketConn(protocolWriter, packetConn, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\tprotocolReader := &UDPReader{\n\t\t\t\tReader: conn,\n\t\t\t\tUser:   user,\n\t\t\t}\n\t\t\treturn udp.CopyPacketConn(packetConn, protocolReader, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif request.Command == protocol.RequestCommandTCP {\n\t\trequestDone := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\t\t\tbufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\t\tbodyWriter, err := WriteTCPRequest(request, bufferedWriter)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to write request\").Base(err)\n\t\t\t}\n\n\t\t\tif err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {\n\t\t\t\treturn newError(\"failed to write A request payload\").Base(err).AtWarning()\n\t\t\t}\n\n\t\t\tif err := bufferedWriter.SetBuffered(false); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer))\n\t\t}\n\n\t\tresponseDone := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\t\tresponseReader, err := ReadTCPResponse(user, conn)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn buf.Copy(responseReader, link.Writer, buf.UpdateActivity(timer))\n\t\t}\n\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif request.Command == protocol.RequestCommandUDP {\n\t\twriter := &buf.SequentialWriter{Writer: &UDPWriter{\n\t\t\tWriter:  conn,\n\t\t\tRequest: request,\n\t\t}}\n\n\t\trequestDone := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\t\tif err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\treturn newError(\"failed to transport all UDP request\").Base(err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tresponseDone := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\t\treader := &UDPReader{\n\t\t\t\tReader: conn,\n\t\t\t\tUser:   user,\n\t\t\t}\n\n\t\t\tif err := buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\treturn newError(\"failed to transport all UDP response\").Base(err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewClient(ctx, config.(*ClientConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/shadowsocks/config.go",
    "content": "package shadowsocks\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/md5\"\n\t\"crypto/sha1\"\n\t\"io\"\n\t\"strings\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n\t\"golang.org/x/crypto/hkdf\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/antireplay\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n// MemoryAccount is an account type converted from Account.\ntype MemoryAccount struct {\n\tCipher Cipher\n\tKey    []byte\n\n\treplayFilter antireplay.GeneralizedReplayFilter\n\n\tReducedIVEntropy bool\n}\n\n// Equals implements protocol.Account.Equals().\nfunc (a *MemoryAccount) Equals(another protocol.Account) bool {\n\tif account, ok := another.(*MemoryAccount); ok {\n\t\treturn bytes.Equal(a.Key, account.Key)\n\t}\n\treturn false\n}\n\nfunc (a *MemoryAccount) CheckIV(iv []byte) error {\n\tif a.replayFilter == nil {\n\t\treturn nil\n\t}\n\tif a.replayFilter.Check(iv) {\n\t\treturn nil\n\t}\n\treturn newError(\"IV is not unique\")\n}\n\nfunc createAesGcm(key []byte) cipher.AEAD {\n\tblock, err := aes.NewCipher(key)\n\tcommon.Must(err)\n\tgcm, err := cipher.NewGCM(block)\n\tcommon.Must(err)\n\treturn gcm\n}\n\nfunc createChaCha20Poly1305(key []byte) cipher.AEAD {\n\tChaChaPoly1305, err := chacha20poly1305.New(key)\n\tcommon.Must(err)\n\treturn ChaChaPoly1305\n}\n\nfunc (a *Account) getCipher() (Cipher, error) {\n\tswitch a.CipherType {\n\tcase CipherType_AES_128_GCM:\n\t\treturn &AEADCipher{\n\t\t\tKeyBytes:        16,\n\t\t\tIVBytes:         16,\n\t\t\tAEADAuthCreator: createAesGcm,\n\t\t}, nil\n\tcase CipherType_AES_256_GCM:\n\t\treturn &AEADCipher{\n\t\t\tKeyBytes:        32,\n\t\t\tIVBytes:         32,\n\t\t\tAEADAuthCreator: createAesGcm,\n\t\t}, nil\n\tcase CipherType_CHACHA20_POLY1305:\n\t\treturn &AEADCipher{\n\t\t\tKeyBytes:        32,\n\t\t\tIVBytes:         32,\n\t\t\tAEADAuthCreator: createChaCha20Poly1305,\n\t\t}, nil\n\tcase CipherType_NONE:\n\t\treturn NoneCipher{}, nil\n\tdefault:\n\t\treturn nil, newError(\"Unsupported cipher.\")\n\t}\n}\n\n// AsAccount implements protocol.AsAccount.\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\tCipher, err := a.getCipher()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get cipher\").Base(err)\n\t}\n\treturn &MemoryAccount{\n\t\tCipher: Cipher,\n\t\tKey:    passwordToCipherKey([]byte(a.Password), Cipher.KeySize()),\n\t\treplayFilter: func() antireplay.GeneralizedReplayFilter {\n\t\t\tif a.IvCheck {\n\t\t\t\treturn antireplay.NewBloomRing()\n\t\t\t}\n\t\t\treturn nil\n\t\t}(),\n\t\tReducedIVEntropy: a.ExperimentReducedIvHeadEntropy,\n\t}, nil\n}\n\n// Cipher is an interface for all Shadowsocks ciphers.\ntype Cipher interface {\n\tKeySize() int32\n\tIVSize() int32\n\tNewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error)\n\tNewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error)\n\tIsAEAD() bool\n\tEncodePacket(key []byte, b *buf.Buffer) error\n\tDecodePacket(key []byte, b *buf.Buffer) error\n}\n\ntype AEADCipher struct {\n\tKeyBytes        int32\n\tIVBytes         int32\n\tAEADAuthCreator func(key []byte) cipher.AEAD\n}\n\nfunc (*AEADCipher) IsAEAD() bool {\n\treturn true\n}\n\nfunc (c *AEADCipher) KeySize() int32 {\n\treturn c.KeyBytes\n}\n\nfunc (c *AEADCipher) IVSize() int32 {\n\treturn c.IVBytes\n}\n\nfunc (c *AEADCipher) createAuthenticator(key []byte, iv []byte) *crypto.AEADAuthenticator {\n\tnonce := crypto.GenerateInitialAEADNonce()\n\tsubkey := make([]byte, c.KeyBytes)\n\thkdfSHA1(key, iv, subkey)\n\treturn &crypto.AEADAuthenticator{\n\t\tAEAD:           c.AEADAuthCreator(subkey),\n\t\tNonceGenerator: nonce,\n\t}\n}\n\nfunc (c *AEADCipher) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {\n\tauth := c.createAuthenticator(key, iv)\n\treturn crypto.NewAuthenticationWriter(auth, &crypto.AEADChunkSizeParser{\n\t\tAuth: auth,\n\t}, writer, protocol.TransferTypeStream, nil), nil\n}\n\nfunc (c *AEADCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {\n\tauth := c.createAuthenticator(key, iv)\n\treturn crypto.NewAuthenticationReader(auth, &crypto.AEADChunkSizeParser{\n\t\tAuth: auth,\n\t}, reader, protocol.TransferTypeStream, nil), nil\n}\n\nfunc (c *AEADCipher) EncodePacket(key []byte, b *buf.Buffer) error {\n\tivLen := c.IVSize()\n\tpayloadLen := b.Len()\n\tauth := c.createAuthenticator(key, b.BytesTo(ivLen))\n\n\tb.Extend(int32(auth.Overhead()))\n\t_, err := auth.Seal(b.BytesTo(ivLen), b.BytesRange(ivLen, payloadLen))\n\treturn err\n}\n\nfunc (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {\n\tif b.Len() <= c.IVSize() {\n\t\treturn newError(\"insufficient data: \", b.Len())\n\t}\n\tivLen := c.IVSize()\n\tpayloadLen := b.Len()\n\tauth := c.createAuthenticator(key, b.BytesTo(ivLen))\n\n\tbbb, err := auth.Open(b.BytesTo(ivLen), b.BytesRange(ivLen, payloadLen))\n\tif err != nil {\n\t\treturn err\n\t}\n\tb.Resize(ivLen, int32(len(bbb)))\n\treturn nil\n}\n\ntype NoneCipher struct{}\n\nfunc (NoneCipher) KeySize() int32 { return 0 }\nfunc (NoneCipher) IVSize() int32  { return 0 }\nfunc (NoneCipher) IsAEAD() bool {\n\treturn false\n}\n\nfunc (NoneCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {\n\treturn buf.NewReader(reader), nil\n}\n\nfunc (NoneCipher) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {\n\treturn buf.NewWriter(writer), nil\n}\n\nfunc (NoneCipher) EncodePacket(key []byte, b *buf.Buffer) error {\n\treturn nil\n}\n\nfunc (NoneCipher) DecodePacket(key []byte, b *buf.Buffer) error {\n\treturn nil\n}\n\nfunc CipherFromString(c string) CipherType {\n\tswitch strings.ToLower(c) {\n\tcase \"aes-128-gcm\", \"aes_128_gcm\", \"aead_aes_128_gcm\":\n\t\treturn CipherType_AES_128_GCM\n\tcase \"aes-256-gcm\", \"aes_256_gcm\", \"aead_aes_256_gcm\":\n\t\treturn CipherType_AES_256_GCM\n\tcase \"chacha20-poly1305\", \"chacha20_poly1305\", \"aead_chacha20_poly1305\", \"chacha20-ietf-poly1305\":\n\t\treturn CipherType_CHACHA20_POLY1305\n\tcase \"none\", \"plain\":\n\t\treturn CipherType_NONE\n\tdefault:\n\t\treturn CipherType_UNKNOWN\n\t}\n}\n\nfunc passwordToCipherKey(password []byte, keySize int32) []byte {\n\tkey := make([]byte, 0, keySize)\n\n\tmd5Sum := md5.Sum(password)\n\tkey = append(key, md5Sum[:]...)\n\n\tfor int32(len(key)) < keySize {\n\t\tmd5Hash := md5.New()\n\t\tcommon.Must2(md5Hash.Write(md5Sum[:]))\n\t\tcommon.Must2(md5Hash.Write(password))\n\t\tmd5Hash.Sum(md5Sum[:0])\n\n\t\tkey = append(key, md5Sum[:]...)\n\t}\n\treturn key\n}\n\nfunc hkdfSHA1(secret, salt, outKey []byte) {\n\tr := hkdf.New(sha1.New, secret, salt, []byte(\"ss-subkey\"))\n\tcommon.Must2(io.ReadFull(r, outKey))\n}\n"
  },
  {
    "path": "proxy/shadowsocks/config.pb.go",
    "content": "package shadowsocks\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 CipherType int32\n\nconst (\n\tCipherType_UNKNOWN           CipherType = 0\n\tCipherType_AES_128_GCM       CipherType = 1\n\tCipherType_AES_256_GCM       CipherType = 2\n\tCipherType_CHACHA20_POLY1305 CipherType = 3\n\tCipherType_NONE              CipherType = 4\n)\n\n// Enum value maps for CipherType.\nvar (\n\tCipherType_name = map[int32]string{\n\t\t0: \"UNKNOWN\",\n\t\t1: \"AES_128_GCM\",\n\t\t2: \"AES_256_GCM\",\n\t\t3: \"CHACHA20_POLY1305\",\n\t\t4: \"NONE\",\n\t}\n\tCipherType_value = map[string]int32{\n\t\t\"UNKNOWN\":           0,\n\t\t\"AES_128_GCM\":       1,\n\t\t\"AES_256_GCM\":       2,\n\t\t\"CHACHA20_POLY1305\": 3,\n\t\t\"NONE\":              4,\n\t}\n)\n\nfunc (x CipherType) Enum() *CipherType {\n\tp := new(CipherType)\n\t*p = x\n\treturn p\n}\n\nfunc (x CipherType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (CipherType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_proxy_shadowsocks_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (CipherType) Type() protoreflect.EnumType {\n\treturn &file_proxy_shadowsocks_config_proto_enumTypes[0]\n}\n\nfunc (x CipherType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use CipherType.Descriptor instead.\nfunc (CipherType) EnumDescriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Account struct {\n\tstate                          protoimpl.MessageState `protogen:\"open.v1\"`\n\tPassword                       string                 `protobuf:\"bytes,1,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tCipherType                     CipherType             `protobuf:\"varint,2,opt,name=cipher_type,json=cipherType,proto3,enum=v2ray.core.proxy.shadowsocks.CipherType\" json:\"cipher_type,omitempty\"`\n\tIvCheck                        bool                   `protobuf:\"varint,3,opt,name=iv_check,json=ivCheck,proto3\" json:\"iv_check,omitempty\"`\n\tExperimentReducedIvHeadEntropy bool                   `protobuf:\"varint,90001,opt,name=experiment_reduced_iv_head_entropy,json=experimentReducedIvHeadEntropy,proto3\" json:\"experiment_reduced_iv_head_entropy,omitempty\"`\n\tunknownFields                  protoimpl.UnknownFields\n\tsizeCache                      protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_shadowsocks_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks_config_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Account) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nfunc (x *Account) GetCipherType() CipherType {\n\tif x != nil {\n\t\treturn x.CipherType\n\t}\n\treturn CipherType_UNKNOWN\n}\n\nfunc (x *Account) GetIvCheck() bool {\n\tif x != nil {\n\t\treturn x.IvCheck\n\t}\n\treturn false\n}\n\nfunc (x *Account) GetExperimentReducedIvHeadEntropy() bool {\n\tif x != nil {\n\t\treturn x.ExperimentReducedIvHeadEntropy\n\t}\n\treturn false\n}\n\ntype ServerConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// UdpEnabled specified whether or not to enable UDP for Shadowsocks.\n\t// Deprecated. Use 'network' field.\n\t//\n\t// Deprecated: Marked as deprecated in proxy/shadowsocks/config.proto.\n\tUdpEnabled     bool                      `protobuf:\"varint,1,opt,name=udp_enabled,json=udpEnabled,proto3\" json:\"udp_enabled,omitempty\"`\n\tUser           *protocol.User            `protobuf:\"bytes,2,opt,name=user,proto3\" json:\"user,omitempty\"`\n\tNetwork        []net.Network             `protobuf:\"varint,3,rep,packed,name=network,proto3,enum=v2ray.core.common.net.Network\" json:\"network,omitempty\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,4,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_shadowsocks_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks_config_proto_msgTypes[1]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_config_proto_rawDescGZIP(), []int{1}\n}\n\n// Deprecated: Marked as deprecated in proxy/shadowsocks/config.proto.\nfunc (x *ServerConfig) GetUdpEnabled() bool {\n\tif x != nil {\n\t\treturn x.UdpEnabled\n\t}\n\treturn false\n}\n\nfunc (x *ServerConfig) GetUser() *protocol.User {\n\tif x != nil {\n\t\treturn x.User\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetNetwork() []net.Network {\n\tif x != nil {\n\t\treturn x.Network\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\ntype ClientConfig struct {\n\tstate         protoimpl.MessageState     `protogen:\"open.v1\"`\n\tServer        []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=server,proto3\" json:\"server,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_shadowsocks_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks_config_proto_msgTypes[2]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\nvar File_proxy_shadowsocks_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_shadowsocks_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1eproxy/shadowsocks/config.proto\\x12\\x1cv2ray.core.proxy.shadowsocks\\x1a\\x18common/net/network.proto\\x1a\\x1acommon/protocol/user.proto\\x1a!common/protocol/server_spec.proto\\x1a\\\"common/net/packetaddr/config.proto\\\"\\xd9\\x01\\n\" +\n\t\"\\aAccount\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x01 \\x01(\\tR\\bpassword\\x12I\\n\" +\n\t\"\\vcipher_type\\x18\\x02 \\x01(\\x0e2(.v2ray.core.proxy.shadowsocks.CipherTypeR\\n\" +\n\t\"cipherType\\x12\\x19\\n\" +\n\t\"\\biv_check\\x18\\x03 \\x01(\\bR\\aivCheck\\x12L\\n\" +\n\t\"\\\"experiment_reduced_iv_head_entropy\\x18\\x91\\xbf\\x05 \\x01(\\bR\\x1eexperimentReducedIvHeadEntropy\\\"\\xf7\\x01\\n\" +\n\t\"\\fServerConfig\\x12#\\n\" +\n\t\"\\vudp_enabled\\x18\\x01 \\x01(\\bB\\x02\\x18\\x01R\\n\" +\n\t\"udpEnabled\\x124\\n\" +\n\t\"\\x04user\\x18\\x02 \\x01(\\v2 .v2ray.core.common.protocol.UserR\\x04user\\x128\\n\" +\n\t\"\\anetwork\\x18\\x03 \\x03(\\x0e2\\x1e.v2ray.core.common.net.NetworkR\\anetwork\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\x04 \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding\\\"R\\n\" +\n\t\"\\fClientConfig\\x12B\\n\" +\n\t\"\\x06server\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x06server*\\\\\\n\" +\n\t\"\\n\" +\n\t\"CipherType\\x12\\v\\n\" +\n\t\"\\aUNKNOWN\\x10\\x00\\x12\\x0f\\n\" +\n\t\"\\vAES_128_GCM\\x10\\x01\\x12\\x0f\\n\" +\n\t\"\\vAES_256_GCM\\x10\\x02\\x12\\x15\\n\" +\n\t\"\\x11CHACHA20_POLY1305\\x10\\x03\\x12\\b\\n\" +\n\t\"\\x04NONE\\x10\\x04Bu\\n\" +\n\t\" com.v2ray.core.proxy.shadowsocksP\\x01Z0github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\\xaa\\x02\\x1cV2Ray.Core.Proxy.Shadowsocksb\\x06proto3\"\n\nvar (\n\tfile_proxy_shadowsocks_config_proto_rawDescOnce sync.Once\n\tfile_proxy_shadowsocks_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_shadowsocks_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_shadowsocks_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_shadowsocks_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_shadowsocks_config_proto_rawDesc), len(file_proxy_shadowsocks_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_shadowsocks_config_proto_rawDescData\n}\n\nvar file_proxy_shadowsocks_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_proxy_shadowsocks_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_proxy_shadowsocks_config_proto_goTypes = []any{\n\t(CipherType)(0),                 // 0: v2ray.core.proxy.shadowsocks.CipherType\n\t(*Account)(nil),                 // 1: v2ray.core.proxy.shadowsocks.Account\n\t(*ServerConfig)(nil),            // 2: v2ray.core.proxy.shadowsocks.ServerConfig\n\t(*ClientConfig)(nil),            // 3: v2ray.core.proxy.shadowsocks.ClientConfig\n\t(*protocol.User)(nil),           // 4: v2ray.core.common.protocol.User\n\t(net.Network)(0),                // 5: v2ray.core.common.net.Network\n\t(packetaddr.PacketAddrType)(0),  // 6: v2ray.core.net.packetaddr.PacketAddrType\n\t(*protocol.ServerEndpoint)(nil), // 7: v2ray.core.common.protocol.ServerEndpoint\n}\nvar file_proxy_shadowsocks_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.proxy.shadowsocks.Account.cipher_type:type_name -> v2ray.core.proxy.shadowsocks.CipherType\n\t4, // 1: v2ray.core.proxy.shadowsocks.ServerConfig.user:type_name -> v2ray.core.common.protocol.User\n\t5, // 2: v2ray.core.proxy.shadowsocks.ServerConfig.network:type_name -> v2ray.core.common.net.Network\n\t6, // 3: v2ray.core.proxy.shadowsocks.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t7, // 4: v2ray.core.proxy.shadowsocks.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_shadowsocks_config_proto_init() }\nfunc file_proxy_shadowsocks_config_proto_init() {\n\tif File_proxy_shadowsocks_config_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: unsafe.Slice(unsafe.StringData(file_proxy_shadowsocks_config_proto_rawDesc), len(file_proxy_shadowsocks_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_shadowsocks_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_shadowsocks_config_proto_depIdxs,\n\t\tEnumInfos:         file_proxy_shadowsocks_config_proto_enumTypes,\n\t\tMessageInfos:      file_proxy_shadowsocks_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_shadowsocks_config_proto = out.File\n\tfile_proxy_shadowsocks_config_proto_goTypes = nil\n\tfile_proxy_shadowsocks_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.shadowsocks;\noption csharp_namespace = \"V2Ray.Core.Proxy.Shadowsocks\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\";\noption java_package = \"com.v2ray.core.proxy.shadowsocks\";\noption java_multiple_files = true;\n\nimport \"common/net/network.proto\";\nimport \"common/protocol/user.proto\";\nimport \"common/protocol/server_spec.proto\";\nimport \"common/net/packetaddr/config.proto\";\n\nmessage Account {\n  string password = 1;\n  CipherType cipher_type = 2;\n\n  bool iv_check = 3;\n  bool experiment_reduced_iv_head_entropy = 90001;\n}\n\nenum CipherType {\n  UNKNOWN = 0;\n  AES_128_GCM = 1;\n  AES_256_GCM = 2;\n  CHACHA20_POLY1305 = 3;\n  NONE = 4;\n}\n\nmessage ServerConfig {\n  // UdpEnabled specified whether or not to enable UDP for Shadowsocks.\n  // Deprecated. Use 'network' field.\n  bool udp_enabled = 1 [deprecated = true];\n  v2ray.core.common.protocol.User user = 2;\n  repeated v2ray.core.common.net.Network network = 3;\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 4;\n}\n\nmessage ClientConfig {\n  repeated v2ray.core.common.protocol.ServerEndpoint server = 1;\n}\n"
  },
  {
    "path": "proxy/shadowsocks/config_test.go",
    "content": "package shadowsocks_test\n\nimport (\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n)\n\nfunc TestAEADCipherUDP(t *testing.T) {\n\trawAccount := &shadowsocks.Account{\n\t\tCipherType: shadowsocks.CipherType_AES_128_GCM,\n\t\tPassword:   \"test\",\n\t}\n\taccount, err := rawAccount.AsAccount()\n\tcommon.Must(err)\n\n\tcipher := account.(*shadowsocks.MemoryAccount).Cipher\n\n\tkey := make([]byte, cipher.KeySize())\n\tcommon.Must2(rand.Read(key))\n\n\tpayload := make([]byte, 1024)\n\tcommon.Must2(rand.Read(payload))\n\n\tb1 := buf.New()\n\tcommon.Must2(b1.ReadFullFrom(rand.Reader, cipher.IVSize()))\n\tcommon.Must2(b1.Write(payload))\n\tcommon.Must(cipher.EncodePacket(key, b1))\n\n\tcommon.Must(cipher.DecodePacket(key, b1))\n\tif diff := cmp.Diff(b1.Bytes(), payload); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "proxy/shadowsocks/errors.generated.go",
    "content": "package shadowsocks\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/shadowsocks/protocol.go",
    "content": "package shadowsocks\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"hash/crc32\"\n\t\"io\"\n\tmrand \"math/rand\"\n\tgonet \"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/drain\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nconst (\n\tVersion = 1\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6),\n\tprotocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),\n\tprotocol.WithAddressTypeParser(func(b byte) byte {\n\t\treturn b & 0x0F\n\t}),\n)\n\n// ReadTCPSession reads a Shadowsocks TCP session from the given reader, returns its header and remaining parts.\nfunc ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {\n\taccount := user.Account.(*MemoryAccount)\n\n\thashkdf := hmac.New(sha256.New, []byte(\"SSBSKDF\"))\n\thashkdf.Write(account.Key)\n\n\tbehaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil))\n\n\tdrainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64)\n\tif err != nil {\n\t\treturn nil, nil, newError(\"failed to initialize drainer\").Base(err)\n\t}\n\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\n\tivLen := account.Cipher.IVSize()\n\tvar iv []byte\n\tif ivLen > 0 {\n\t\tif _, err := buffer.ReadFullFrom(reader, ivLen); err != nil {\n\t\t\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\t\t\treturn nil, nil, drain.WithError(drainer, reader, newError(\"failed to read IV\").Base(err))\n\t\t}\n\n\t\tiv = append([]byte(nil), buffer.BytesTo(ivLen)...)\n\t}\n\n\tr, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader)\n\tif err != nil {\n\t\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\t\treturn nil, nil, drain.WithError(drainer, reader, newError(\"failed to initialize decoding stream\").Base(err).AtError())\n\t}\n\tbr := &buf.BufferedReader{Reader: r}\n\n\trequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tUser:    user,\n\t\tCommand: protocol.RequestCommandTCP,\n\t}\n\n\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\tbuffer.Clear()\n\n\taddr, port, err := addrParser.ReadAddressPort(buffer, br)\n\tif err != nil {\n\t\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\t\treturn nil, nil, drain.WithError(drainer, reader, newError(\"failed to read address\").Base(err))\n\t}\n\n\trequest.Address = addr\n\trequest.Port = port\n\n\tif request.Address == nil {\n\t\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\t\treturn nil, nil, drain.WithError(drainer, reader, newError(\"invalid remote address.\"))\n\t}\n\n\tif ivError := account.CheckIV(iv); ivError != nil {\n\t\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\t\treturn nil, nil, drain.WithError(drainer, reader, newError(\"failed iv check\").Base(ivError))\n\t}\n\n\treturn request, br, nil\n}\n\n// WriteTCPRequest writes Shadowsocks request into the given writer, and returns a writer for body.\nfunc WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {\n\tuser := request.User\n\taccount := user.Account.(*MemoryAccount)\n\n\tvar iv []byte\n\tif account.Cipher.IVSize() > 0 {\n\t\tiv = make([]byte, account.Cipher.IVSize())\n\t\tcommon.Must2(rand.Read(iv))\n\t\tif account.ReducedIVEntropy {\n\t\t\tremapToPrintable(iv[:6])\n\t\t}\n\t\tif ivError := account.CheckIV(iv); ivError != nil {\n\t\t\treturn nil, newError(\"failed to mark outgoing iv\").Base(ivError)\n\t\t}\n\t\tif err := buf.WriteAllBytes(writer, iv); err != nil {\n\t\t\treturn nil, newError(\"failed to write IV\")\n\t\t}\n\t}\n\n\tw, err := account.Cipher.NewEncryptionWriter(account.Key, iv, writer)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create encoding stream\").Base(err).AtError()\n\t}\n\n\theader := buf.New()\n\n\tif err := addrParser.WriteAddressPort(header, request.Address, request.Port); err != nil {\n\t\treturn nil, newError(\"failed to write address\").Base(err)\n\t}\n\n\tif err := w.WriteMultiBuffer(buf.MultiBuffer{header}); err != nil {\n\t\treturn nil, newError(\"failed to write header\").Base(err)\n\t}\n\n\treturn w, nil\n}\n\nfunc ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, error) {\n\taccount := user.Account.(*MemoryAccount)\n\n\thashkdf := hmac.New(sha256.New, []byte(\"SSBSKDF\"))\n\thashkdf.Write(account.Key)\n\n\tbehaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil))\n\n\tdrainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(behaviorSeed), 16+38, 3266, 64)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to initialize drainer\").Base(err)\n\t}\n\n\tvar iv []byte\n\tif account.Cipher.IVSize() > 0 {\n\t\tiv = make([]byte, account.Cipher.IVSize())\n\t\tif n, err := io.ReadFull(reader, iv); err != nil {\n\t\t\treturn nil, newError(\"failed to read IV\").Base(err)\n\t\t} else { // nolint: revive\n\t\t\tdrainer.AcknowledgeReceive(n)\n\t\t}\n\t}\n\n\tif ivError := account.CheckIV(iv); ivError != nil {\n\t\treturn nil, drain.WithError(drainer, reader, newError(\"failed iv check\").Base(ivError))\n\t}\n\n\treturn account.Cipher.NewDecryptionReader(account.Key, iv, reader)\n}\n\nfunc WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {\n\tuser := request.User\n\taccount := user.Account.(*MemoryAccount)\n\n\tvar iv []byte\n\tif account.Cipher.IVSize() > 0 {\n\t\tiv = make([]byte, account.Cipher.IVSize())\n\t\tcommon.Must2(rand.Read(iv))\n\t\tif ivError := account.CheckIV(iv); ivError != nil {\n\t\t\treturn nil, newError(\"failed to mark outgoing iv\").Base(ivError)\n\t\t}\n\t\tif err := buf.WriteAllBytes(writer, iv); err != nil {\n\t\t\treturn nil, newError(\"failed to write IV.\").Base(err)\n\t\t}\n\t}\n\n\treturn account.Cipher.NewEncryptionWriter(account.Key, iv, writer)\n}\n\nfunc EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buffer, error) {\n\tuser := request.User\n\taccount := user.Account.(*MemoryAccount)\n\n\tivLen := account.Cipher.IVSize()\n\t// Calculate required buffer size: IV + address length + payload + AEAD overhead (16)\n\n\tvar addrPortLen int32\n\tswitch request.Address.Family() {\n\tcase net.AddressFamilyDomain:\n\t\tif protocol.IsDomainTooLong(request.Address.Domain()) {\n\t\t\treturn nil, newError(\"Super long domain is not supported: \", request.Address.Domain())\n\t\t}\n\t\taddrPortLen = 1 + 1 + int32(len(request.Address.Domain())) + 2\n\tcase net.AddressFamilyIPv4:\n\t\taddrPortLen = 1 + 4 + 2\n\tcase net.AddressFamilyIPv6:\n\t\taddrPortLen = 1 + 16 + 2\n\tdefault:\n\t\tpanic(\"Unknown address type.\")\n\t}\n\n\tneededSize := ivLen + addrPortLen + int32(len(payload)) + 16\n\n\tvar buffer *buf.Buffer\n\tif neededSize > buf.Size {\n\t\tbuffer = buf.NewWithSize(neededSize)\n\t} else {\n\t\tbuffer = buf.New()\n\t}\n\n\tif ivLen > 0 {\n\t\tcommon.Must2(buffer.ReadFullFrom(rand.Reader, ivLen))\n\t}\n\n\tif err := addrParser.WriteAddressPort(buffer, request.Address, request.Port); err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, newError(\"failed to write address\").Base(err)\n\t}\n\n\tbuffer.Write(payload)\n\n\tif err := account.Cipher.EncodePacket(account.Key, buffer); err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, newError(\"failed to encrypt UDP payload\").Base(err)\n\t}\n\n\treturn buffer, nil\n}\n\nfunc DecodeUDPPacket(user *protocol.MemoryUser, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) {\n\taccount := user.Account.(*MemoryAccount)\n\n\tvar iv []byte\n\tif !account.Cipher.IsAEAD() && account.Cipher.IVSize() > 0 {\n\t\t// Keep track of IV as it gets removed from payload in DecodePacket.\n\t\tiv = make([]byte, account.Cipher.IVSize())\n\t\tcopy(iv, payload.BytesTo(account.Cipher.IVSize()))\n\t}\n\n\tif err := account.Cipher.DecodePacket(account.Key, payload); err != nil {\n\t\treturn nil, nil, newError(\"failed to decrypt UDP payload\").Base(err)\n\t}\n\n\trequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tUser:    user,\n\t\tCommand: protocol.RequestCommandUDP,\n\t}\n\n\tpayload.SetByte(0, payload.Byte(0)&0x0F)\n\n\taddr, port, err := addrParser.ReadAddressPort(nil, payload)\n\tif err != nil {\n\t\treturn nil, nil, newError(\"failed to parse address\").Base(err)\n\t}\n\n\trequest.Address = addr\n\trequest.Port = port\n\n\treturn request, payload, nil\n}\n\ntype UDPReader struct {\n\tReader io.Reader\n\tUser   *protocol.MemoryUser\n}\n\nfunc (v *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tbuffer := buf.New()\n\t_, err := buffer.ReadFrom(v.Reader)\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, err\n\t}\n\t_, payload, err := DecodeUDPPacket(v.User, buffer)\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, err\n\t}\n\treturn buf.MultiBuffer{payload}, nil\n}\n\nfunc (v *UDPReader) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) {\n\tbuffer := buf.New()\n\t_, err = buffer.ReadFrom(v.Reader)\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn 0, nil, err\n\t}\n\tvaddr, payload, err := DecodeUDPPacket(v.User, buffer)\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn 0, nil, err\n\t}\n\tn = copy(p, payload.Bytes())\n\tpayload.Release()\n\treturn n, &gonet.UDPAddr{IP: vaddr.Address.IP(), Port: int(vaddr.Port)}, nil\n}\n\ntype UDPWriter struct {\n\tWriter  io.Writer\n\tRequest *protocol.RequestHeader\n}\n\n// Write implements io.Writer.\nfunc (w *UDPWriter) Write(payload []byte) (int, error) {\n\tpacket, err := EncodeUDPPacket(w.Request, payload)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t_, err = w.Writer.Write(packet.Bytes())\n\tpacket.Release()\n\treturn len(payload), err\n}\n\nfunc (w *UDPWriter) WriteTo(payload []byte, addr gonet.Addr) (n int, err error) {\n\trequest := *w.Request\n\tudpAddr := addr.(*gonet.UDPAddr)\n\trequest.Command = protocol.RequestCommandUDP\n\trequest.Address = net.IPAddress(udpAddr.IP)\n\trequest.Port = net.Port(udpAddr.Port)\n\tpacket, err := EncodeUDPPacket(&request, payload)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t_, err = w.Writer.Write(packet.Bytes())\n\tpacket.Release()\n\treturn len(payload), err\n}\n\nfunc remapToPrintable(input []byte) {\n\tconst charSet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\\\\\\\"\"\n\tseed := mrand.New(mrand.NewSource(int64(crc32.ChecksumIEEE(input))))\n\tfor i := range input {\n\t\tinput[i] = charSet[seed.Intn(len(charSet))]\n\t}\n}\n"
  },
  {
    "path": "proxy/shadowsocks/protocol_test.go",
    "content": "package shadowsocks_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n)\n\nfunc toAccount(a *Account) protocol.Account {\n\taccount, err := a.AsAccount()\n\tcommon.Must(err)\n\treturn account\n}\n\nfunc equalRequestHeader(x, y *protocol.RequestHeader) bool {\n\treturn cmp.Equal(x, y, cmp.Comparer(func(x, y protocol.RequestHeader) bool {\n\t\treturn x == y\n\t}))\n}\n\nfunc TestUDPEncoding(t *testing.T) {\n\trequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tCommand: protocol.RequestCommandUDP,\n\t\tAddress: net.LocalHostIP,\n\t\tPort:    1234,\n\t\tUser: &protocol.MemoryUser{\n\t\t\tEmail: \"love@v2fly.org\",\n\t\t\tAccount: toAccount(&Account{\n\t\t\t\tPassword:   \"password\",\n\t\t\t\tCipherType: CipherType_AES_128_GCM,\n\t\t\t}),\n\t\t},\n\t}\n\n\tdata := buf.New()\n\tcommon.Must2(data.WriteString(\"test string\"))\n\tencodedData, err := EncodeUDPPacket(request, data.Bytes())\n\tcommon.Must(err)\n\n\tdecodedRequest, decodedData, err := DecodeUDPPacket(request.User, encodedData)\n\tcommon.Must(err)\n\n\tif r := cmp.Diff(decodedData.Bytes(), data.Bytes()); r != \"\" {\n\t\tt.Error(\"data: \", r)\n\t}\n\n\tif equalRequestHeader(decodedRequest, request) == false {\n\t\tt.Error(\"different request\")\n\t}\n}\n\nfunc TestTCPRequest(t *testing.T) {\n\tcases := []struct {\n\t\trequest *protocol.RequestHeader\n\t\tpayload []byte\n\t}{\n\t\t{\n\t\t\trequest: &protocol.RequestHeader{\n\t\t\t\tVersion: Version,\n\t\t\t\tCommand: protocol.RequestCommandTCP,\n\t\t\t\tAddress: net.LocalHostIP,\n\t\t\t\tPort:    1234,\n\t\t\t\tUser: &protocol.MemoryUser{\n\t\t\t\t\tEmail: \"love@v2fly.org\",\n\t\t\t\t\tAccount: toAccount(&Account{\n\t\t\t\t\t\tPassword:   \"tcp-password\",\n\t\t\t\t\t\tCipherType: CipherType_AES_128_GCM,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t},\n\t\t\tpayload: []byte(\"test string\"),\n\t\t},\n\t\t{\n\t\t\trequest: &protocol.RequestHeader{\n\t\t\t\tVersion: Version,\n\t\t\t\tCommand: protocol.RequestCommandTCP,\n\t\t\t\tAddress: net.LocalHostIPv6,\n\t\t\t\tPort:    1234,\n\t\t\t\tUser: &protocol.MemoryUser{\n\t\t\t\t\tEmail: \"love@v2fly.org\",\n\t\t\t\t\tAccount: toAccount(&Account{\n\t\t\t\t\t\tPassword:   \"password\",\n\t\t\t\t\t\tCipherType: CipherType_AES_256_GCM,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t},\n\t\t\tpayload: []byte(\"test string\"),\n\t\t},\n\t\t{\n\t\t\trequest: &protocol.RequestHeader{\n\t\t\t\tVersion: Version,\n\t\t\t\tCommand: protocol.RequestCommandTCP,\n\t\t\t\tAddress: net.DomainAddress(\"v2fly.org\"),\n\t\t\t\tPort:    1234,\n\t\t\t\tUser: &protocol.MemoryUser{\n\t\t\t\t\tEmail: \"love@v2fly.org\",\n\t\t\t\t\tAccount: toAccount(&Account{\n\t\t\t\t\t\tPassword:   \"password\",\n\t\t\t\t\t\tCipherType: CipherType_CHACHA20_POLY1305,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t},\n\t\t\tpayload: []byte(\"test string\"),\n\t\t},\n\t}\n\n\trunTest := func(request *protocol.RequestHeader, payload []byte) {\n\t\tdata := buf.New()\n\t\tcommon.Must2(data.Write(payload))\n\n\t\tcache := buf.New()\n\t\tdefer cache.Release()\n\n\t\twriter, err := WriteTCPRequest(request, cache)\n\t\tcommon.Must(err)\n\n\t\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{data}))\n\n\t\tdecodedRequest, reader, err := ReadTCPSession(request.User, cache)\n\t\tcommon.Must(err)\n\t\tif equalRequestHeader(decodedRequest, request) == false {\n\t\t\tt.Error(\"different request\")\n\t\t}\n\n\t\tdecodedData, err := reader.ReadMultiBuffer()\n\t\tcommon.Must(err)\n\t\tif r := cmp.Diff(decodedData[0].Bytes(), payload); r != \"\" {\n\t\t\tt.Error(\"data: \", r)\n\t\t}\n\t}\n\n\tfor _, test := range cases {\n\t\trunTest(test.request, test.payload)\n\t}\n}\n\nfunc TestUDPReaderWriter(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tAccount: toAccount(&Account{\n\t\t\tPassword:   \"test-password\",\n\t\t\tCipherType: CipherType_CHACHA20_POLY1305,\n\t\t}),\n\t}\n\tcache := buf.New()\n\tdefer cache.Release()\n\n\twriter := &buf.SequentialWriter{Writer: &UDPWriter{\n\t\tWriter: cache,\n\t\tRequest: &protocol.RequestHeader{\n\t\t\tVersion: Version,\n\t\t\tAddress: net.DomainAddress(\"v2fly.org\"),\n\t\t\tPort:    123,\n\t\t\tUser:    user,\n\t\t},\n\t}}\n\n\treader := &UDPReader{\n\t\tReader: cache,\n\t\tUser:   user,\n\t}\n\n\t{\n\t\tb := buf.New()\n\t\tcommon.Must2(b.WriteString(\"test payload\"))\n\t\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{b}))\n\n\t\tpayload, err := reader.ReadMultiBuffer()\n\t\tcommon.Must(err)\n\t\tif payload[0].String() != \"test payload\" {\n\t\t\tt.Error(\"unexpected output: \", payload[0].String())\n\t\t}\n\t}\n\n\t{\n\t\tb := buf.New()\n\t\tcommon.Must2(b.WriteString(\"test payload 2\"))\n\t\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{b}))\n\n\t\tpayload, err := reader.ReadMultiBuffer()\n\t\tcommon.Must(err)\n\t\tif payload[0].String() != \"test payload 2\" {\n\t\t\tt.Error(\"unexpected output: \", payload[0].String())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "proxy/shadowsocks/server.go",
    "content": "package shadowsocks\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tudp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\ntype Server struct {\n\tconfig        *ServerConfig\n\tuser          *protocol.MemoryUser\n\tpolicyManager policy.Manager\n}\n\n// NewServer create a new Shadowsocks server.\nfunc NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {\n\tif config.GetUser() == nil {\n\t\treturn nil, newError(\"user is not specified\")\n\t}\n\n\tmUser, err := config.User.ToMemoryUser()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse user account\").Base(err)\n\t}\n\n\tv := core.MustFromContext(ctx)\n\ts := &Server{\n\t\tconfig:        config,\n\t\tuser:          mUser,\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\n\treturn s, nil\n}\n\nfunc (s *Server) Network() []net.Network {\n\tlist := s.config.Network\n\tif len(list) == 0 {\n\t\tlist = append(list, net.Network_TCP)\n\t}\n\tif s.config.UdpEnabled {\n\t\tlist = append(list, net.Network_UDP)\n\t}\n\treturn list\n}\n\nfunc (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tswitch network {\n\tcase net.Network_TCP:\n\t\treturn s.handleConnection(ctx, conn, dispatcher)\n\tcase net.Network_UDP:\n\t\treturn s.handlerUDPPayload(ctx, conn, dispatcher)\n\tdefault:\n\t\treturn newError(\"unknown network: \", network)\n\t}\n}\n\nfunc (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tudpDispatcherConstructor := udp.NewSplitDispatcher\n\tswitch s.config.PacketEncoding {\n\tcase packetaddr.PacketAddrType_None:\n\t\tbreak\n\tcase packetaddr.PacketAddrType_Packet:\n\t\tpacketAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)\n\t\tudpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher\n\t}\n\n\tudpServer := udpDispatcherConstructor(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {\n\t\trequest := protocol.RequestHeaderFromContext(ctx)\n\t\tif request == nil {\n\t\t\trequest = &protocol.RequestHeader{\n\t\t\t\tPort:    packet.Source.Port,\n\t\t\t\tAddress: packet.Source.Address,\n\t\t\t\tUser:    s.user,\n\t\t\t}\n\t\t}\n\n\t\tpayload := packet.Payload\n\t\tdata, err := EncodeUDPPacket(request, payload.Bytes())\n\t\tpayload.Release()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to encode UDP packet\").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t\treturn\n\t\t}\n\t\tdefer data.Release()\n\n\t\tconn.Write(data.Bytes())\n\t})\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil {\n\t\tpanic(\"no inbound metadata\")\n\t}\n\tinbound.User = s.user\n\n\treader := buf.NewPacketReader(conn)\n\tfor {\n\t\tmpayload, err := reader.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tfor _, payload := range mpayload {\n\t\t\trequest, data, err := DecodeUDPPacket(s.user, payload)\n\t\t\tif err != nil {\n\t\t\t\tif inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {\n\t\t\t\t\tnewError(\"dropping invalid UDP packet from: \", inbound.Source).Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t\tlog.Record(&log.AccessMessage{\n\t\t\t\t\t\tFrom:   inbound.Source,\n\t\t\t\t\t\tTo:     \"\",\n\t\t\t\t\t\tStatus: log.AccessRejected,\n\t\t\t\t\t\tReason: err,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tpayload.Release()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcurrentPacketCtx := ctx\n\t\t\tdest := request.Destination()\n\t\t\tif inbound.Source.IsValid() {\n\t\t\t\tcurrentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\t\t\t\tFrom:   inbound.Source,\n\t\t\t\t\tTo:     dest,\n\t\t\t\t\tStatus: log.AccessAccepted,\n\t\t\t\t\tReason: \"\",\n\t\t\t\t\tEmail:  request.User.Email,\n\t\t\t\t})\n\t\t\t}\n\t\t\tnewError(\"tunnelling request to \", dest).WriteToLog(session.ExportIDToError(currentPacketCtx))\n\n\t\t\tcurrentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)\n\t\t\tudpServer.Dispatch(currentPacketCtx, dest, data)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tsessionPolicy := s.policyManager.ForLevel(s.user.Level)\n\tconn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake))\n\n\tbufferedReader := buf.BufferedReader{Reader: buf.NewReader(conn)}\n\trequest, bodyReader, err := ReadTCPSession(s.user, &bufferedReader)\n\tif err != nil {\n\t\tlog.Record(&log.AccessMessage{\n\t\t\tFrom:   conn.RemoteAddr(),\n\t\t\tTo:     \"\",\n\t\t\tStatus: log.AccessRejected,\n\t\t\tReason: err,\n\t\t})\n\t\treturn newError(\"failed to create request from: \", conn.RemoteAddr()).Base(err)\n\t}\n\tconn.SetReadDeadline(time.Time{})\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil {\n\t\tpanic(\"no inbound metadata\")\n\t}\n\tinbound.User = s.user\n\n\tdest := request.Destination()\n\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\tFrom:   conn.RemoteAddr(),\n\t\tTo:     dest,\n\t\tStatus: log.AccessAccepted,\n\t\tReason: \"\",\n\t\tEmail:  request.User.Email,\n\t})\n\tnewError(\"tunnelling request to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\tlink, err := dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tbufferedWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\tresponseWriter, err := WriteTCPResponse(request, bufferedWriter)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to write response\").Base(err)\n\t\t}\n\n\t\t{\n\t\t\tpayload, err := link.Reader.ReadMultiBuffer()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := responseWriter.WriteMultiBuffer(payload); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif err := bufferedWriter.SetBuffered(false); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err := buf.Copy(link.Reader, responseWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport all TCP response\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tif err := buf.Copy(bodyReader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport all TCP request\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\trequestDoneAndCloseWriter := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestDoneAndCloseWriter, responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServer(ctx, config.(*ServerConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/shadowsocks/shadowsocks.go",
    "content": "// Package shadowsocks provides compatible functionality to Shadowsocks.\n//\n// Shadowsocks client and server are implemented as outbound and inbound respectively in V2Ray's term.\n//\n// R.I.P Shadowsocks\npackage shadowsocks\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/shadowsocks/simplified/config.go",
    "content": "package simplified\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/golang/protobuf/jsonpb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n)\n\nfunc (c *CipherTypeWrapper) UnmarshalJSONPB(unmarshaler *jsonpb.Unmarshaler, bytes []byte) error {\n\tvar method string\n\n\tif err := json.Unmarshal(bytes, &method); err != nil {\n\t\treturn err\n\t}\n\n\tif c.Value = shadowsocks.CipherFromString(method); c.Value == shadowsocks.CipherType_UNKNOWN {\n\t\treturn newError(\"unknown cipher method: \", method)\n\t}\n\n\treturn nil\n}\n\nfunc (c *CipherTypeWrapper) MarshalJSONPB(marshaler *jsonpb.Marshaler) ([]byte, error) {\n\tmethod := c.Value.String()\n\n\treturn json.Marshal(method)\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*ServerConfig)\n\t\tfullServer := &shadowsocks.ServerConfig{\n\t\t\tUser: &protocol.User{\n\t\t\t\tAccount: serial.ToTypedMessage(&shadowsocks.Account{\n\t\t\t\t\tPassword:   simplifiedServer.Password,\n\t\t\t\t\tCipherType: simplifiedServer.Method.Value,\n\t\t\t\t}),\n\t\t\t},\n\t\t\tNetwork:        simplifiedServer.Networks.GetNetwork(),\n\t\t\tPacketEncoding: simplifiedServer.PacketEncoding,\n\t\t}\n\n\t\treturn common.CreateObject(ctx, fullServer)\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedClient := config.(*ClientConfig)\n\t\tfullClient := &shadowsocks.ClientConfig{\n\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t{\n\t\t\t\t\tAddress: simplifiedClient.Address,\n\t\t\t\t\tPort:    simplifiedClient.Port,\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&shadowsocks.Account{\n\t\t\t\t\t\t\t\tPassword:                       simplifiedClient.Password,\n\t\t\t\t\t\t\t\tCipherType:                     simplifiedClient.Method.Value,\n\t\t\t\t\t\t\t\tExperimentReducedIvHeadEntropy: simplifiedClient.ExperimentReducedIvHeadEntropy,\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\n\t\treturn common.CreateObject(ctx, fullClient)\n\t}))\n}\n"
  },
  {
    "path": "proxy/shadowsocks/simplified/config.pb.go",
    "content": "package simplified\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tshadowsocks \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ServerConfig struct {\n\tstate          protoimpl.MessageState    `protogen:\"open.v1\"`\n\tMethod         *CipherTypeWrapper        `protobuf:\"bytes,1,opt,name=method,proto3\" json:\"method,omitempty\"`\n\tPassword       string                    `protobuf:\"bytes,2,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tNetworks       *net.NetworkList          `protobuf:\"bytes,3,opt,name=networks,proto3\" json:\"networks,omitempty\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,4,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_shadowsocks_simplified_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks_simplified_config_proto_msgTypes[0]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_simplified_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ServerConfig) GetMethod() *CipherTypeWrapper {\n\tif x != nil {\n\t\treturn x.Method\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerConfig) GetNetworks() *net.NetworkList {\n\tif x != nil {\n\t\treturn x.Networks\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\ntype ClientConfig struct {\n\tstate                          protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress                        *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort                           uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tMethod                         *CipherTypeWrapper     `protobuf:\"bytes,3,opt,name=method,proto3\" json:\"method,omitempty\"`\n\tPassword                       string                 `protobuf:\"bytes,4,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tExperimentReducedIvHeadEntropy bool                   `protobuf:\"varint,90001,opt,name=experiment_reduced_iv_head_entropy,json=experimentReducedIvHeadEntropy,proto3\" json:\"experiment_reduced_iv_head_entropy,omitempty\"`\n\tunknownFields                  protoimpl.UnknownFields\n\tsizeCache                      protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_shadowsocks_simplified_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks_simplified_config_proto_msgTypes[1]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_simplified_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ClientConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetMethod() *CipherTypeWrapper {\n\tif x != nil {\n\t\treturn x.Method\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nfunc (x *ClientConfig) GetExperimentReducedIvHeadEntropy() bool {\n\tif x != nil {\n\t\treturn x.ExperimentReducedIvHeadEntropy\n\t}\n\treturn false\n}\n\ntype CipherTypeWrapper struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         shadowsocks.CipherType `protobuf:\"varint,1,opt,name=value,proto3,enum=v2ray.core.proxy.shadowsocks.CipherType\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *CipherTypeWrapper) Reset() {\n\t*x = CipherTypeWrapper{}\n\tmi := &file_proxy_shadowsocks_simplified_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *CipherTypeWrapper) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*CipherTypeWrapper) ProtoMessage() {}\n\nfunc (x *CipherTypeWrapper) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks_simplified_config_proto_msgTypes[2]\n\tif 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 CipherTypeWrapper.ProtoReflect.Descriptor instead.\nfunc (*CipherTypeWrapper) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks_simplified_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *CipherTypeWrapper) GetValue() shadowsocks.CipherType {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn shadowsocks.CipherType(0)\n}\n\nvar File_proxy_shadowsocks_simplified_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_shadowsocks_simplified_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\")proxy/shadowsocks/simplified/config.proto\\x12'v2ray.core.proxy.shadowsocks.simplified\\x1a common/protoext/extensions.proto\\x1a\\x18common/net/address.proto\\x1a\\x18common/net/network.proto\\x1a\\\"common/net/packetaddr/config.proto\\x1a\\x1eproxy/shadowsocks/config.proto\\\"\\xae\\x02\\n\" +\n\t\"\\fServerConfig\\x12R\\n\" +\n\t\"\\x06method\\x18\\x01 \\x01(\\v2:.v2ray.core.proxy.shadowsocks.simplified.CipherTypeWrapperR\\x06method\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x02 \\x01(\\tR\\bpassword\\x12>\\n\" +\n\t\"\\bnetworks\\x18\\x03 \\x01(\\v2\\\".v2ray.core.common.net.NetworkListR\\bnetworks\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\x04 \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding:\\x1a\\x82\\xb5\\x18\\x16\\n\" +\n\t\"\\ainbound\\x12\\vshadowsocks\\\"\\xbe\\x02\\n\" +\n\t\"\\fClientConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12R\\n\" +\n\t\"\\x06method\\x18\\x03 \\x01(\\v2:.v2ray.core.proxy.shadowsocks.simplified.CipherTypeWrapperR\\x06method\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x04 \\x01(\\tR\\bpassword\\x12L\\n\" +\n\t\"\\\"experiment_reduced_iv_head_entropy\\x18\\x91\\xbf\\x05 \\x01(\\bR\\x1eexperimentReducedIvHeadEntropy:\\x1f\\x82\\xb5\\x18\\x1b\\n\" +\n\t\"\\boutbound\\x12\\vshadowsocks\\x90\\xff)\\x01\\\"S\\n\" +\n\t\"\\x11CipherTypeWrapper\\x12>\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\x0e2(.v2ray.core.proxy.shadowsocks.CipherTypeR\\x05valueB\\x96\\x01\\n\" +\n\t\"+com.v2ray.core.proxy.shadowsocks.simplifiedP\\x01Z;github.com/v2fly/v2ray-core/v5/proxy/shadowsocks/simplified\\xaa\\x02'V2Ray.Core.Proxy.Shadowsocks.Simplifiedb\\x06proto3\"\n\nvar (\n\tfile_proxy_shadowsocks_simplified_config_proto_rawDescOnce sync.Once\n\tfile_proxy_shadowsocks_simplified_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_shadowsocks_simplified_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_shadowsocks_simplified_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_shadowsocks_simplified_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_shadowsocks_simplified_config_proto_rawDesc), len(file_proxy_shadowsocks_simplified_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_shadowsocks_simplified_config_proto_rawDescData\n}\n\nvar file_proxy_shadowsocks_simplified_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_proxy_shadowsocks_simplified_config_proto_goTypes = []any{\n\t(*ServerConfig)(nil),           // 0: v2ray.core.proxy.shadowsocks.simplified.ServerConfig\n\t(*ClientConfig)(nil),           // 1: v2ray.core.proxy.shadowsocks.simplified.ClientConfig\n\t(*CipherTypeWrapper)(nil),      // 2: v2ray.core.proxy.shadowsocks.simplified.CipherTypeWrapper\n\t(*net.NetworkList)(nil),        // 3: v2ray.core.common.net.NetworkList\n\t(packetaddr.PacketAddrType)(0), // 4: v2ray.core.net.packetaddr.PacketAddrType\n\t(*net.IPOrDomain)(nil),         // 5: v2ray.core.common.net.IPOrDomain\n\t(shadowsocks.CipherType)(0),    // 6: v2ray.core.proxy.shadowsocks.CipherType\n}\nvar file_proxy_shadowsocks_simplified_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.shadowsocks.simplified.ServerConfig.method:type_name -> v2ray.core.proxy.shadowsocks.simplified.CipherTypeWrapper\n\t3, // 1: v2ray.core.proxy.shadowsocks.simplified.ServerConfig.networks:type_name -> v2ray.core.common.net.NetworkList\n\t4, // 2: v2ray.core.proxy.shadowsocks.simplified.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t5, // 3: v2ray.core.proxy.shadowsocks.simplified.ClientConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t2, // 4: v2ray.core.proxy.shadowsocks.simplified.ClientConfig.method:type_name -> v2ray.core.proxy.shadowsocks.simplified.CipherTypeWrapper\n\t6, // 5: v2ray.core.proxy.shadowsocks.simplified.CipherTypeWrapper.value:type_name -> v2ray.core.proxy.shadowsocks.CipherType\n\t6, // [6:6] is the sub-list for method output_type\n\t6, // [6:6] is the sub-list for method input_type\n\t6, // [6:6] is the sub-list for extension type_name\n\t6, // [6:6] is the sub-list for extension extendee\n\t0, // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_shadowsocks_simplified_config_proto_init() }\nfunc file_proxy_shadowsocks_simplified_config_proto_init() {\n\tif File_proxy_shadowsocks_simplified_config_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: unsafe.Slice(unsafe.StringData(file_proxy_shadowsocks_simplified_config_proto_rawDesc), len(file_proxy_shadowsocks_simplified_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_shadowsocks_simplified_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_shadowsocks_simplified_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_shadowsocks_simplified_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_shadowsocks_simplified_config_proto = out.File\n\tfile_proxy_shadowsocks_simplified_config_proto_goTypes = nil\n\tfile_proxy_shadowsocks_simplified_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks/simplified/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.shadowsocks.simplified;\noption csharp_namespace = \"V2Ray.Core.Proxy.Shadowsocks.Simplified\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks/simplified\";\noption java_package = \"com.v2ray.core.proxy.shadowsocks.simplified\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"common/net/address.proto\";\nimport \"common/net/network.proto\";\nimport \"common/net/packetaddr/config.proto\";\nimport \"proxy/shadowsocks/config.proto\";\n\nmessage ServerConfig{\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"shadowsocks\";\n\n  CipherTypeWrapper method = 1;\n  string password = 2;\n  v2ray.core.common.net.NetworkList networks = 3;\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 4;\n}\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"shadowsocks\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  CipherTypeWrapper method = 3;\n  string password = 4;\n  bool experiment_reduced_iv_head_entropy = 90001;\n}\n\nmessage CipherTypeWrapper {\n  v2ray.core.proxy.shadowsocks.CipherType value = 1;\n}"
  },
  {
    "path": "proxy/shadowsocks/simplified/errors.generated.go",
    "content": "package simplified\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/client.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"context\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\ntype Client struct {\n\tconfig *ClientConfig\n\tctx    context.Context\n}\n\nconst UDPConnectionState = \"UDPConnectionState\"\n\ntype ClientUDPConnState struct {\n\tsession  *ClientUDPSession\n\tinitOnce *sync.Once\n}\n\nfunc (c *ClientUDPConnState) GetOrCreateSession(create func() (*ClientUDPSession, error)) (*ClientUDPSession, error) {\n\tvar errOuter error\n\tc.initOnce.Do(func() {\n\t\tsessionState, err := create()\n\t\tif err != nil {\n\t\t\terrOuter = newError(\"failed to create UDP session\").Base(err)\n\t\t\treturn\n\t\t}\n\t\tc.session = sessionState\n\t})\n\tif errOuter != nil {\n\t\treturn nil, newError(\"failed to initialize UDP State\").Base(errOuter)\n\t}\n\treturn c.session, nil\n}\n\nfunc NewClientUDPConnState() (*ClientUDPConnState, error) {\n\treturn &ClientUDPConnState{initOnce: &sync.Once{}}, nil\n}\n\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\")\n\t}\n\tdestination := outbound.Target\n\tnetwork := destination.Network\n\n\tkeyDerivation := newBLAKE3KeyDerivation()\n\tvar method Method\n\tswitch c.config.Method {\n\tcase \"2022-blake3-aes-128-gcm\":\n\t\tmethod = newAES128GCMMethod()\n\tcase \"2022-blake3-aes-256-gcm\":\n\t\tmethod = newAES256GCMMethod()\n\tdefault:\n\t\treturn newError(\"unknown method: \", c.config.Method)\n\t}\n\n\teffectivePsk := c.config.Psk\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, time.Minute)\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\tudpSession, err := c.getUDPSession(c.ctx, network, dialer, method, keyDerivation)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get UDP udpSession\").Base(err)\n\t\t}\n\t\trequestDone := func() error {\n\t\t\treturn udp.CopyPacketConn(udpSession, packetConn, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\treturn udp.CopyPacketConn(packetConn, udpSession, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif network == net.Network_TCP {\n\t\tvar conn internet.Connection\n\t\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\t\tdest := net.TCPDestination(c.config.Address.AsAddress(), net.Port(c.config.Port))\n\t\t\tdest.Network = network\n\t\t\trawConn, err := dialer.Dial(ctx, dest)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tconn = rawConn\n\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to find an available destination\").AtWarning().Base(err)\n\t\t}\n\t\tnewError(\"tunneling request to \", destination, \" via \", network, \":\", net.TCPDestination(c.config.Address.AsAddress(), net.Port(c.config.Port)).NetAddr()).WriteToLog(session.ExportIDToError(ctx))\n\t\tdefer conn.Close()\n\n\t\trequest := &TCPRequest{\n\t\t\tkeyDerivation: keyDerivation,\n\t\t\tmethod:        method,\n\t\t}\n\t\tTCPRequestBuffer := buf.New()\n\t\tdefer TCPRequestBuffer.Release()\n\t\terr = request.EncodeTCPRequestHeader(effectivePsk, c.config.Ipsk, destination.Address,\n\t\t\tint(destination.Port), nil, TCPRequestBuffer)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to encode TCP request header\").Base(err)\n\t\t}\n\t\t_, err = conn.Write(TCPRequestBuffer.Bytes())\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to write TCP request header\").Base(err)\n\t\t}\n\t\trequestDone := func() error {\n\t\t\tencodedWriter := request.CreateClientC2SWriter(conn)\n\t\t\treturn buf.Copy(link.Reader, encodedWriter, buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\terr = request.DecodeTCPResponseHeader(effectivePsk, conn)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to decode TCP response header\").Base(err)\n\t\t\t}\n\t\t\tif err = request.CheckC2SConnectionConstraint(); err != nil {\n\t\t\t\treturn newError(\"C2S connection constraint violation\").Base(err)\n\t\t\t}\n\t\t\tinitialPayload := buf.NewWithSize(65535)\n\t\t\tencodedReader, err := request.CreateClientS2CReader(conn, initialPayload)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to create client S2C reader\").Base(err)\n\t\t\t}\n\t\t\terr = link.Writer.WriteMultiBuffer(buf.MultiBuffer{initialPayload})\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to write initial payload\").Base(err)\n\t\t\t}\n\t\t\treturn buf.Copy(encodedReader, link.Writer, buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\t} else {\n\t\tudpSession, err := c.getUDPSession(c.ctx, network, dialer, method, keyDerivation)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get UDP udpSession\").Base(err)\n\t\t}\n\t\tmonoDestUDPConn := udp.NewMonoDestUDPConn(udpSession, &gonet.UDPAddr{IP: destination.Address.IP(), Port: int(destination.Port)})\n\t\trequestDone := func() error {\n\t\t\treturn buf.Copy(link.Reader, monoDestUDPConn, buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\treturn buf.Copy(monoDestUDPConn, link.Writer, buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (c *Client) getUDPSession(ctx context.Context, network net.Network, dialer internet.Dialer, method Method, keyDerivation *BLAKE3KeyDerivation) (internet.AbstractPacketConn, error) {\n\tstorage := envctx.EnvironmentFromContext(ctx).(environment.ProxyEnvironment).TransientStorage()\n\tclientUDPStateIfce, err := storage.Get(ctx, UDPConnectionState)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get UDP connection state\").Base(err)\n\t}\n\tclientUDPState, ok := clientUDPStateIfce.(*ClientUDPConnState)\n\tif !ok {\n\t\treturn nil, newError(\"failed to cast UDP connection state\")\n\t}\n\n\tsessionState, err := clientUDPState.GetOrCreateSession(func() (*ClientUDPSession, error) {\n\t\tvar conn internet.Connection\n\t\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\t\tdest := net.TCPDestination(c.config.Address.AsAddress(), net.Port(c.config.Port))\n\t\t\tdest.Network = network\n\t\t\trawConn, err := dialer.Dial(ctx, dest)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tconn = rawConn\n\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to find an available destination\").AtWarning().Base(err)\n\t\t}\n\t\tnewError(\"creating udp session to \", network, \":\", c.config.Address).WriteToLog(session.ExportIDToError(ctx))\n\t\tpacketProcessor, err := method.GetUDPClientProcessor(c.config.Ipsk, c.config.Psk, keyDerivation)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create UDP client packet processor\").Base(err)\n\t\t}\n\t\treturn NewClientUDPSession(ctx, conn, packetProcessor), nil\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create UDP session\").Base(err)\n\t}\n\tsessionConn, err := sessionState.NewSessionConn()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create UDP session connection\").Base(err)\n\t}\n\treturn sessionConn, nil\n}\n\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tstorage := envctx.EnvironmentFromContext(ctx).(environment.ProxyEnvironment).TransientStorage()\n\n\tudpState, err := NewClientUDPConnState()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create UDP connection state\").Base(err)\n\t}\n\tstorage.Put(ctx, UDPConnectionState, udpState)\n\n\treturn &Client{\n\t\tconfig: config,\n\t\tctx:    ctx,\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tclientConfig, ok := config.(*ClientConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a ClientConfig\")\n\t\t}\n\t\treturn NewClient(ctx, clientConfig)\n\t}))\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/client_session.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"io\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\n\t\"github.com/pion/transport/v2/replaydetector\"\n)\n\nfunc NewClientUDPSession(ctx context.Context, conn io.ReadWriteCloser, packetProcessor UDPClientPacketProcessor) *ClientUDPSession {\n\tsession := &ClientUDPSession{\n\t\tlocker:          &sync.RWMutex{},\n\t\tconn:            conn,\n\t\tpacketProcessor: packetProcessor,\n\t\tsessionMap:      make(map[string]*ClientUDPSessionConn),\n\t\tsessionMapAlias: make(map[string]string),\n\t}\n\tsession.ctx, session.finish = context.WithCancel(ctx)\n\n\tgo session.KeepReading()\n\treturn session\n}\n\ntype ClientUDPSession struct {\n\tlocker *sync.RWMutex\n\n\tconn            io.ReadWriteCloser\n\tpacketProcessor UDPClientPacketProcessor\n\tsessionMap      map[string]*ClientUDPSessionConn\n\n\tsessionMapAlias map[string]string\n\n\tctx    context.Context\n\tfinish func()\n}\n\nfunc (c *ClientUDPSession) GetCachedState(sessionID string) UDPClientPacketProcessorCachedState {\n\tc.locker.RLock()\n\tdefer c.locker.RUnlock()\n\n\tstate, ok := c.sessionMap[sessionID]\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn state.cachedProcessorState\n}\n\nfunc (c *ClientUDPSession) GetCachedServerState(serverSessionID string) UDPClientPacketProcessorCachedState {\n\tc.locker.RLock()\n\tdefer c.locker.RUnlock()\n\n\tclientSessionID := c.getCachedStateAlias(serverSessionID)\n\tif clientSessionID == \"\" {\n\t\treturn nil\n\t}\n\tstate, ok := c.sessionMap[clientSessionID]\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tif serverState, ok := state.trackedServerSessionID[serverSessionID]; !ok {\n\t\treturn nil\n\t} else {\n\t\treturn serverState.cachedRecvProcessorState\n\t}\n}\n\nfunc (c *ClientUDPSession) getCachedStateAlias(serverSessionID string) string {\n\tstate, ok := c.sessionMapAlias[serverSessionID]\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn state\n}\n\nfunc (c *ClientUDPSession) PutCachedState(sessionID string, cache UDPClientPacketProcessorCachedState) {\n\tc.locker.RLock()\n\tdefer c.locker.RUnlock()\n\n\tstate, ok := c.sessionMap[sessionID]\n\tif !ok {\n\t\treturn\n\t}\n\tstate.cachedProcessorState = cache\n}\n\nfunc (c *ClientUDPSession) PutCachedServerState(serverSessionID string, cache UDPClientPacketProcessorCachedState) {\n\tc.locker.RLock()\n\tdefer c.locker.RUnlock()\n\n\tclientSessionID := c.getCachedStateAlias(serverSessionID)\n\tif clientSessionID == \"\" {\n\t\treturn\n\t}\n\tstate, ok := c.sessionMap[clientSessionID]\n\tif !ok {\n\t\treturn\n\t}\n\n\tif serverState, ok := state.trackedServerSessionID[serverSessionID]; ok {\n\t\tserverState.cachedRecvProcessorState = cache\n\t\treturn\n\t}\n}\n\nfunc (c *ClientUDPSession) Close() error {\n\tc.finish()\n\treturn c.conn.Close()\n}\n\nfunc (c *ClientUDPSession) WriteUDPRequest(request *UDPRequest) error {\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\terr := c.packetProcessor.EncodeUDPRequest(request, buffer, c)\n\tif request.Payload != nil {\n\t\trequest.Payload.Release()\n\t}\n\tif err != nil {\n\t\treturn newError(\"unable to encode udp request\").Base(err)\n\t}\n\t_, err = c.conn.Write(buffer.Bytes())\n\tif err != nil {\n\t\treturn newError(\"unable to write to conn\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc (c *ClientUDPSession) KeepReading() {\n\tfor c.ctx.Err() == nil {\n\t\tudpResp := &UDPResponse{}\n\t\tbuffer := make([]byte, 1600)\n\t\tn, err := c.conn.Read(buffer)\n\t\tif err != nil {\n\t\t\tnewError(\"unable to read from conn\").Base(err).WriteToLog()\n\t\t\treturn\n\t\t}\n\t\tif n != 0 {\n\t\t\terr := c.packetProcessor.DecodeUDPResp(buffer[:n], udpResp, c)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"unable to decode udp response\").Base(err).WriteToLog()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t{\n\t\t\t\ttimeDifference := int64(udpResp.TimeStamp) - time.Now().Unix()\n\t\t\t\tif timeDifference < -30 || timeDifference > 30 {\n\t\t\t\t\tnewError(\"udp packet timestamp difference too large, packet discarded, time diff = \", timeDifference).WriteToLog()\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.locker.RLock()\n\t\t\tsession, ok := c.sessionMap[string(udpResp.ClientSessionID[:])]\n\t\t\tc.locker.RUnlock()\n\t\t\tif ok {\n\t\t\t\tselect {\n\t\t\t\tcase session.readChan <- udpResp:\n\t\t\t\tdefault:\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewError(\"misbehaving server: unknown client session ID\").Base(err).WriteToLog()\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (c *ClientUDPSession) NewSessionConn() (internet.AbstractPacketConn, error) {\n\tsessionID := make([]byte, 8)\n\t_, err := rand.Read(sessionID)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to generate session id\").Base(err)\n\t}\n\n\tconnctx, connfinish := context.WithCancel(c.ctx)\n\n\tsessionConn := &ClientUDPSessionConn{\n\t\tsessionID:              string(sessionID),\n\t\treadChan:               make(chan *UDPResponse, 128),\n\t\tparent:                 c,\n\t\tctx:                    connctx,\n\t\tfinish:                 connfinish,\n\t\tnextWritePacketID:      0,\n\t\ttrackedServerSessionID: make(map[string]*ClientUDPSessionServerTracker),\n\t}\n\tc.locker.Lock()\n\tc.sessionMap[sessionConn.sessionID] = sessionConn\n\tc.locker.Unlock()\n\treturn sessionConn, nil\n}\n\ntype ClientUDPSessionServerTracker struct {\n\tcachedRecvProcessorState UDPClientPacketProcessorCachedState\n\trxReplayDetector         replaydetector.ReplayDetector\n\tlastSeen                 time.Time\n}\n\ntype ClientUDPSessionConn struct {\n\tsessionID string\n\treadChan  chan *UDPResponse\n\tparent    *ClientUDPSession\n\n\tnextWritePacketID      uint64\n\ttrackedServerSessionID map[string]*ClientUDPSessionServerTracker\n\n\tcachedProcessorState UDPClientPacketProcessorCachedState\n\n\tctx    context.Context\n\tfinish func()\n}\n\nfunc (c *ClientUDPSessionConn) Close() error {\n\tc.parent.locker.Lock()\n\tdelete(c.parent.sessionMap, c.sessionID)\n\tfor k := range c.trackedServerSessionID {\n\t\tdelete(c.parent.sessionMapAlias, k)\n\t}\n\tc.parent.locker.Unlock()\n\tc.finish()\n\treturn nil\n}\n\nfunc (c *ClientUDPSessionConn) WriteTo(p []byte, addr gonet.Addr) (n int, err error) {\n\tthisPacketID := c.nextWritePacketID\n\tc.nextWritePacketID += 1\n\treq := &UDPRequest{\n\t\tSessionID: [8]byte{},\n\t\tPacketID:  thisPacketID,\n\t\tTimeStamp: uint64(time.Now().Unix()),\n\t\tAddress:   net.IPAddress(addr.(*gonet.UDPAddr).IP),\n\t\tPort:      addr.(*net.UDPAddr).Port,\n\t\tPayload:   nil,\n\t}\n\tcopy(req.SessionID[:], c.sessionID)\n\treq.Payload = buf.New()\n\treq.Payload.Write(p)\n\terr = c.parent.WriteUDPRequest(req)\n\tif err != nil {\n\t\treturn 0, newError(\"unable to write to parent session\").Base(err)\n\t}\n\treturn len(p), nil\n}\n\nfunc (c *ClientUDPSessionConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {\n\tfor {\n\t\tselect {\n\t\tcase <-c.ctx.Done():\n\t\t\treturn 0, nil, io.EOF\n\t\tcase resp := <-c.readChan:\n\t\t\tn = copy(p, resp.Payload.Bytes())\n\t\t\tresp.Payload.Release()\n\n\t\t\tvar trackedState *ClientUDPSessionServerTracker\n\t\t\tif trackedStateReceived, ok := c.trackedServerSessionID[string(resp.SessionID[:])]; !ok {\n\t\t\t\tfor key, value := range c.trackedServerSessionID {\n\t\t\t\t\tif time.Since(value.lastSeen) > 65*time.Second {\n\t\t\t\t\t\tdelete(c.trackedServerSessionID, key)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tstate := &ClientUDPSessionServerTracker{\n\t\t\t\t\trxReplayDetector: replaydetector.New(1024, ^uint64(0)),\n\t\t\t\t}\n\t\t\t\tc.trackedServerSessionID[string(resp.SessionID[:])] = state\n\t\t\t\tc.parent.locker.Lock()\n\t\t\t\tc.parent.sessionMapAlias[string(resp.SessionID[:])] = string(resp.ClientSessionID[:])\n\t\t\t\tc.parent.locker.Unlock()\n\t\t\t\ttrackedState = state\n\t\t\t} else {\n\t\t\t\ttrackedState = trackedStateReceived\n\t\t\t}\n\n\t\t\tif accept, ok := trackedState.rxReplayDetector.Check(resp.PacketID); ok {\n\t\t\t\taccept()\n\t\t\t} else {\n\t\t\t\tnewError(\"misbehaving server: replayed packet\").Base(err).WriteToLog()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttrackedState.lastSeen = time.Now()\n\n\t\t\taddr = &net.UDPAddr{IP: resp.Address.IP(), Port: resp.Port}\n\t\t}\n\t\treturn n, addr, nil\n\t}\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/config.pb.go",
    "content": "package shadowsocks2022\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ClientConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tMethod        string                 `protobuf:\"bytes,1,opt,name=method,proto3\" json:\"method,omitempty\"`\n\tPsk           []byte                 `protobuf:\"bytes,2,opt,name=psk,proto3\" json:\"psk,omitempty\"`\n\tIpsk          [][]byte               `protobuf:\"bytes,4,rep,name=ipsk,proto3\" json:\"ipsk,omitempty\"`\n\tAddress       *net.IPOrDomain        `protobuf:\"bytes,5,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,6,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_shadowsocks2022_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_shadowsocks2022_config_proto_msgTypes[0]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_shadowsocks2022_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ClientConfig) GetMethod() string {\n\tif x != nil {\n\t\treturn x.Method\n\t}\n\treturn \"\"\n}\n\nfunc (x *ClientConfig) GetPsk() []byte {\n\tif x != nil {\n\t\treturn x.Psk\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetIpsk() [][]byte {\n\tif x != nil {\n\t\treturn x.Ipsk\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nvar File_proxy_shadowsocks2022_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_shadowsocks2022_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\\"proxy/shadowsocks2022/config.proto\\x12 v2ray.core.proxy.shadowsocks2022\\x1a\\x18common/net/address.proto\\x1a common/protoext/extensions.proto\\\"\\xc2\\x01\\n\" +\n\t\"\\fClientConfig\\x12\\x16\\n\" +\n\t\"\\x06method\\x18\\x01 \\x01(\\tR\\x06method\\x12\\x10\\n\" +\n\t\"\\x03psk\\x18\\x02 \\x01(\\fR\\x03psk\\x12\\x12\\n\" +\n\t\"\\x04ipsk\\x18\\x04 \\x03(\\fR\\x04ipsk\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x05 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x06 \\x01(\\rR\\x04port:#\\x82\\xb5\\x18\\x1f\\n\" +\n\t\"\\boutbound\\x12\\x0fshadowsocks2022\\x90\\xff)\\x01B\\x81\\x01\\n\" +\n\t\"$com.v2ray.core.proxy.shadowsocks2022P\\x01Z4github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022\\xaa\\x02 V2Ray.Core.Proxy.Shadowsocks2022b\\x06proto3\"\n\nvar (\n\tfile_proxy_shadowsocks2022_config_proto_rawDescOnce sync.Once\n\tfile_proxy_shadowsocks2022_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_shadowsocks2022_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_shadowsocks2022_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_shadowsocks2022_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_shadowsocks2022_config_proto_rawDesc), len(file_proxy_shadowsocks2022_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_shadowsocks2022_config_proto_rawDescData\n}\n\nvar file_proxy_shadowsocks2022_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_shadowsocks2022_config_proto_goTypes = []any{\n\t(*ClientConfig)(nil),   // 0: v2ray.core.proxy.shadowsocks2022.ClientConfig\n\t(*net.IPOrDomain)(nil), // 1: v2ray.core.common.net.IPOrDomain\n}\nvar file_proxy_shadowsocks2022_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.proxy.shadowsocks2022.ClientConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_shadowsocks2022_config_proto_init() }\nfunc file_proxy_shadowsocks2022_config_proto_init() {\n\tif File_proxy_shadowsocks2022_config_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: unsafe.Slice(unsafe.StringData(file_proxy_shadowsocks2022_config_proto_rawDesc), len(file_proxy_shadowsocks2022_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_shadowsocks2022_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_shadowsocks2022_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_shadowsocks2022_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_shadowsocks2022_config_proto = out.File\n\tfile_proxy_shadowsocks2022_config_proto_goTypes = nil\n\tfile_proxy_shadowsocks2022_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.shadowsocks2022;\noption csharp_namespace = \"V2Ray.Core.Proxy.Shadowsocks2022\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022\";\noption java_package = \"com.v2ray.core.proxy.shadowsocks2022\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"shadowsocks2022\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  string method = 1;\n  bytes psk = 2;\n  repeated bytes ipsk = 4;\n\n  v2ray.core.common.net.IPOrDomain address = 5;\n  uint32 port = 6;\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/eih_aes.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"crypto/subtle\"\n\t\"io\"\n\n\t\"github.com/v2fly/struc\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\n\t\"lukechampine.com/blake3\"\n)\n\nfunc newAESEIH(size int) *aesEIH {\n\treturn &aesEIH{length: size}\n}\n\nfunc newAESEIHWithData(size int, eih [][aesEIHSize]byte) *aesEIH {\n\treturn &aesEIH{length: size, eih: eih}\n}\n\nconst aesEIHSize = 16\n\ntype aesEIH struct {\n\teih    [][aesEIHSize]byte\n\tlength int\n}\n\nfunc (a *aesEIH) Pack(p []byte, opt *struc.Options) (int, error) {\n\tvar totalCopy int\n\tfor i := 0; i < a.length; i++ {\n\t\tn := copy(p[aesEIHSize*i:aesEIHSize*(i+1)], a.eih[i][:])\n\t\tif n != 16 {\n\t\t\treturn 0, newError(\"failed to pack aesEIH\")\n\t\t}\n\t\ttotalCopy += n\n\t}\n\treturn totalCopy, nil\n}\n\nfunc (a *aesEIH) Unpack(r io.Reader, length int, opt *struc.Options) error {\n\ta.eih = make([][aesEIHSize]byte, a.length)\n\tfor i := 0; i < a.length; i++ {\n\t\tn, err := r.Read(a.eih[i][:])\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to unpack aesEIH\").Base(err)\n\t\t}\n\t\tif n != aesEIHSize {\n\t\t\treturn newError(\"failed to unpack aesEIH\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (a *aesEIH) Size(opt *struc.Options) int {\n\treturn a.length * aesEIHSize\n}\n\nfunc (a *aesEIH) String() string {\n\treturn \"\"\n}\n\nconst aesEIHPskHashSize = 16\n\ntype aesEIHGenerator struct {\n\tipsk     [][]byte\n\tipskHash [][aesEIHPskHashSize]byte\n\tpsk      []byte\n\tpskHash  [aesEIHPskHashSize]byte\n\tlength   int\n}\n\nfunc newAESEIHGeneratorContainer(size int, effectivePsk []byte, ipsk [][]byte) *aesEIHGenerator {\n\tvar ipskHash [][aesEIHPskHashSize]byte\n\tfor _, v := range ipsk {\n\t\thash := blake3.Sum512(v)\n\t\tipskHash = append(ipskHash, [aesEIHPskHashSize]byte(hash[:16]))\n\t}\n\tpskHashFull := blake3.Sum512(effectivePsk)\n\tpskHash := [aesEIHPskHashSize]byte(pskHashFull[:16])\n\treturn &aesEIHGenerator{length: size, ipsk: ipsk, ipskHash: ipskHash, psk: effectivePsk, pskHash: pskHash}\n}\n\nfunc (a *aesEIHGenerator) GenerateEIH(derivation KeyDerivation, method Method, salt []byte) (ExtensibleIdentityHeaders, error) {\n\treturn a.generateEIHWithMask(derivation, method, salt, nil)\n}\n\nfunc (a *aesEIHGenerator) GenerateEIHUDP(derivation KeyDerivation, method Method, mask []byte) (ExtensibleIdentityHeaders, error) {\n\treturn a.generateEIHWithMask(derivation, method, nil, mask)\n}\n\nfunc (a *aesEIHGenerator) generateEIHWithMask(derivation KeyDerivation, method Method, salt, mask []byte) (ExtensibleIdentityHeaders, error) {\n\teih := make([][16]byte, a.length)\n\tcurrent := a.length - 1\n\tcurrentPskHash := a.pskHash\n\tfor {\n\t\tidentityKeyBuf := buf.New()\n\t\tidentityKey := identityKeyBuf.Extend(int32(method.GetSessionSubKeyAndSaltLength()))\n\t\tif mask == nil {\n\t\t\terr := derivation.GetIdentitySubKey(a.ipsk[current], salt, identityKey)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to get identity sub key\").Base(err)\n\t\t\t}\n\t\t} else {\n\t\t\tcopy(identityKey, a.ipsk[current])\n\t\t}\n\t\teih[current] = [16]byte{}\n\t\tif mask != nil {\n\t\t\tsubtle.XORBytes(currentPskHash[:], mask, currentPskHash[:])\n\t\t}\n\t\terr := method.GenerateEIH(identityKey, currentPskHash[:], eih[current][:])\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to generate EIH\").Base(err)\n\t\t}\n\t\tcurrent--\n\t\tif current < 0 {\n\t\t\tbreak\n\t\t}\n\t\tcurrentPskHash = a.ipskHash[current]\n\t\tidentityKeyBuf.Release()\n\t}\n\treturn newAESEIHWithData(a.length, eih), nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/encoding.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"bytes\"\n\t\"crypto/cipher\"\n\tcryptoRand \"crypto/rand\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/v2fly/struc\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\ntype TCPRequest struct {\n\tkeyDerivation KeyDerivation\n\tmethod        Method\n\n\tc2sSalt  RequestSalt\n\tc2sNonce crypto.BytesGenerator\n\tc2sAEAD  cipher.AEAD\n\n\ts2cSalt  RequestSalt\n\ts2cNonce crypto.BytesGenerator\n\ts2cAEAD  cipher.AEAD\n\n\ts2cSaltAssert         RequestSalt\n\ts2cInitialPayloadSize int\n}\n\nfunc (t *TCPRequest) EncodeTCPRequestHeader(effectivePsk []byte,\n\teih [][]byte, address DestinationAddress, destPort int, initialPayload []byte, out *buf.Buffer,\n) error {\n\trequestSalt := newRequestSaltWithLength(t.method.GetSessionSubKeyAndSaltLength())\n\t{\n\t\terr := requestSalt.FillAllFrom(cryptoRand.Reader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to fill salt\").Base(err)\n\t\t}\n\t}\n\tt.c2sSalt = requestSalt\n\tsessionKey := make([]byte, t.method.GetSessionSubKeyAndSaltLength())\n\t{\n\t\terr := t.keyDerivation.GetSessionSubKey(effectivePsk, requestSalt.Bytes(), sessionKey)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get session sub key\").Base(err)\n\t\t}\n\t}\n\n\taead, err := t.method.GetStreamAEAD(sessionKey)\n\tif err != nil {\n\t\treturn newError(\"failed to get stream AEAD\").Base(err)\n\t}\n\tt.c2sAEAD = aead\n\tpaddingLength := TCPMinPaddingLength\n\tif initialPayload == nil {\n\t\tinitialPayload = []byte{}\n\t\tpaddingLength += 1 + dice.RollWith(TCPMaxPaddingLength, cryptoRand.Reader)\n\t}\n\n\tvariableLengthHeader := &TCPRequestHeader3VariableLength{\n\t\tDestinationAddress: address,\n\t\tContents: struct {\n\t\t\tPaddingLength uint16 `struc:\"sizeof=Padding\"`\n\t\t\tPadding       []byte\n\t\t}(struct {\n\t\t\tPaddingLength uint16\n\t\t\tPadding       []byte\n\t\t}{\n\t\t\tPaddingLength: uint16(paddingLength),\n\t\t\tPadding:       make([]byte, paddingLength),\n\t\t}),\n\t}\n\tvariableLengthHeaderBuffer := buf.New()\n\tdefer variableLengthHeaderBuffer.Release()\n\t{\n\t\terr := addrParser.WriteAddressPort(variableLengthHeaderBuffer, address, net.Port(destPort))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to write address port\").Base(err)\n\t\t}\n\t}\n\t{\n\t\terr := struc.Pack(variableLengthHeaderBuffer, &variableLengthHeader.Contents)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to pack variable length header\").Base(err)\n\t\t}\n\t}\n\t{\n\t\t_, err := variableLengthHeaderBuffer.Write(initialPayload)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to write initial payload\").Base(err)\n\t\t}\n\t}\n\n\tfixedLengthHeader := &TCPRequestHeader2FixedLength{\n\t\tType:         TCPHeaderTypeClientToServerStream,\n\t\tTimestamp:    uint64(time.Now().Unix()),\n\t\tHeaderLength: uint16(variableLengthHeaderBuffer.Len()),\n\t}\n\n\tfixedLengthHeaderBuffer := buf.New()\n\tdefer fixedLengthHeaderBuffer.Release()\n\t{\n\t\terr := struc.Pack(fixedLengthHeaderBuffer, fixedLengthHeader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to pack fixed length header\").Base(err)\n\t\t}\n\t}\n\teihHeader := ExtensibleIdentityHeaders(newAESEIH(0))\n\tif len(eih) != 0 {\n\t\teihGenerator := newAESEIHGeneratorContainer(len(eih), effectivePsk, eih)\n\t\teihHeaderGenerated, err := eihGenerator.GenerateEIH(t.keyDerivation, t.method, requestSalt.Bytes())\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to construct EIH\").Base(err)\n\t\t}\n\t\teihHeader = eihHeaderGenerated\n\t}\n\tpreSessionKeyHeader := &TCPRequestHeader1PreSessionKey{\n\t\tSalt: requestSalt,\n\t\tEIH:  eihHeader,\n\t}\n\tpreSessionKeyHeaderBuffer := buf.New()\n\tdefer preSessionKeyHeaderBuffer.Release()\n\t{\n\t\terr := struc.Pack(preSessionKeyHeaderBuffer, preSessionKeyHeader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to pack pre session key header\").Base(err)\n\t\t}\n\t}\n\trequestNonce := crypto.GenerateInitialAEADNonce()\n\tt.c2sNonce = requestNonce\n\t{\n\t\tn, err := out.Write(preSessionKeyHeaderBuffer.BytesFrom(0))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to write pre session key header\").Base(err)\n\t\t}\n\t\tif int32(n) != preSessionKeyHeaderBuffer.Len() {\n\t\t\treturn newError(\"failed to write pre session key header\")\n\t\t}\n\t}\n\t{\n\t\tfixedLengthEncrypted := out.Extend(fixedLengthHeaderBuffer.Len() + int32(aead.Overhead()))\n\t\taead.Seal(fixedLengthEncrypted[:0], requestNonce(), fixedLengthHeaderBuffer.Bytes(), nil)\n\t}\n\t{\n\t\tvariableLengthEncrypted := out.Extend(variableLengthHeaderBuffer.Len() + int32(aead.Overhead()))\n\t\taead.Seal(variableLengthEncrypted[:0], requestNonce(), variableLengthHeaderBuffer.Bytes(), nil)\n\t}\n\treturn nil\n}\n\nfunc (t *TCPRequest) DecodeTCPResponseHeader(effectivePsk []byte, in io.Reader) error {\n\tvar preSessionKeyHeader TCPResponseHeader1PreSessionKey\n\tpreSessionKeyHeader.Salt = newRequestSaltWithLength(t.method.GetSessionSubKeyAndSaltLength())\n\t{\n\t\terr := struc.Unpack(in, &preSessionKeyHeader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to unpack pre session key header\").Base(err)\n\t\t}\n\t}\n\ts2cSalt := preSessionKeyHeader.Salt.Bytes()\n\tt.s2cSalt = preSessionKeyHeader.Salt\n\tsessionKey := make([]byte, t.method.GetSessionSubKeyAndSaltLength())\n\t{\n\t\terr := t.keyDerivation.GetSessionSubKey(effectivePsk, s2cSalt, sessionKey)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get session sub key\").Base(err)\n\t\t}\n\t}\n\taead, err := t.method.GetStreamAEAD(sessionKey)\n\tif err != nil {\n\t\treturn newError(\"failed to get stream AEAD\").Base(err)\n\t}\n\tt.s2cAEAD = aead\n\n\tfixedLengthHeaderEncryptedBuffer := buf.New()\n\tdefer fixedLengthHeaderEncryptedBuffer.Release()\n\t{\n\t\t_, err := fixedLengthHeaderEncryptedBuffer.ReadFullFrom(in, 11+int32(t.method.GetSessionSubKeyAndSaltLength())+int32(aead.Overhead()))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to read fixed length header encrypted\").Base(err)\n\t\t}\n\t}\n\ts2cNonce := crypto.GenerateInitialAEADNonce()\n\tt.s2cNonce = s2cNonce\n\tfixedLengthHeaderDecryptedBuffer := buf.New()\n\tdefer fixedLengthHeaderDecryptedBuffer.Release()\n\t{\n\t\tdecryptionBuffer := fixedLengthHeaderDecryptedBuffer.Extend(11 + int32(t.method.GetSessionSubKeyAndSaltLength()))\n\t\t_, err = aead.Open(decryptionBuffer[:0], s2cNonce(), fixedLengthHeaderEncryptedBuffer.Bytes(), nil)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to decrypt fixed length header\").Base(err)\n\t\t}\n\t}\n\tvar fixedLengthHeader TCPResponseHeader2FixedLength\n\tfixedLengthHeader.RequestSalt = newRequestSaltWithLength(t.method.GetSessionSubKeyAndSaltLength())\n\t{\n\t\terr := struc.Unpack(bytes.NewReader(fixedLengthHeaderDecryptedBuffer.Bytes()), &fixedLengthHeader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to unpack fixed length header\").Base(err)\n\t\t}\n\t}\n\n\tif fixedLengthHeader.Type != TCPHeaderTypeServerToClientStream {\n\t\treturn newError(\"unexpected TCP header type\")\n\t}\n\ttimeDifference := int64(fixedLengthHeader.Timestamp) - time.Now().Unix()\n\tif timeDifference < -30 || timeDifference > 30 {\n\t\treturn newError(\"timestamp is too far away, timeDifference = \", timeDifference)\n\t}\n\n\tt.s2cSaltAssert = fixedLengthHeader.RequestSalt\n\tt.s2cInitialPayloadSize = int(fixedLengthHeader.InitialPayloadLength)\n\treturn nil\n}\n\nfunc (t *TCPRequest) CheckC2SConnectionConstraint() error {\n\tif !bytes.Equal(t.c2sSalt.Bytes(), t.s2cSaltAssert.Bytes()) {\n\t\treturn newError(\"c2s salt not equal to s2c salt assert\")\n\t}\n\treturn nil\n}\n\nfunc (t *TCPRequest) CreateClientS2CReader(in io.Reader, initialPayload *buf.Buffer) (buf.Reader, error) {\n\tAEADAuthenticator := &crypto.AEADAuthenticator{\n\t\tAEAD:                    t.s2cAEAD,\n\t\tNonceGenerator:          t.s2cNonce,\n\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t}\n\tinitialPayloadEncrypted := buf.NewWithSize(65535)\n\tdefer initialPayloadEncrypted.Release()\n\tinitialPayloadEncryptedBytes := initialPayloadEncrypted.Extend(int32(t.s2cAEAD.Overhead()) + int32(t.s2cInitialPayloadSize))\n\t_, err := io.ReadFull(in, initialPayloadEncryptedBytes)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read initial payload\").Base(err)\n\t}\n\tinitialPayloadBytes := initialPayload.Extend(int32(t.s2cInitialPayloadSize))\n\t_, err = t.s2cAEAD.Open(initialPayloadBytes[:0], t.s2cNonce(), initialPayloadEncryptedBytes, nil)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to decrypt initial payload\").Base(err)\n\t}\n\treturn crypto.NewAuthenticationReader(AEADAuthenticator, &AEADChunkSizeParser{\n\t\tAuth: AEADAuthenticator,\n\t}, in, protocol.TransferTypeStream, nil), nil\n}\n\nfunc (t *TCPRequest) CreateClientC2SWriter(writer io.Writer) buf.Writer {\n\tAEADAuthenticator := &crypto.AEADAuthenticator{\n\t\tAEAD:                    t.c2sAEAD,\n\t\tNonceGenerator:          t.c2sNonce,\n\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t}\n\tsizeParser := &crypto.AEADChunkSizeParser{\n\t\tAuth: AEADAuthenticator,\n\t}\n\treturn crypto.NewAuthenticationWriter(AEADAuthenticator, sizeParser, writer, protocol.TransferTypeStream, nil)\n}\n\ntype AEADChunkSizeParser struct {\n\tAuth *crypto.AEADAuthenticator\n}\n\nfunc (p *AEADChunkSizeParser) HasConstantOffset() uint16 {\n\treturn uint16(p.Auth.Overhead())\n}\n\nfunc (p *AEADChunkSizeParser) SizeBytes() int32 {\n\treturn 2 + int32(p.Auth.Overhead())\n}\n\nfunc (p *AEADChunkSizeParser) Encode(size uint16, b []byte) []byte {\n\tbinary.BigEndian.PutUint16(b, size-uint16(p.Auth.Overhead()))\n\tb, err := p.Auth.Seal(b[:0], b[:2])\n\tcommon.Must(err)\n\treturn b\n}\n\nfunc (p *AEADChunkSizeParser) Decode(b []byte) (uint16, error) {\n\tb, err := p.Auth.Open(b[:0], b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn binary.BigEndian.Uint16(b), nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/errors.generated.go",
    "content": "package shadowsocks2022\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/kdf_blake3.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"lukechampine.com/blake3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\nfunc newBLAKE3KeyDerivation() *BLAKE3KeyDerivation {\n\treturn &BLAKE3KeyDerivation{}\n}\n\ntype BLAKE3KeyDerivation struct{}\n\nfunc (b BLAKE3KeyDerivation) GetSessionSubKey(effectivePsk, salt []byte, outKey []byte) error {\n\tkeyingMaterialBuffer := buf.New()\n\tkeyingMaterialBuffer.Write(effectivePsk)\n\tkeyingMaterialBuffer.Write(salt)\n\tblake3.DeriveKey(outKey, \"shadowsocks 2022 session subkey\", keyingMaterialBuffer.Bytes())\n\tkeyingMaterialBuffer.Release()\n\treturn nil\n}\n\nfunc (b BLAKE3KeyDerivation) GetIdentitySubKey(effectivePsk, salt []byte, outKey []byte) error {\n\tkeyingMaterialBuffer := buf.New()\n\tkeyingMaterialBuffer.Write(effectivePsk)\n\tkeyingMaterialBuffer.Write(salt)\n\tblake3.DeriveKey(outKey, \"shadowsocks 2022 identity subkey\", keyingMaterialBuffer.Bytes())\n\tkeyingMaterialBuffer.Release()\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/method_aes128gcm.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n)\n\nfunc newAES128GCMMethod() *AES128GCMMethod {\n\treturn &AES128GCMMethod{}\n}\n\ntype AES128GCMMethod struct{}\n\nfunc (a AES128GCMMethod) GetSessionSubKeyAndSaltLength() int {\n\treturn 16\n}\n\nfunc (a AES128GCMMethod) GetStreamAEAD(sessionSubKey []byte) (cipher.AEAD, error) {\n\taesCipher, err := aes.NewCipher(sessionSubKey)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES cipher\").Base(err)\n\t}\n\taead, err := cipher.NewGCM(aesCipher)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES-GCM AEAD\").Base(err)\n\t}\n\treturn aead, nil\n}\n\nfunc (a AES128GCMMethod) GenerateEIH(currentIdentitySubKey []byte, nextPskHash []byte, out []byte) error {\n\taesCipher, err := aes.NewCipher(currentIdentitySubKey)\n\tif err != nil {\n\t\treturn newError(\"failed to create AES cipher\").Base(err)\n\t}\n\taesCipher.Encrypt(out, nextPskHash)\n\treturn nil\n}\n\nfunc (a AES128GCMMethod) GetUDPClientProcessor(ipsk [][]byte, psk []byte, derivation KeyDerivation) (UDPClientPacketProcessor, error) {\n\treqSeparateHeaderPsk := psk\n\tif ipsk != nil {\n\t\treqSeparateHeaderPsk = ipsk[0]\n\t}\n\treqSeparateHeaderCipher, err := aes.NewCipher(reqSeparateHeaderPsk)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES cipher\").Base(err)\n\t}\n\trespSeparateHeaderCipher, err := aes.NewCipher(psk)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES cipher\").Base(err)\n\t}\n\tgetPacketAEAD := func(sessionID []byte) cipher.AEAD {\n\t\tsessionKey := make([]byte, a.GetSessionSubKeyAndSaltLength())\n\t\tderivation.GetSessionSubKey(psk, sessionID, sessionKey)\n\t\tblock, err := aes.NewCipher(sessionKey)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\taead, err := cipher.NewGCM(block)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\treturn aead\n\t}\n\tif len(ipsk) == 0 {\n\t\treturn NewAESUDPClientPacketProcessor(reqSeparateHeaderCipher, respSeparateHeaderCipher, getPacketAEAD, nil), nil\n\t}\n\teihGenerator := newAESEIHGeneratorContainer(len(ipsk), psk, ipsk)\n\tgetEIH := func(mask []byte) ExtensibleIdentityHeaders {\n\t\teih, err := eihGenerator.GenerateEIHUDP(derivation, a, mask)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to generate EIH\").Base(err).WriteToLog()\n\t\t}\n\t\treturn eih\n\t}\n\treturn NewAESUDPClientPacketProcessor(reqSeparateHeaderCipher, respSeparateHeaderCipher, getPacketAEAD, getEIH), nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/method_aes256gcm.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n)\n\nfunc newAES256GCMMethod() *AES256GCMMethod {\n\treturn &AES256GCMMethod{}\n}\n\ntype AES256GCMMethod struct{}\n\nfunc (a AES256GCMMethod) GetSessionSubKeyAndSaltLength() int {\n\treturn 32\n}\n\nfunc (a AES256GCMMethod) GetStreamAEAD(sessionSubKey []byte) (cipher.AEAD, error) {\n\taesCipher, err := aes.NewCipher(sessionSubKey)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES cipher\").Base(err)\n\t}\n\taead, err := cipher.NewGCM(aesCipher)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES-GCM AEAD\").Base(err)\n\t}\n\treturn aead, nil\n}\n\nfunc (a AES256GCMMethod) GenerateEIH(currentIdentitySubKey []byte, nextPskHash []byte, out []byte) error {\n\taesCipher, err := aes.NewCipher(currentIdentitySubKey)\n\tif err != nil {\n\t\treturn newError(\"failed to create AES cipher\").Base(err)\n\t}\n\taesCipher.Encrypt(out, nextPskHash)\n\treturn nil\n}\n\nfunc (a AES256GCMMethod) GetUDPClientProcessor(ipsk [][]byte, psk []byte, derivation KeyDerivation) (UDPClientPacketProcessor, error) {\n\treqSeparateHeaderPsk := psk\n\tif ipsk != nil {\n\t\treqSeparateHeaderPsk = ipsk[0]\n\t}\n\treqSeparateHeaderCipher, err := aes.NewCipher(reqSeparateHeaderPsk)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES cipher\").Base(err)\n\t}\n\trespSeparateHeaderCipher, err := aes.NewCipher(psk)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create AES cipher\").Base(err)\n\t}\n\tgetPacketAEAD := func(sessionID []byte) cipher.AEAD {\n\t\tsessionKey := make([]byte, a.GetSessionSubKeyAndSaltLength())\n\t\tderivation.GetSessionSubKey(psk, sessionID, sessionKey)\n\t\tblock, err := aes.NewCipher(sessionKey)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\taead, err := cipher.NewGCM(block)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\treturn aead\n\t}\n\tif len(ipsk) == 0 {\n\t\treturn NewAESUDPClientPacketProcessor(reqSeparateHeaderCipher, respSeparateHeaderCipher, getPacketAEAD, nil), nil\n\t}\n\teihGenerator := newAESEIHGeneratorContainer(len(ipsk), psk, ipsk)\n\tgetEIH := func(mask []byte) ExtensibleIdentityHeaders {\n\t\teih, err := eihGenerator.GenerateEIHUDP(derivation, a, mask)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to generate EIH\").Base(err).WriteToLog()\n\t\t}\n\t\treturn eih\n\t}\n\treturn NewAESUDPClientPacketProcessor(reqSeparateHeaderCipher, respSeparateHeaderCipher, getPacketAEAD, getEIH), nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/requestsalt.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"encoding/hex\"\n\t\"io\"\n\n\t\"github.com/v2fly/struc\"\n)\n\nfunc newRequestSaltWithLength(length int) RequestSalt {\n\treturn &requestSaltWithLength{length: length}\n}\n\ntype requestSaltWithLength struct {\n\tlength  int\n\tcontent []byte\n}\n\nfunc (r *requestSaltWithLength) isRequestSalt() {}\nfunc (r *requestSaltWithLength) Pack(p []byte, opt *struc.Options) (int, error) {\n\tn := copy(p, r.content)\n\tif n != r.length {\n\t\treturn 0, newError(\"failed to pack request salt with length\")\n\t}\n\treturn n, nil\n}\n\nfunc (r *requestSaltWithLength) Unpack(reader io.Reader, length int, opt *struc.Options) error {\n\tr.content = make([]byte, r.length)\n\tn, err := io.ReadFull(reader, r.content)\n\tif err != nil {\n\t\treturn newError(\"failed to unpack request salt with length\").Base(err)\n\t}\n\tif n != r.length {\n\t\treturn newError(\"failed to unpack request salt with length\")\n\t}\n\treturn nil\n}\n\nfunc (r *requestSaltWithLength) Size(opt *struc.Options) int {\n\treturn r.length\n}\n\nfunc (r *requestSaltWithLength) String() string {\n\treturn hex.Dump(r.content)\n}\n\nfunc (r *requestSaltWithLength) Bytes() []byte {\n\treturn r.content\n}\n\nfunc (r *requestSaltWithLength) FillAllFrom(reader io.Reader) error {\n\tr.content = make([]byte, r.length)\n\t_, err := io.ReadFull(reader, r.content)\n\tif err != nil {\n\t\treturn newError(\"failed to fill salt from reader\").Base(err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/ss2022.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"crypto/cipher\"\n\t\"io\"\n\n\t\"github.com/v2fly/struc\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype KeyDerivation interface {\n\tGetSessionSubKey(effectivePsk, Salt []byte, OutKey []byte) error\n\tGetIdentitySubKey(effectivePsk, Salt []byte, OutKey []byte) error\n}\n\ntype Method interface {\n\tGetSessionSubKeyAndSaltLength() int\n\tGetStreamAEAD(SessionSubKey []byte) (cipher.AEAD, error)\n\tGenerateEIH(CurrentIdentitySubKey []byte, nextPskHash []byte, out []byte) error\n\tGetUDPClientProcessor(ipsk [][]byte, psk []byte, derivation KeyDerivation) (UDPClientPacketProcessor, error)\n}\n\ntype ExtensibleIdentityHeaders interface {\n\tstruc.Custom\n}\n\ntype DestinationAddress interface {\n\tnet.Address\n}\n\ntype RequestSalt interface {\n\tstruc.Custom\n\tisRequestSalt()\n\tBytes() []byte\n\tFillAllFrom(reader io.Reader) error\n}\n\ntype TCPRequestHeader1PreSessionKey struct {\n\tSalt RequestSalt\n\tEIH  ExtensibleIdentityHeaders\n}\n\ntype TCPRequestHeader2FixedLength struct {\n\tType         byte\n\tTimestamp    uint64\n\tHeaderLength uint16\n}\n\ntype TCPRequestHeader3VariableLength struct {\n\tDestinationAddress DestinationAddress\n\tContents           struct {\n\t\tPaddingLength uint16 `struc:\"sizeof=Padding\"`\n\t\tPadding       []byte\n\t}\n}\n\ntype TCPRequestHeader struct {\n\tPreSessionKeyHeader TCPRequestHeader1PreSessionKey\n\tFixedLengthHeader   TCPRequestHeader2FixedLength\n\tHeader              TCPRequestHeader3VariableLength\n}\n\ntype TCPResponseHeader1PreSessionKey struct {\n\tSalt RequestSalt\n}\n\ntype TCPResponseHeader2FixedLength struct {\n\tType                 byte\n\tTimestamp            uint64\n\tRequestSalt          RequestSalt\n\tInitialPayloadLength uint16\n}\ntype TCPResponseHeader struct {\n\tPreSessionKeyHeader TCPResponseHeader1PreSessionKey\n\tHeader              TCPResponseHeader2FixedLength\n}\n\nconst (\n\tTCPHeaderTypeClientToServerStream = byte(0x00)\n\tTCPHeaderTypeServerToClientStream = byte(0x01)\n\tTCPMinPaddingLength               = 0\n\tTCPMaxPaddingLength               = 900\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6),\n\tprotocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),\n)\n\ntype UDPRequest struct {\n\tSessionID [8]byte\n\tPacketID  uint64\n\tTimeStamp uint64\n\tAddress   DestinationAddress\n\tPort      int\n\tPayload   *buf.Buffer\n}\n\ntype UDPResponse struct {\n\tUDPRequest\n\tClientSessionID [8]byte\n}\n\nconst (\n\tUDPHeaderTypeClientToServerStream = byte(0x00)\n\tUDPHeaderTypeServerToClientStream = byte(0x01)\n)\n\ntype UDPClientPacketProcessorCachedStateContainer interface {\n\tGetCachedState(sessionID string) UDPClientPacketProcessorCachedState\n\tPutCachedState(sessionID string, cache UDPClientPacketProcessorCachedState)\n\tGetCachedServerState(serverSessionID string) UDPClientPacketProcessorCachedState\n\tPutCachedServerState(serverSessionID string, cache UDPClientPacketProcessorCachedState)\n}\n\ntype UDPClientPacketProcessorCachedState interface{}\n\n// UDPClientPacketProcessor\n// Caller retain and receive all ownership of the buffer\ntype UDPClientPacketProcessor interface {\n\tEncodeUDPRequest(request *UDPRequest, out *buf.Buffer, cache UDPClientPacketProcessorCachedStateContainer) error\n\tDecodeUDPResp(input []byte, resp *UDPResponse, cache UDPClientPacketProcessorCachedStateContainer) error\n}\n"
  },
  {
    "path": "proxy/shadowsocks2022/udp_aes.go",
    "content": "package shadowsocks2022\n\nimport (\n\t\"bytes\"\n\t\"crypto/cipher\"\n\t\"io\"\n\n\t\"github.com/v2fly/struc\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype AESUDPClientPacketProcessor struct {\n\trequestSeparateHeaderBlockCipher  cipher.Block\n\tresponseSeparateHeaderBlockCipher cipher.Block\n\tmainPacketAEAD                    func([]byte) cipher.AEAD\n\tEIHGenerator                      func([]byte) ExtensibleIdentityHeaders\n}\n\nfunc NewAESUDPClientPacketProcessor(requestSeparateHeaderBlockCipher, responseSeparateHeaderBlockCipher cipher.Block, mainPacketAEAD func([]byte) cipher.AEAD, eih func([]byte) ExtensibleIdentityHeaders) *AESUDPClientPacketProcessor {\n\treturn &AESUDPClientPacketProcessor{\n\t\trequestSeparateHeaderBlockCipher:  requestSeparateHeaderBlockCipher,\n\t\tresponseSeparateHeaderBlockCipher: responseSeparateHeaderBlockCipher,\n\t\tmainPacketAEAD:                    mainPacketAEAD,\n\t\tEIHGenerator:                      eih,\n\t}\n}\n\ntype separateHeader struct {\n\tSessionID [8]byte\n\tPacketID  uint64\n}\n\ntype header struct {\n\tType          byte\n\tTimeStamp     uint64\n\tPaddingLength uint16 `struc:\"sizeof=Padding\"`\n\tPadding       []byte\n}\n\ntype respHeader struct {\n\tType            byte\n\tTimeStamp       uint64\n\tClientSessionID [8]byte\n\tPaddingLength   uint16 `struc:\"sizeof=Padding\"`\n\tPadding         []byte\n}\n\ntype cachedUDPState struct {\n\tsessionAEAD     cipher.AEAD\n\tsessionRecvAEAD cipher.AEAD\n}\n\nfunc (p *AESUDPClientPacketProcessor) EncodeUDPRequest(request *UDPRequest, out *buf.Buffer,\n\tcache UDPClientPacketProcessorCachedStateContainer,\n) error {\n\tseparateHeaderStruct := separateHeader{PacketID: request.PacketID, SessionID: request.SessionID}\n\tseparateHeaderBuffer := buf.New()\n\tdefer separateHeaderBuffer.Release()\n\t{\n\t\terr := struc.Pack(separateHeaderBuffer, &separateHeaderStruct)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to pack separateHeader\").Base(err)\n\t\t}\n\t}\n\tseparateHeaderBufferBytes := separateHeaderBuffer.Bytes()\n\t{\n\t\tencryptedDest := out.Extend(16)\n\t\tp.requestSeparateHeaderBlockCipher.Encrypt(encryptedDest, separateHeaderBufferBytes)\n\t}\n\n\tif p.EIHGenerator != nil {\n\t\teih := p.EIHGenerator(separateHeaderBufferBytes[0:16])\n\t\teihHeader := struct {\n\t\t\tEIH ExtensibleIdentityHeaders\n\t\t}{\n\t\t\tEIH: eih,\n\t\t}\n\t\terr := struc.Pack(out, &eihHeader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to pack eih\").Base(err)\n\t\t}\n\t}\n\n\theaderStruct := header{\n\t\tType:          UDPHeaderTypeClientToServerStream,\n\t\tTimeStamp:     request.TimeStamp,\n\t\tPaddingLength: 0,\n\t\tPadding:       nil,\n\t}\n\trequestBodyBuffer := buf.New()\n\t{\n\t\terr := struc.Pack(requestBodyBuffer, &headerStruct)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to header\").Base(err)\n\t\t}\n\t}\n\t{\n\t\terr := addrParser.WriteAddressPort(requestBodyBuffer, request.Address, net.Port(request.Port))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to write address port\").Base(err)\n\t\t}\n\t}\n\t{\n\t\t_, err := io.Copy(requestBodyBuffer, bytes.NewReader(request.Payload.Bytes()))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to copy payload\").Base(err)\n\t\t}\n\t}\n\t{\n\t\tcacheKey := string(separateHeaderBufferBytes[0:8])\n\t\treceivedCacheInterface := cache.GetCachedState(cacheKey)\n\t\tcachedState := &cachedUDPState{}\n\t\tif receivedCacheInterface != nil {\n\t\t\tcachedState = receivedCacheInterface.(*cachedUDPState)\n\t\t}\n\t\tif cachedState.sessionAEAD == nil {\n\t\t\tcachedState.sessionAEAD = p.mainPacketAEAD(separateHeaderBufferBytes[0:8])\n\t\t\tcache.PutCachedState(cacheKey, cachedState)\n\t\t}\n\n\t\tmainPacketAEADMaterialized := cachedState.sessionAEAD\n\n\t\tencryptedDest := out.Extend(int32(mainPacketAEADMaterialized.Overhead()) + requestBodyBuffer.Len())\n\t\tmainPacketAEADMaterialized.Seal(encryptedDest[:0], separateHeaderBuffer.Bytes()[4:16], requestBodyBuffer.Bytes(), nil)\n\t}\n\treturn nil\n}\n\nfunc (p *AESUDPClientPacketProcessor) DecodeUDPResp(input []byte, resp *UDPResponse,\n\tcache UDPClientPacketProcessorCachedStateContainer,\n) error {\n\tseparateHeaderBuffer := buf.New()\n\tdefer separateHeaderBuffer.Release()\n\t{\n\t\tencryptedDest := separateHeaderBuffer.Extend(16)\n\t\tp.responseSeparateHeaderBlockCipher.Decrypt(encryptedDest, input)\n\t}\n\tseparateHeaderStruct := separateHeader{}\n\t{\n\t\terr := struc.Unpack(separateHeaderBuffer, &separateHeaderStruct)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to unpack separateHeader\").Base(err)\n\t\t}\n\t}\n\tresp.PacketID = separateHeaderStruct.PacketID\n\tresp.SessionID = separateHeaderStruct.SessionID\n\t{\n\t\tcacheKey := string(separateHeaderBuffer.Bytes()[0:8])\n\t\treceivedCacheInterface := cache.GetCachedServerState(cacheKey)\n\t\tcachedState := &cachedUDPState{}\n\t\tif receivedCacheInterface != nil {\n\t\t\tcachedState = receivedCacheInterface.(*cachedUDPState)\n\t\t}\n\n\t\tif cachedState.sessionRecvAEAD == nil {\n\t\t\tcachedState.sessionRecvAEAD = p.mainPacketAEAD(separateHeaderBuffer.Bytes()[0:8])\n\t\t\tcache.PutCachedServerState(cacheKey, cachedState)\n\t\t}\n\n\t\tmainPacketAEADMaterialized := cachedState.sessionRecvAEAD\n\t\tdecryptedDestBuffer := buf.New()\n\t\tdecryptedDest := decryptedDestBuffer.Extend(int32(len(input)) - 16 - int32(mainPacketAEADMaterialized.Overhead()))\n\t\t_, err := mainPacketAEADMaterialized.Open(decryptedDest[:0], separateHeaderBuffer.Bytes()[4:16], input[16:], nil)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to open main packet\").Base(err)\n\t\t}\n\t\tdecryptedDestReader := bytes.NewReader(decryptedDest)\n\t\theaderStruct := respHeader{}\n\t\t{\n\t\t\terr := struc.Unpack(decryptedDestReader, &headerStruct)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to unpack header\").Base(err)\n\t\t\t}\n\t\t}\n\t\tresp.TimeStamp = headerStruct.TimeStamp\n\t\taddressReaderBuf := buf.New()\n\t\tdefer addressReaderBuf.Release()\n\t\tvar port net.Port\n\t\tresp.Address, port, err = addrParser.ReadAddressPort(addressReaderBuf, decryptedDestReader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to read address port\").Base(err)\n\t\t}\n\t\tresp.Port = int(port)\n\t\treadedLength := decryptedDestReader.Size() - int64(decryptedDestReader.Len())\n\t\tdecryptedDestBuffer.Advance(int32(readedLength))\n\t\tresp.Payload = decryptedDestBuffer\n\t\tresp.ClientSessionID = headerStruct.ClientSessionID\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "proxy/socks/client.go",
    "content": "package socks\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// Client is a Socks5 client.\ntype Client struct {\n\tserverPicker   protocol.ServerPicker\n\tpolicyManager  policy.Manager\n\tversion        Version\n\tdns            dns.Client\n\tdelayAuthWrite bool\n}\n\n// NewClient create a new Socks5 client based on the given config.\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Server {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get server spec\").Base(err)\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\tif serverList.Size() == 0 {\n\t\treturn nil, newError(\"0 target server\")\n\t}\n\n\tv := core.MustFromContext(ctx)\n\tc := &Client{\n\t\tserverPicker:   protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager:  v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t\tversion:        config.Version,\n\t\tdelayAuthWrite: config.DelayAuthWrite,\n\t}\n\tif config.Version == Version_SOCKS4 {\n\t\tc.dns = v.GetFeature(dns.ClientType()).(dns.Client)\n\t}\n\n\treturn c, nil\n}\n\n// Process implements proxy.Outbound.Process.\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified.\")\n\t}\n\t// Destination of the inner request.\n\tdestination := outbound.Target\n\n\t// Outbound server.\n\tvar server *protocol.ServerSpec\n\t// Outbound server's destination.\n\tvar dest net.Destination\n\t// Connection to the outbound server.\n\tvar conn internet.Connection\n\n\tif err := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tserver = c.serverPicker.PickServer()\n\t\tdest = server.Destination()\n\t\trawConn, err := dialer.Dial(ctx, dest)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconn = rawConn\n\n\t\treturn nil\n\t}); err != nil {\n\t\treturn newError(\"failed to find an available destination\").Base(err)\n\t}\n\n\tdefer func() {\n\t\tif err := conn.Close(); err != nil {\n\t\t\tnewError(\"failed to closed connection\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t}()\n\n\tp := c.policyManager.ForLevel(0)\n\n\trequest := &protocol.RequestHeader{\n\t\tVersion: socks5Version,\n\t\tCommand: protocol.RequestCommandTCP,\n\t\tAddress: destination.Address,\n\t\tPort:    destination.Port,\n\t}\n\n\tswitch c.version {\n\tcase Version_SOCKS4:\n\t\tif request.Address.Family().IsDomain() {\n\t\t\tips, err := dns.LookupIPWithOption(c.dns, request.Address.Domain(), dns.IPOption{IPv4Enable: true, IPv6Enable: false, FakeEnable: false})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t} else if len(ips) == 0 {\n\t\t\t\treturn dns.ErrEmptyResponse\n\t\t\t}\n\t\t\trequest.Address = net.IPAddress(ips[0])\n\t\t}\n\t\tfallthrough\n\tcase Version_SOCKS4A:\n\t\trequest.Version = socks4Version\n\n\t\tif destination.Network == net.Network_UDP {\n\t\t\treturn newError(\"udp is not supported in socks4\")\n\t\t} else if destination.Address.Family().IsIPv6() {\n\t\t\treturn newError(\"ipv6 is not supported in socks4\")\n\t\t}\n\t}\n\n\tif destination.Network == net.Network_UDP {\n\t\trequest.Command = protocol.RequestCommandUDP\n\t}\n\n\tuser := server.PickUser()\n\tif user != nil {\n\t\trequest.User = user\n\t\tp = c.policyManager.ForLevel(user.Level)\n\t}\n\n\tif err := conn.SetDeadline(time.Now().Add(p.Timeouts.Handshake)); err != nil {\n\t\tnewError(\"failed to set deadline for handshake\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tvar udpRequest *protocol.RequestHeader\n\tvar err error\n\tif request.Version == socks4Version {\n\t\terr = ClientHandshake4(request, conn, conn)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to establish connection to server\").AtWarning().Base(err)\n\t\t}\n\t} else {\n\t\tudpRequest, err = ClientHandshake(request, conn, conn, c.delayAuthWrite)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to establish connection to server\").AtWarning().Base(err)\n\t\t}\n\t}\n\n\tif udpRequest != nil {\n\t\tif udpRequest.Address == net.AnyIP || udpRequest.Address == net.AnyIPv6 {\n\t\t\tudpRequest.Address = dest.Address\n\t\t}\n\t}\n\n\tif err := conn.SetDeadline(time.Time{}); err != nil {\n\t\tnewError(\"failed to clear deadline after handshake\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, p.Timeouts.ConnectionIdle)\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\tudpConn, err := dialer.Dial(ctx, udpRequest.Destination())\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create UDP connection\").Base(err)\n\t\t}\n\t\tdefer udpConn.Close()\n\n\t\trequestDone := func() error {\n\t\t\tprotocolWriter := NewUDPWriter(request, udpConn)\n\t\t\treturn udp.CopyPacketConn(protocolWriter, packetConn, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\tprotocolReader := &UDPReader{\n\t\t\t\treader: udpConn,\n\t\t\t}\n\t\t\treturn udp.CopyPacketConn(packetConn, protocolReader, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tvar requestFunc func() error\n\tvar responseFunc func() error\n\tif request.Command == protocol.RequestCommandTCP {\n\t\trequestFunc = func() error {\n\t\t\tdefer timer.SetTimeout(p.Timeouts.DownlinkOnly)\n\t\t\treturn buf.Copy(link.Reader, buf.NewWriter(conn), buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseFunc = func() error {\n\t\t\tdefer timer.SetTimeout(p.Timeouts.UplinkOnly)\n\t\t\treturn buf.Copy(buf.NewReader(conn), link.Writer, buf.UpdateActivity(timer))\n\t\t}\n\t} else if request.Command == protocol.RequestCommandUDP {\n\t\tudpConn, err := dialer.Dial(ctx, udpRequest.Destination())\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create UDP connection\").Base(err)\n\t\t}\n\t\tdefer udpConn.Close()\n\t\trequestFunc = func() error {\n\t\t\tdefer timer.SetTimeout(p.Timeouts.DownlinkOnly)\n\t\t\treturn buf.Copy(link.Reader, &buf.SequentialWriter{Writer: NewUDPWriter(request, udpConn)}, buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseFunc = func() error {\n\t\t\tdefer timer.SetTimeout(p.Timeouts.UplinkOnly)\n\t\t\treader := &UDPReader{reader: udpConn}\n\t\t\treturn buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))\n\t\t}\n\t}\n\n\tresponseDonePost := task.OnSuccess(responseFunc, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestFunc, responseDonePost); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewClient(ctx, config.(*ClientConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/socks/config.go",
    "content": "package socks\n\nimport \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\nfunc (a *Account) Equals(another protocol.Account) bool {\n\tif account, ok := another.(*Account); ok {\n\t\treturn a.Username == account.Username\n\t}\n\treturn false\n}\n\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\treturn a, nil\n}\n\nfunc (c *ServerConfig) HasAccount(username, password string) bool {\n\tif c.Accounts == nil {\n\t\treturn false\n\t}\n\tstoredPassed, found := c.Accounts[username]\n\tif !found {\n\t\treturn false\n\t}\n\treturn storedPassed == password\n}\n"
  },
  {
    "path": "proxy/socks/config.pb.go",
    "content": "package socks\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// AuthType is the authentication type of Socks proxy.\ntype AuthType int32\n\nconst (\n\t// NO_AUTH is for anonymous authentication.\n\tAuthType_NO_AUTH AuthType = 0\n\t// PASSWORD is for username/password authentication.\n\tAuthType_PASSWORD AuthType = 1\n)\n\n// Enum value maps for AuthType.\nvar (\n\tAuthType_name = map[int32]string{\n\t\t0: \"NO_AUTH\",\n\t\t1: \"PASSWORD\",\n\t}\n\tAuthType_value = map[string]int32{\n\t\t\"NO_AUTH\":  0,\n\t\t\"PASSWORD\": 1,\n\t}\n)\n\nfunc (x AuthType) Enum() *AuthType {\n\tp := new(AuthType)\n\t*p = x\n\treturn p\n}\n\nfunc (x AuthType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (AuthType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_proxy_socks_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (AuthType) Type() protoreflect.EnumType {\n\treturn &file_proxy_socks_config_proto_enumTypes[0]\n}\n\nfunc (x AuthType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use AuthType.Descriptor instead.\nfunc (AuthType) EnumDescriptor() ([]byte, []int) {\n\treturn file_proxy_socks_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Version int32\n\nconst (\n\tVersion_SOCKS5  Version = 0\n\tVersion_SOCKS4  Version = 1\n\tVersion_SOCKS4A Version = 2\n)\n\n// Enum value maps for Version.\nvar (\n\tVersion_name = map[int32]string{\n\t\t0: \"SOCKS5\",\n\t\t1: \"SOCKS4\",\n\t\t2: \"SOCKS4A\",\n\t}\n\tVersion_value = map[string]int32{\n\t\t\"SOCKS5\":  0,\n\t\t\"SOCKS4\":  1,\n\t\t\"SOCKS4A\": 2,\n\t}\n)\n\nfunc (x Version) Enum() *Version {\n\tp := new(Version)\n\t*p = x\n\treturn p\n}\n\nfunc (x Version) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Version) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_proxy_socks_config_proto_enumTypes[1].Descriptor()\n}\n\nfunc (Version) Type() protoreflect.EnumType {\n\treturn &file_proxy_socks_config_proto_enumTypes[1]\n}\n\nfunc (x Version) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Version.Descriptor instead.\nfunc (Version) EnumDescriptor() ([]byte, []int) {\n\treturn file_proxy_socks_config_proto_rawDescGZIP(), []int{1}\n}\n\n// Account represents a Socks account.\ntype Account struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUsername      string                 `protobuf:\"bytes,1,opt,name=username,proto3\" json:\"username,omitempty\"`\n\tPassword      string                 `protobuf:\"bytes,2,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_socks_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_socks_config_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_socks_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Account) GetUsername() string {\n\tif x != nil {\n\t\treturn x.Username\n\t}\n\treturn \"\"\n}\n\nfunc (x *Account) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\n// ServerConfig is the protobuf config for Socks server.\ntype ServerConfig struct {\n\tstate      protoimpl.MessageState `protogen:\"open.v1\"`\n\tAuthType   AuthType               `protobuf:\"varint,1,opt,name=auth_type,json=authType,proto3,enum=v2ray.core.proxy.socks.AuthType\" json:\"auth_type,omitempty\"`\n\tAccounts   map[string]string      `protobuf:\"bytes,2,rep,name=accounts,proto3\" json:\"accounts,omitempty\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n\tAddress    *net.IPOrDomain        `protobuf:\"bytes,3,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tUdpEnabled bool                   `protobuf:\"varint,4,opt,name=udp_enabled,json=udpEnabled,proto3\" json:\"udp_enabled,omitempty\"`\n\t// Deprecated: Marked as deprecated in proxy/socks/config.proto.\n\tTimeout        uint32                    `protobuf:\"varint,5,opt,name=timeout,proto3\" json:\"timeout,omitempty\"`\n\tUserLevel      uint32                    `protobuf:\"varint,6,opt,name=user_level,json=userLevel,proto3\" json:\"user_level,omitempty\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,7,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tDeferLastReply bool                      `protobuf:\"varint,8,opt,name=defer_last_reply,json=deferLastReply,proto3\" json:\"defer_last_reply,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_socks_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_socks_config_proto_msgTypes[1]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_socks_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ServerConfig) GetAuthType() AuthType {\n\tif x != nil {\n\t\treturn x.AuthType\n\t}\n\treturn AuthType_NO_AUTH\n}\n\nfunc (x *ServerConfig) GetAccounts() map[string]string {\n\tif x != nil {\n\t\treturn x.Accounts\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetUdpEnabled() bool {\n\tif x != nil {\n\t\treturn x.UdpEnabled\n\t}\n\treturn false\n}\n\n// Deprecated: Marked as deprecated in proxy/socks/config.proto.\nfunc (x *ServerConfig) GetTimeout() uint32 {\n\tif x != nil {\n\t\treturn x.Timeout\n\t}\n\treturn 0\n}\n\nfunc (x *ServerConfig) GetUserLevel() uint32 {\n\tif x != nil {\n\t\treturn x.UserLevel\n\t}\n\treturn 0\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\nfunc (x *ServerConfig) GetDeferLastReply() bool {\n\tif x != nil {\n\t\treturn x.DeferLastReply\n\t}\n\treturn false\n}\n\n// ClientConfig is the protobuf config for Socks client.\ntype ClientConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Sever is a list of Socks server addresses.\n\tServer         []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=server,proto3\" json:\"server,omitempty\"`\n\tVersion        Version                    `protobuf:\"varint,2,opt,name=version,proto3,enum=v2ray.core.proxy.socks.Version\" json:\"version,omitempty\"`\n\tDelayAuthWrite bool                       `protobuf:\"varint,3,opt,name=delay_auth_write,json=delayAuthWrite,proto3\" json:\"delay_auth_write,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_socks_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_socks_config_proto_msgTypes[2]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_socks_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetVersion() Version {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn Version_SOCKS5\n}\n\nfunc (x *ClientConfig) GetDelayAuthWrite() bool {\n\tif x != nil {\n\t\treturn x.DelayAuthWrite\n\t}\n\treturn false\n}\n\nvar File_proxy_socks_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_socks_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x18proxy/socks/config.proto\\x12\\x16v2ray.core.proxy.socks\\x1a\\x18common/net/address.proto\\x1a\\\"common/net/packetaddr/config.proto\\x1a!common/protocol/server_spec.proto\\\"A\\n\" +\n\t\"\\aAccount\\x12\\x1a\\n\" +\n\t\"\\busername\\x18\\x01 \\x01(\\tR\\busername\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x02 \\x01(\\tR\\bpassword\\\"\\xf3\\x03\\n\" +\n\t\"\\fServerConfig\\x12=\\n\" +\n\t\"\\tauth_type\\x18\\x01 \\x01(\\x0e2 .v2ray.core.proxy.socks.AuthTypeR\\bauthType\\x12N\\n\" +\n\t\"\\baccounts\\x18\\x02 \\x03(\\v22.v2ray.core.proxy.socks.ServerConfig.AccountsEntryR\\baccounts\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x03 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x1f\\n\" +\n\t\"\\vudp_enabled\\x18\\x04 \\x01(\\bR\\n\" +\n\t\"udpEnabled\\x12\\x1c\\n\" +\n\t\"\\atimeout\\x18\\x05 \\x01(\\rB\\x02\\x18\\x01R\\atimeout\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"user_level\\x18\\x06 \\x01(\\rR\\tuserLevel\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\a \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding\\x12(\\n\" +\n\t\"\\x10defer_last_reply\\x18\\b \\x01(\\bR\\x0edeferLastReply\\x1a;\\n\" +\n\t\"\\rAccountsEntry\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value:\\x028\\x01\\\"\\xb7\\x01\\n\" +\n\t\"\\fClientConfig\\x12B\\n\" +\n\t\"\\x06server\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x06server\\x129\\n\" +\n\t\"\\aversion\\x18\\x02 \\x01(\\x0e2\\x1f.v2ray.core.proxy.socks.VersionR\\aversion\\x12(\\n\" +\n\t\"\\x10delay_auth_write\\x18\\x03 \\x01(\\bR\\x0edelayAuthWrite*%\\n\" +\n\t\"\\bAuthType\\x12\\v\\n\" +\n\t\"\\aNO_AUTH\\x10\\x00\\x12\\f\\n\" +\n\t\"\\bPASSWORD\\x10\\x01*.\\n\" +\n\t\"\\aVersion\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06SOCKS5\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06SOCKS4\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aSOCKS4A\\x10\\x02Bc\\n\" +\n\t\"\\x1acom.v2ray.core.proxy.socksP\\x01Z*github.com/v2fly/v2ray-core/v5/proxy/socks\\xaa\\x02\\x16V2Ray.Core.Proxy.Socksb\\x06proto3\"\n\nvar (\n\tfile_proxy_socks_config_proto_rawDescOnce sync.Once\n\tfile_proxy_socks_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_socks_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_socks_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_socks_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_socks_config_proto_rawDesc), len(file_proxy_socks_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_socks_config_proto_rawDescData\n}\n\nvar file_proxy_socks_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)\nvar file_proxy_socks_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_proxy_socks_config_proto_goTypes = []any{\n\t(AuthType)(0),                   // 0: v2ray.core.proxy.socks.AuthType\n\t(Version)(0),                    // 1: v2ray.core.proxy.socks.Version\n\t(*Account)(nil),                 // 2: v2ray.core.proxy.socks.Account\n\t(*ServerConfig)(nil),            // 3: v2ray.core.proxy.socks.ServerConfig\n\t(*ClientConfig)(nil),            // 4: v2ray.core.proxy.socks.ClientConfig\n\tnil,                             // 5: v2ray.core.proxy.socks.ServerConfig.AccountsEntry\n\t(*net.IPOrDomain)(nil),          // 6: v2ray.core.common.net.IPOrDomain\n\t(packetaddr.PacketAddrType)(0),  // 7: v2ray.core.net.packetaddr.PacketAddrType\n\t(*protocol.ServerEndpoint)(nil), // 8: v2ray.core.common.protocol.ServerEndpoint\n}\nvar file_proxy_socks_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.proxy.socks.ServerConfig.auth_type:type_name -> v2ray.core.proxy.socks.AuthType\n\t5, // 1: v2ray.core.proxy.socks.ServerConfig.accounts:type_name -> v2ray.core.proxy.socks.ServerConfig.AccountsEntry\n\t6, // 2: v2ray.core.proxy.socks.ServerConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t7, // 3: v2ray.core.proxy.socks.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t8, // 4: v2ray.core.proxy.socks.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t1, // 5: v2ray.core.proxy.socks.ClientConfig.version:type_name -> v2ray.core.proxy.socks.Version\n\t6, // [6:6] is the sub-list for method output_type\n\t6, // [6:6] is the sub-list for method input_type\n\t6, // [6:6] is the sub-list for extension type_name\n\t6, // [6:6] is the sub-list for extension extendee\n\t0, // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_socks_config_proto_init() }\nfunc file_proxy_socks_config_proto_init() {\n\tif File_proxy_socks_config_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: unsafe.Slice(unsafe.StringData(file_proxy_socks_config_proto_rawDesc), len(file_proxy_socks_config_proto_rawDesc)),\n\t\t\tNumEnums:      2,\n\t\t\tNumMessages:   4,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_socks_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_socks_config_proto_depIdxs,\n\t\tEnumInfos:         file_proxy_socks_config_proto_enumTypes,\n\t\tMessageInfos:      file_proxy_socks_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_socks_config_proto = out.File\n\tfile_proxy_socks_config_proto_goTypes = nil\n\tfile_proxy_socks_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/socks/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.socks;\noption csharp_namespace = \"V2Ray.Core.Proxy.Socks\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/socks\";\noption java_package = \"com.v2ray.core.proxy.socks\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/net/packetaddr/config.proto\";\nimport \"common/protocol/server_spec.proto\";\n\n// Account represents a Socks account.\nmessage Account {\n  string username = 1;\n  string password = 2;\n}\n\n// AuthType is the authentication type of Socks proxy.\nenum AuthType {\n  // NO_AUTH is for anonymous authentication.\n  NO_AUTH = 0;\n  // PASSWORD is for username/password authentication.\n  PASSWORD = 1;\n}\n\nenum Version {\n  SOCKS5 = 0;\n  SOCKS4 = 1;\n  SOCKS4A = 2;\n}\n\n\n// ServerConfig is the protobuf config for Socks server.\nmessage ServerConfig {\n  AuthType auth_type = 1;\n  map<string, string> accounts = 2;\n  v2ray.core.common.net.IPOrDomain address = 3;\n  bool udp_enabled = 4;\n  uint32 timeout = 5 [deprecated = true];\n  uint32 user_level = 6;\n\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 7;\n  bool defer_last_reply = 8;\n}\n\n// ClientConfig is the protobuf config for Socks client.\nmessage ClientConfig {\n  // Sever is a list of Socks server addresses.\n  repeated v2ray.core.common.protocol.ServerEndpoint server = 1;\n  Version version = 2;\n\n  bool delay_auth_write = 3;\n}\n"
  },
  {
    "path": "proxy/socks/errors.generated.go",
    "content": "package socks\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/socks/protocol.go",
    "content": "package socks\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\tgonet \"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nconst (\n\tsocks5Version = 0x05\n\tsocks4Version = 0x04\n\n\tcmdTCPConnect    = 0x01\n\tcmdTCPBind       = 0x02\n\tcmdUDPAssociate  = 0x03\n\tcmdTorResolve    = 0xF0\n\tcmdTorResolvePTR = 0xF1\n\n\tsocks4RequestGranted  = 90\n\tsocks4RequestRejected = 91\n\n\tauthNotRequired = 0x00\n\t// authGssAPI           = 0x01\n\tauthPassword         = 0x02\n\tauthNoMatchingMethod = 0xFF\n\n\tstatusSuccess       = 0x00\n\tstatusConnRefused   = 0x05\n\tstatusCmdNotSupport = 0x07\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6),\n\tprotocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),\n)\n\ntype ServerSession struct {\n\tconfig         *ServerConfig\n\taddress        net.Address\n\tport           net.Port\n\tclientAddress  net.Address\n\tflushLastReply func(bool) error\n}\n\nfunc (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {\n\tif s.config.AuthType == AuthType_PASSWORD {\n\t\twriteSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0))\n\t\treturn nil, newError(\"socks 4 is not allowed when auth is required.\")\n\t}\n\n\tvar port net.Port\n\tvar address net.Address\n\n\t{\n\t\tbuffer := buf.StackNew()\n\t\tif _, err := buffer.ReadFullFrom(reader, 6); err != nil {\n\t\t\tbuffer.Release()\n\t\t\treturn nil, newError(\"insufficient header\").Base(err)\n\t\t}\n\t\tport = net.PortFromBytes(buffer.BytesRange(0, 2))\n\t\taddress = net.IPAddress(buffer.BytesRange(2, 6))\n\t\tbuffer.Release()\n\t}\n\n\tif _, err := ReadUntilNull(reader); /* user id */ err != nil {\n\t\treturn nil, err\n\t}\n\tif address.IP()[0] == 0x00 {\n\t\tdomain, err := ReadUntilNull(reader)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to read domain for socks 4a\").Base(err)\n\t\t}\n\t\taddress = net.DomainAddress(domain)\n\t}\n\n\tswitch cmd {\n\tcase cmdTCPConnect:\n\t\trequest := &protocol.RequestHeader{\n\t\t\tCommand: protocol.RequestCommandTCP,\n\t\t\tAddress: address,\n\t\t\tPort:    port,\n\t\t\tVersion: socks4Version,\n\t\t}\n\t\tif err := s.setupLastReply(func(ok bool) error {\n\t\t\tif ok {\n\t\t\t\treturn writeSocks4Response(writer, socks4RequestGranted, net.AnyIP, net.Port(0))\n\t\t\t} else {\n\t\t\t\treturn writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0))\n\t\t\t}\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn request, nil\n\tdefault:\n\t\twriteSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0))\n\t\treturn nil, newError(\"unsupported command: \", cmd)\n\t}\n}\n\nfunc (s *ServerSession) auth5(nMethod byte, reader io.Reader, writer io.Writer) (username string, err error) {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tif _, err = buffer.ReadFullFrom(reader, int32(nMethod)); err != nil {\n\t\treturn \"\", newError(\"failed to read auth methods\").Base(err)\n\t}\n\n\tvar expectedAuth byte = authNotRequired\n\tif s.config.AuthType == AuthType_PASSWORD {\n\t\texpectedAuth = authPassword\n\t}\n\n\tif !hasAuthMethod(expectedAuth, buffer.BytesRange(0, int32(nMethod))) {\n\t\twriteSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod)\n\t\treturn \"\", newError(\"no matching auth method\")\n\t}\n\n\tif err := writeSocks5AuthenticationResponse(writer, socks5Version, expectedAuth); err != nil {\n\t\treturn \"\", newError(\"failed to write auth response\").Base(err)\n\t}\n\n\tif expectedAuth == authPassword {\n\t\tusername, password, err := ReadUsernamePassword(reader)\n\t\tif err != nil {\n\t\t\treturn \"\", newError(\"failed to read username and password for authentication\").Base(err)\n\t\t}\n\n\t\tif !s.config.HasAccount(username, password) {\n\t\t\twriteSocks5AuthenticationResponse(writer, 0x01, 0xFF)\n\t\t\treturn \"\", newError(\"invalid username or password\")\n\t\t}\n\n\t\tif err := writeSocks5AuthenticationResponse(writer, 0x01, 0x00); err != nil {\n\t\t\treturn \"\", newError(\"failed to write auth response\").Base(err)\n\t\t}\n\t\treturn username, nil\n\t}\n\n\treturn \"\", nil\n}\n\nfunc (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {\n\tvar (\n\t\tusername string\n\t\terr      error\n\t)\n\tif username, err = s.auth5(nMethod, reader, writer); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar cmd byte\n\t{\n\t\tbuffer := buf.StackNew()\n\t\tif _, err := buffer.ReadFullFrom(reader, 3); err != nil {\n\t\t\tbuffer.Release()\n\t\t\treturn nil, newError(\"failed to read request\").Base(err)\n\t\t}\n\t\tcmd = buffer.Byte(1)\n\t\tbuffer.Release()\n\t}\n\n\trequest := new(protocol.RequestHeader)\n\tif username != \"\" {\n\t\trequest.User = &protocol.MemoryUser{Email: username}\n\t}\n\tswitch cmd {\n\tcase cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR:\n\t\t// We don't have a solution for Tor case now. Simply treat it as connect command.\n\t\trequest.Command = protocol.RequestCommandTCP\n\tcase cmdUDPAssociate:\n\t\tif !s.config.UdpEnabled {\n\t\t\twriteSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))\n\t\t\treturn nil, newError(\"UDP is not enabled.\")\n\t\t}\n\t\trequest.Command = protocol.RequestCommandUDP\n\tcase cmdTCPBind:\n\t\twriteSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))\n\t\treturn nil, newError(\"TCP bind is not supported.\")\n\tdefault:\n\t\twriteSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0))\n\t\treturn nil, newError(\"unknown command \", cmd)\n\t}\n\n\trequest.Version = socks5Version\n\n\taddr, port, err := addrParser.ReadAddressPort(nil, reader)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read address\").Base(err)\n\t}\n\trequest.Address = addr\n\trequest.Port = port\n\n\tresponseAddress := s.address\n\tresponsePort := s.port\n\t//nolint:gocritic // Use if else chain for clarity\n\tif request.Command == protocol.RequestCommandUDP {\n\t\tif s.config.Address != nil {\n\t\t\t// Use configured IP as remote address in the response to UdpAssociate\n\t\t\tresponseAddress = s.config.Address.AsAddress()\n\t\t} else if s.clientAddress == net.LocalHostIP || s.clientAddress == net.LocalHostIPv6 {\n\t\t\t// For localhost clients use loopback IP\n\t\t\tresponseAddress = s.clientAddress\n\t\t} else {\n\t\t\t// For non-localhost clients use inbound listening address\n\t\t\tresponseAddress = s.address\n\t\t}\n\t}\n\tif err := s.setupLastReply(func(ok bool) error {\n\t\tif ok {\n\t\t\treturn writeSocks5Response(writer, statusSuccess, responseAddress, responsePort)\n\t\t} else {\n\t\t\treturn writeSocks5Response(writer, statusConnRefused, net.AnyIP, net.Port(0))\n\t\t}\n\t}); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn request, nil\n}\n\n// Sets the callback and calls or postpones it based on the boolean field\nfunc (s *ServerSession) setupLastReply(callback func(bool) error) error {\n\tnoOpCallback := func(bool) error {\n\t\treturn nil\n\t}\n\n\t// set the field even if we call it now because it will be called again\n\ts.flushLastReply = func(ok bool) error {\n\t\ts.flushLastReply = noOpCallback\n\t\treturn callback(ok)\n\t}\n\n\tif s.config.GetDeferLastReply() {\n\t\treturn nil\n\t}\n\treturn s.flushLastReply(true)\n}\n\n// Handshake performs a Socks4/4a/5 handshake.\nfunc (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {\n\tbuffer := buf.StackNew()\n\tif _, err := buffer.ReadFullFrom(reader, 2); err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, newError(\"insufficient header\").Base(err)\n\t}\n\n\tversion := buffer.Byte(0)\n\tcmd := buffer.Byte(1)\n\tbuffer.Release()\n\n\tswitch version {\n\tcase socks4Version:\n\t\treturn s.handshake4(cmd, reader, writer)\n\tcase socks5Version:\n\t\treturn s.handshake5(cmd, reader, writer)\n\tdefault:\n\t\treturn nil, newError(\"unknown Socks version: \", version)\n\t}\n}\n\n// ReadUsernamePassword reads Socks 5 username/password message from the given reader.\n// +----+------+----------+------+----------+\n// |VER | ULEN |  UNAME   | PLEN |  PASSWD  |\n// +----+------+----------+------+----------+\n// | 1  |  1   | 1 to 255 |  1   | 1 to 255 |\n// +----+------+----------+------+----------+\nfunc ReadUsernamePassword(reader io.Reader) (string, string, error) {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tif _, err := buffer.ReadFullFrom(reader, 2); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tnUsername := int32(buffer.Byte(1))\n\n\tbuffer.Clear()\n\tif _, err := buffer.ReadFullFrom(reader, nUsername); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tusername := buffer.String()\n\n\tbuffer.Clear()\n\tif _, err := buffer.ReadFullFrom(reader, 1); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tnPassword := int32(buffer.Byte(0))\n\n\tbuffer.Clear()\n\tif _, err := buffer.ReadFullFrom(reader, nPassword); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tpassword := buffer.String()\n\treturn username, password, nil\n}\n\n// ReadUntilNull reads content from given reader, until a null (0x00) byte.\nfunc ReadUntilNull(reader io.Reader) (string, error) {\n\tb := buf.StackNew()\n\tdefer b.Release()\n\n\tfor {\n\t\t_, err := b.ReadFullFrom(reader, 1)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tif b.Byte(b.Len()-1) == 0x00 {\n\t\t\tb.Resize(0, b.Len()-1)\n\t\t\treturn b.String(), nil\n\t\t}\n\t\tif b.IsFull() {\n\t\t\treturn \"\", newError(\"buffer overrun\")\n\t\t}\n\t}\n}\n\nfunc hasAuthMethod(expectedAuth byte, authCandidates []byte) bool {\n\tfor _, a := range authCandidates {\n\t\tif a == expectedAuth {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc writeSocks5AuthenticationResponse(writer io.Writer, version byte, auth byte) error {\n\treturn buf.WriteAllBytes(writer, []byte{version, auth})\n}\n\nfunc writeSocks5Response(writer io.Writer, errCode byte, address net.Address, port net.Port) error {\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\n\tcommon.Must2(buffer.Write([]byte{socks5Version, errCode, 0x00 /* reserved */}))\n\tif err := addrParser.WriteAddressPort(buffer, address, port); err != nil {\n\t\treturn err\n\t}\n\n\treturn buf.WriteAllBytes(writer, buffer.Bytes())\n}\n\nfunc writeSocks4Response(writer io.Writer, errCode byte, address net.Address, port net.Port) error {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tcommon.Must(buffer.WriteByte(0x00))\n\tcommon.Must(buffer.WriteByte(errCode))\n\tportBytes := buffer.Extend(2)\n\tbinary.BigEndian.PutUint16(portBytes, port.Value())\n\tcommon.Must2(buffer.Write(address.IP()))\n\treturn buf.WriteAllBytes(writer, buffer.Bytes())\n}\n\nfunc DecodeUDPPacket(packet *buf.Buffer) (*protocol.RequestHeader, error) {\n\tif packet.Len() < 5 {\n\t\treturn nil, newError(\"insufficient length of packet.\")\n\t}\n\trequest := &protocol.RequestHeader{\n\t\tVersion: socks5Version,\n\t\tCommand: protocol.RequestCommandUDP,\n\t}\n\n\t// packet[0] and packet[1] are reserved\n\tif packet.Byte(2) != 0 /* fragments */ {\n\t\treturn nil, newError(\"discarding fragmented payload.\")\n\t}\n\n\tpacket.Advance(3)\n\n\taddr, port, err := addrParser.ReadAddressPort(nil, packet)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read UDP header\").Base(err)\n\t}\n\trequest.Address = addr\n\trequest.Port = port\n\treturn request, nil\n}\n\nfunc EncodeUDPPacket(request *protocol.RequestHeader, data []byte) (*buf.Buffer, error) {\n\tb := buf.New()\n\tcommon.Must2(b.Write([]byte{0, 0, 0 /* Fragment */}))\n\tif err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {\n\t\tb.Release()\n\t\treturn nil, err\n\t}\n\tcommon.Must2(b.Write(data))\n\treturn b, nil\n}\n\nfunc EncodeUDPPacketFromAddress(address net.Destination, data []byte) (*buf.Buffer, error) {\n\tb := buf.New()\n\tcommon.Must2(b.Write([]byte{0, 0, 0 /* Fragment */}))\n\tif err := addrParser.WriteAddressPort(b, address.Address, address.Port); err != nil {\n\t\tb.Release()\n\t\treturn nil, err\n\t}\n\tcommon.Must2(b.Write(data))\n\treturn b, nil\n}\n\ntype UDPReader struct {\n\treader io.Reader\n}\n\nfunc NewUDPReader(reader io.Reader) *UDPReader {\n\treturn &UDPReader{reader: reader}\n}\n\nfunc (r *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tb := buf.New()\n\tif _, err := b.ReadFrom(r.reader); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err := DecodeUDPPacket(b); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf.MultiBuffer{b}, nil\n}\n\nfunc (r *UDPReader) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) {\n\tbuffer := buf.New()\n\t_, err = buffer.ReadFrom(r.reader)\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn 0, nil, err\n\t}\n\treq, err := DecodeUDPPacket(buffer)\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn 0, nil, err\n\t}\n\tn = copy(p, buffer.Bytes())\n\tbuffer.Release()\n\treturn n, &gonet.UDPAddr{IP: req.Address.IP(), Port: int(req.Port)}, nil\n}\n\ntype UDPWriter struct {\n\trequest *protocol.RequestHeader\n\twriter  io.Writer\n}\n\nfunc NewUDPWriter(request *protocol.RequestHeader, writer io.Writer) *UDPWriter {\n\treturn &UDPWriter{\n\t\trequest: request,\n\t\twriter:  writer,\n\t}\n}\n\n// Write implements io.Writer.\nfunc (w *UDPWriter) Write(b []byte) (int, error) {\n\teb, err := EncodeUDPPacket(w.request, b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer eb.Release()\n\tif _, err := w.writer.Write(eb.Bytes()); err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(b), nil\n}\n\nfunc (w *UDPWriter) WriteTo(payload []byte, addr gonet.Addr) (n int, err error) {\n\trequest := *w.request\n\tudpAddr := addr.(*gonet.UDPAddr)\n\trequest.Command = protocol.RequestCommandUDP\n\trequest.Address = net.IPAddress(udpAddr.IP)\n\trequest.Port = net.Port(udpAddr.Port)\n\tpacket, err := EncodeUDPPacket(&request, payload)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t_, err = w.writer.Write(packet.Bytes())\n\tpacket.Release()\n\treturn len(payload), err\n}\n\nfunc ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer, delayAuthWrite bool) (*protocol.RequestHeader, error) {\n\tauthByte := byte(authNotRequired)\n\tif request.User != nil {\n\t\tauthByte = byte(authPassword)\n\t}\n\n\tb := buf.New()\n\tdefer b.Release()\n\n\tcommon.Must2(b.Write([]byte{socks5Version, 0x01, authByte}))\n\tif !delayAuthWrite {\n\t\tif authByte == authPassword {\n\t\t\taccount := request.User.Account.(*Account)\n\t\t\tcommon.Must(b.WriteByte(0x01))\n\t\t\tcommon.Must(b.WriteByte(byte(len(account.Username))))\n\t\t\tcommon.Must2(b.WriteString(account.Username))\n\t\t\tcommon.Must(b.WriteByte(byte(len(account.Password))))\n\t\t\tcommon.Must2(b.WriteString(account.Password))\n\t\t}\n\t}\n\n\tif err := buf.WriteAllBytes(writer, b.Bytes()); err != nil {\n\t\treturn nil, err\n\t}\n\n\tb.Clear()\n\tif _, err := b.ReadFullFrom(reader, 2); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif b.Byte(0) != socks5Version {\n\t\treturn nil, newError(\"unexpected server version: \", b.Byte(0)).AtWarning()\n\t}\n\tif b.Byte(1) != authByte {\n\t\treturn nil, newError(\"auth method not supported.\").AtWarning()\n\t}\n\n\tif authByte == authPassword {\n\t\tb.Clear()\n\t\tif delayAuthWrite {\n\t\t\taccount := request.User.Account.(*Account)\n\t\t\tcommon.Must(b.WriteByte(0x01))\n\t\t\tcommon.Must(b.WriteByte(byte(len(account.Username))))\n\t\t\tcommon.Must2(b.WriteString(account.Username))\n\t\t\tcommon.Must(b.WriteByte(byte(len(account.Password))))\n\t\t\tcommon.Must2(b.WriteString(account.Password))\n\t\t\tif err := buf.WriteAllBytes(writer, b.Bytes()); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb.Clear()\n\t\t}\n\t\tif _, err := b.ReadFullFrom(reader, 2); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif b.Byte(1) != 0x00 {\n\t\t\treturn nil, newError(\"server rejects account: \", b.Byte(1))\n\t\t}\n\t}\n\n\tb.Clear()\n\n\tcommand := byte(cmdTCPConnect)\n\tif request.Command == protocol.RequestCommandUDP {\n\t\tcommand = byte(cmdUDPAssociate)\n\t}\n\tcommon.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */}))\n\tif err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := buf.WriteAllBytes(writer, b.Bytes()); err != nil {\n\t\treturn nil, err\n\t}\n\n\tb.Clear()\n\tif _, err := b.ReadFullFrom(reader, 3); err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp := b.Byte(1)\n\tif resp != 0x00 {\n\t\treturn nil, newError(\"server rejects request: \", resp)\n\t}\n\n\tb.Clear()\n\n\taddress, port, err := addrParser.ReadAddressPort(b, reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif request.Command == protocol.RequestCommandUDP {\n\t\tudpRequest := &protocol.RequestHeader{\n\t\t\tVersion: socks5Version,\n\t\t\tCommand: protocol.RequestCommandUDP,\n\t\t\tAddress: address,\n\t\t\tPort:    port,\n\t\t}\n\t\treturn udpRequest, nil\n\t}\n\n\treturn nil, nil\n}\n\nfunc ClientHandshake4(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) error {\n\tb := buf.New()\n\tdefer b.Release()\n\n\tcommon.Must2(b.Write([]byte{socks4Version, cmdTCPConnect}))\n\tportBytes := b.Extend(2)\n\tbinary.BigEndian.PutUint16(portBytes, request.Port.Value())\n\tswitch request.Address.Family() {\n\tcase net.AddressFamilyIPv4:\n\t\tcommon.Must2(b.Write(request.Address.IP()))\n\tcase net.AddressFamilyDomain:\n\t\tcommon.Must2(b.Write([]byte{0x00, 0x00, 0x00, 0x01}))\n\tcase net.AddressFamilyIPv6:\n\t\treturn newError(\"ipv6 is not supported in socks4\")\n\tdefault:\n\t\tpanic(\"Unknown family type.\")\n\t}\n\tif request.User != nil {\n\t\taccount := request.User.Account.(*Account)\n\t\tcommon.Must2(b.WriteString(account.Username))\n\t}\n\tcommon.Must(b.WriteByte(0x00))\n\tif request.Address.Family() == net.AddressFamilyDomain {\n\t\tcommon.Must2(b.WriteString(request.Address.Domain()))\n\t\tcommon.Must(b.WriteByte(0x00))\n\t}\n\tif err := buf.WriteAllBytes(writer, b.Bytes()); err != nil {\n\t\treturn err\n\t}\n\n\tb.Clear()\n\tif _, err := b.ReadFullFrom(reader, 8); err != nil {\n\t\treturn err\n\t}\n\tif b.Byte(0) != 0x00 {\n\t\treturn newError(\"unexpected version of the reply code: \", b.Byte(0))\n\t}\n\tif b.Byte(1) != socks4RequestGranted {\n\t\treturn newError(\"server rejects request: \", b.Byte(1))\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/socks/protocol_test.go",
    "content": "package socks_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n)\n\nfunc TestUDPEncoding(t *testing.T) {\n\tb := buf.New()\n\n\trequest := &protocol.RequestHeader{\n\t\tAddress: net.IPAddress([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}),\n\t\tPort:    1024,\n\t}\n\twriter := &buf.SequentialWriter{Writer: NewUDPWriter(request, b)}\n\n\tcontent := []byte{'a'}\n\tpayload := buf.New()\n\tpayload.Write(content)\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{payload}))\n\n\treader := NewUDPReader(b)\n\n\tdecodedPayload, err := reader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif r := cmp.Diff(decodedPayload[0].Bytes(), content); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestReadUsernamePassword(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput    []byte\n\t\tUsername string\n\t\tPassword string\n\t\tError    bool\n\t}{\n\t\t{\n\t\t\tInput:    []byte{0x05, 0x01, 'a', 0x02, 'b', 'c'},\n\t\t\tUsername: \"a\",\n\t\t\tPassword: \"bc\",\n\t\t},\n\t\t{\n\t\t\tInput: []byte{0x05, 0x18, 'a', 0x02, 'b', 'c'},\n\t\t\tError: true,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\treader := bytes.NewReader(testCase.Input)\n\t\tusername, password, err := ReadUsernamePassword(reader)\n\t\tif testCase.Error {\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect error, but actually nil\")\n\t\t\t}\n\t\t} else {\n\t\t\tif err != nil {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect no error, but actually \", err.Error())\n\t\t\t}\n\t\t\tif testCase.Username != username {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect username \", testCase.Username, \" but actually \", username)\n\t\t\t}\n\t\t\tif testCase.Password != password {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect password \", testCase.Password, \" but actually \", password)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestReadUntilNull(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput  []byte\n\t\tOutput string\n\t\tError  bool\n\t}{\n\t\t{\n\t\t\tInput:  []byte{'a', 'b', 0x00},\n\t\t\tOutput: \"ab\",\n\t\t},\n\t\t{\n\t\t\tInput: []byte{'a'},\n\t\t\tError: true,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\treader := bytes.NewReader(testCase.Input)\n\t\tvalue, err := ReadUntilNull(reader)\n\t\tif testCase.Error {\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect error, but actually nil\")\n\t\t\t}\n\t\t} else {\n\t\t\tif err != nil {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect no error, but actually \", err.Error())\n\t\t\t}\n\t\t\tif testCase.Output != value {\n\t\t\t\tt.Error(\"for input: \", testCase.Input, \" expect output \", testCase.Output, \" but actually \", value)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc BenchmarkReadUsernamePassword(b *testing.B) {\n\tinput := []byte{0x05, 0x01, 'a', 0x02, 'b', 'c'}\n\tbuffer := buf.New()\n\tbuffer.Write(input)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, err := ReadUsernamePassword(buffer)\n\t\tcommon.Must(err)\n\t\tbuffer.Clear()\n\t\tbuffer.Extend(int32(len(input)))\n\t}\n}\n"
  },
  {
    "path": "proxy/socks/server.go",
    "content": "package socks\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tudp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// Server is a SOCKS 5 proxy server\ntype Server struct {\n\tconfig        *ServerConfig\n\tpolicyManager policy.Manager\n}\n\n// NewServer creates a new Server object.\nfunc NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {\n\tv := core.MustFromContext(ctx)\n\ts := &Server{\n\t\tconfig:        config,\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\treturn s, nil\n}\n\nfunc (s *Server) policy() policy.Session {\n\tconfig := s.config\n\tp := s.policyManager.ForLevel(config.UserLevel)\n\tif config.Timeout > 0 {\n\t\tfeatures.PrintDeprecatedFeatureWarning(\"Socks timeout\")\n\t}\n\tif config.Timeout > 0 && config.UserLevel == 0 {\n\t\tp.Timeouts.ConnectionIdle = time.Duration(config.Timeout) * time.Second\n\t}\n\treturn p\n}\n\n// Network implements proxy.Inbound.\nfunc (s *Server) Network() []net.Network {\n\tlist := []net.Network{net.Network_TCP}\n\tif s.config.UdpEnabled {\n\t\tlist = append(list, net.Network_UDP)\n\t}\n\treturn list\n}\n\n// Process implements proxy.Inbound.\nfunc (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tif inbound := session.InboundFromContext(ctx); inbound != nil {\n\t\tinbound.User = &protocol.MemoryUser{\n\t\t\tLevel: s.config.UserLevel,\n\t\t}\n\t}\n\n\tswitch network {\n\tcase net.Network_TCP:\n\t\treturn s.processTCP(ctx, conn, dispatcher)\n\tcase net.Network_UDP:\n\t\treturn s.handleUDPPayload(ctx, conn, dispatcher)\n\tdefault:\n\t\treturn newError(\"unknown network: \", network)\n\t}\n}\n\nfunc (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tplcy := s.policy()\n\tif err := conn.SetReadDeadline(time.Now().Add(plcy.Timeouts.Handshake)); err != nil {\n\t\tnewError(\"failed to set deadline\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil || !inbound.Gateway.IsValid() {\n\t\treturn newError(\"inbound gateway not specified\")\n\t}\n\n\tsvrSession := &ServerSession{\n\t\tconfig:        s.config,\n\t\taddress:       inbound.Gateway.Address,\n\t\tport:          inbound.Gateway.Port,\n\t\tclientAddress: inbound.Source.Address,\n\t}\n\n\treader := &buf.BufferedReader{Reader: buf.NewReader(conn)}\n\trequest, err := svrSession.Handshake(reader, conn)\n\tif err != nil {\n\t\tif inbound != nil && inbound.Source.IsValid() {\n\t\t\tlog.Record(&log.AccessMessage{\n\t\t\t\tFrom:   inbound.Source,\n\t\t\t\tTo:     \"\",\n\t\t\t\tStatus: log.AccessRejected,\n\t\t\t\tReason: err,\n\t\t\t})\n\t\t}\n\t\treturn newError(\"failed to read request\").Base(err)\n\t}\n\tif request.User != nil {\n\t\tinbound.User.Email = request.User.Email\n\t}\n\n\tif err := conn.SetReadDeadline(time.Time{}); err != nil {\n\t\tnewError(\"failed to clear deadline\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tif request.Command == protocol.RequestCommandTCP {\n\t\tdest := request.Destination()\n\t\tnewError(\"TCP Connect request to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\t\tif inbound != nil && inbound.Source.IsValid() {\n\t\t\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\t\t\tFrom:   inbound.Source,\n\t\t\t\tTo:     dest,\n\t\t\t\tStatus: log.AccessAccepted,\n\t\t\t\tReason: \"\",\n\t\t\t})\n\t\t}\n\n\t\tdispatcher = &handshakeFinalizingDispatcher{Feature: dispatcher, delegate: dispatcher, serverSession: svrSession}\n\t\treturn s.transport(ctx, reader, conn, dest, dispatcher)\n\t}\n\n\terr = svrSession.flushLastReply(true)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif request.Command == protocol.RequestCommandUDP {\n\t\treturn s.handleUDP(conn)\n\t}\n\n\treturn nil\n}\n\n// Wrapper to send final SOCKS reply only after Dispatch() returns\ntype handshakeFinalizingDispatcher struct {\n\tfeatures.Feature // do not inherit Dispatch() in case its signature changes\n\tdelegate         routing.Dispatcher\n\tserverSession    *ServerSession\n}\n\nfunc (d *handshakeFinalizingDispatcher) Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error) {\n\tlink, err := d.delegate.Dispatch(ctx, dest)\n\tif err == nil {\n\t\tcloseInDefer := true\n\t\tdefer func() {\n\t\t\tif closeInDefer {\n\t\t\t\tcommon.Interrupt(link.Reader)\n\t\t\t\tcommon.Interrupt(link.Writer)\n\t\t\t}\n\t\t}()\n\t\terr = d.serverSession.flushLastReply(true)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcloseInDefer = false\n\t} else {\n\t\td.serverSession.flushLastReply(false)\n\t}\n\treturn link, err\n}\n\nfunc (*Server) handleUDP(c io.Reader) error {\n\t// The TCP connection closes after this method returns. We need to wait until\n\t// the client closes it.\n\treturn common.Error2(io.Copy(buf.DiscardBytes, c))\n}\n\nfunc (s *Server) transport(ctx context.Context, reader io.Reader, writer io.Writer, dest net.Destination, dispatcher routing.Dispatcher) error {\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, s.policy().Timeouts.ConnectionIdle)\n\n\tplcy := s.policy()\n\tctx = policy.ContextWithBufferPolicy(ctx, plcy.Buffer)\n\tlink, err := dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.DownlinkOnly)\n\t\tif err := buf.Copy(buf.NewReader(reader), link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport all TCP request\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(plcy.Timeouts.UplinkOnly)\n\n\t\tv2writer := buf.NewWriter(writer)\n\t\tif err := buf.Copy(link.Reader, v2writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transport all TCP response\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\trequestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestDonePost, responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tudpDispatcherConstructor := udp.NewSplitDispatcher\n\tswitch s.config.PacketEncoding {\n\tcase packetaddr.PacketAddrType_None:\n\t\tbreak\n\tcase packetaddr.PacketAddrType_Packet:\n\t\tpacketAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)\n\t\tudpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher\n\t}\n\tudpServer := udpDispatcherConstructor(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {\n\t\tpayload := packet.Payload\n\t\tnewError(\"writing back UDP response with \", payload.Len(), \" bytes\").AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\n\t\trequest := protocol.RequestHeaderFromContext(ctx)\n\t\tvar packetSource net.Destination\n\t\tif request == nil {\n\t\t\tpacketSource = packet.Source\n\t\t} else {\n\t\t\tpacketSource = net.UDPDestination(request.Address, request.Port)\n\t\t}\n\t\tudpMessage, err := EncodeUDPPacketFromAddress(packetSource, payload.Bytes())\n\t\tpayload.Release()\n\n\t\tdefer udpMessage.Release()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to write UDP response\").AtWarning().Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\n\t\tconn.Write(udpMessage.Bytes())\n\t})\n\n\tif inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {\n\t\tnewError(\"client UDP connection from \", inbound.Source).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\treader := buf.NewPacketReader(conn)\n\tfor {\n\t\tmpayload, err := reader.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfor _, payload := range mpayload {\n\t\t\trequest, err := DecodeUDPPacket(payload)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to parse UDP request\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\tpayload.Release()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif payload.IsEmpty() {\n\t\t\t\tpayload.Release()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcurrentPacketCtx := ctx\n\t\t\tnewError(\"send packet to \", request.Destination(), \" with \", payload.Len(), \" bytes\").AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\t\t\tif inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {\n\t\t\t\tcurrentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\t\t\t\tFrom:   inbound.Source,\n\t\t\t\t\tTo:     request.Destination(),\n\t\t\t\t\tStatus: log.AccessAccepted,\n\t\t\t\t\tReason: \"\",\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tcurrentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)\n\t\t\tudpServer.Dispatch(currentPacketCtx, request.Destination(), payload)\n\t\t}\n\t}\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServer(ctx, config.(*ServerConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/socks/simplified/config.go",
    "content": "package simplified\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*ServerConfig)\n\t\tfullServer := &socks.ServerConfig{\n\t\t\tAuthType:       socks.AuthType_NO_AUTH,\n\t\t\tAddress:        simplifiedServer.Address,\n\t\t\tUdpEnabled:     simplifiedServer.UdpEnabled,\n\t\t\tPacketEncoding: simplifiedServer.PacketEncoding,\n\t\t\tDeferLastReply: simplifiedServer.DeferLastReply,\n\t\t}\n\t\treturn common.CreateObject(ctx, fullServer)\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedClient := config.(*ClientConfig)\n\t\tfullClient := &socks.ClientConfig{\n\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t{\n\t\t\t\t\tAddress: simplifiedClient.Address,\n\t\t\t\t\tPort:    simplifiedClient.Port,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\treturn common.CreateObject(ctx, fullClient)\n\t}))\n}\n"
  },
  {
    "path": "proxy/socks/simplified/config.pb.go",
    "content": "package simplified\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ServerConfig struct {\n\tstate          protoimpl.MessageState    `protogen:\"open.v1\"`\n\tAddress        *net.IPOrDomain           `protobuf:\"bytes,3,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tUdpEnabled     bool                      `protobuf:\"varint,4,opt,name=udp_enabled,json=udpEnabled,proto3\" json:\"udp_enabled,omitempty\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,7,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tDeferLastReply bool                      `protobuf:\"varint,8,opt,name=defer_last_reply,json=deferLastReply,proto3\" json:\"defer_last_reply,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_socks_simplified_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_socks_simplified_config_proto_msgTypes[0]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_socks_simplified_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ServerConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetUdpEnabled() bool {\n\tif x != nil {\n\t\treturn x.UdpEnabled\n\t}\n\treturn false\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\nfunc (x *ServerConfig) GetDeferLastReply() bool {\n\tif x != nil {\n\t\treturn x.DeferLastReply\n\t}\n\treturn false\n}\n\ntype ClientConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress       *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_socks_simplified_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_socks_simplified_config_proto_msgTypes[1]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_socks_simplified_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ClientConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nvar File_proxy_socks_simplified_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_socks_simplified_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"#proxy/socks/simplified/config.proto\\x12!v2ray.core.proxy.socks.simplified\\x1a common/protoext/extensions.proto\\x1a\\x18common/net/address.proto\\x1a\\\"common/net/packetaddr/config.proto\\\"\\x80\\x02\\n\" +\n\t\"\\fServerConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x03 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x1f\\n\" +\n\t\"\\vudp_enabled\\x18\\x04 \\x01(\\bR\\n\" +\n\t\"udpEnabled\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\a \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding\\x12(\\n\" +\n\t\"\\x10defer_last_reply\\x18\\b \\x01(\\bR\\x0edeferLastReply:\\x14\\x82\\xb5\\x18\\x10\\n\" +\n\t\"\\ainbound\\x12\\x05socks\\\"v\\n\" +\n\t\"\\fClientConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\boutbound\\x12\\x05socksB\\x84\\x01\\n\" +\n\t\"%com.v2ray.core.proxy.socks.simplifiedP\\x01Z5github.com/v2fly/v2ray-core/v5/proxy/socks/simplified\\xaa\\x02!V2Ray.Core.Proxy.Socks.Simplifiedb\\x06proto3\"\n\nvar (\n\tfile_proxy_socks_simplified_config_proto_rawDescOnce sync.Once\n\tfile_proxy_socks_simplified_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_socks_simplified_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_socks_simplified_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_socks_simplified_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_socks_simplified_config_proto_rawDesc), len(file_proxy_socks_simplified_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_socks_simplified_config_proto_rawDescData\n}\n\nvar file_proxy_socks_simplified_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_socks_simplified_config_proto_goTypes = []any{\n\t(*ServerConfig)(nil),           // 0: v2ray.core.proxy.socks.simplified.ServerConfig\n\t(*ClientConfig)(nil),           // 1: v2ray.core.proxy.socks.simplified.ClientConfig\n\t(*net.IPOrDomain)(nil),         // 2: v2ray.core.common.net.IPOrDomain\n\t(packetaddr.PacketAddrType)(0), // 3: v2ray.core.net.packetaddr.PacketAddrType\n}\nvar file_proxy_socks_simplified_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.socks.simplified.ServerConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t3, // 1: v2ray.core.proxy.socks.simplified.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t2, // 2: v2ray.core.proxy.socks.simplified.ClientConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\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_proxy_socks_simplified_config_proto_init() }\nfunc file_proxy_socks_simplified_config_proto_init() {\n\tif File_proxy_socks_simplified_config_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: unsafe.Slice(unsafe.StringData(file_proxy_socks_simplified_config_proto_rawDesc), len(file_proxy_socks_simplified_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_socks_simplified_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_socks_simplified_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_socks_simplified_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_socks_simplified_config_proto = out.File\n\tfile_proxy_socks_simplified_config_proto_goTypes = nil\n\tfile_proxy_socks_simplified_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/socks/simplified/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.socks.simplified;\noption csharp_namespace = \"V2Ray.Core.Proxy.Socks.Simplified\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/socks/simplified\";\noption java_package = \"com.v2ray.core.proxy.socks.simplified\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"common/net/address.proto\";\nimport \"common/net/packetaddr/config.proto\";\n\nmessage ServerConfig{\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"socks\";\n\n  v2ray.core.common.net.IPOrDomain address = 3;\n  bool udp_enabled = 4;\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 7;\n  bool defer_last_reply = 8;\n}\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"socks\";\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n}"
  },
  {
    "path": "proxy/socks/socks.go",
    "content": "// Package socks provides implements of Socks protocol 4, 4a and 5.\npackage socks\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/trojan/client.go",
    "content": "package trojan\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n// Client is an inbound handler for trojan protocol\ntype Client struct {\n\tserverPicker  protocol.ServerPicker\n\tpolicyManager policy.Manager\n}\n\n// NewClient create a new trojan client.\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Server {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse server spec\").Base(err)\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\tif serverList.Size() == 0 {\n\t\treturn nil, newError(\"0 server\")\n\t}\n\n\tv := core.MustFromContext(ctx)\n\tclient := &Client{\n\t\tserverPicker:  protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\treturn client, nil\n}\n\n// Process implements OutboundHandler.Process().\nfunc (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\")\n\t}\n\tdestination := outbound.Target\n\tnetwork := destination.Network\n\n\tvar server *protocol.ServerSpec\n\tvar conn internet.Connection\n\n\terr := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tserver = c.serverPicker.PickServer()\n\t\trawConn, err := dialer.Dial(ctx, server.Destination())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tconn = rawConn\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to find an available destination\").AtWarning().Base(err)\n\t}\n\tnewError(\"tunneling request to \", destination, \" via \", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx))\n\n\tdefer conn.Close()\n\n\tuser := server.PickUser()\n\taccount, ok := user.Account.(*MemoryAccount)\n\tif !ok {\n\t\treturn newError(\"user account is not valid\")\n\t}\n\n\tsessionPolicy := c.policyManager.ForLevel(user.Level)\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\tpostRequest := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\t\tvar buffer [2048]byte\n\t\t\tn, addr, err := packetConn.ReadFrom(buffer[:])\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to read a packet\").Base(err)\n\t\t\t}\n\t\t\tdest := net.DestinationFromAddr(addr)\n\n\t\t\tbufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\t\tconnWriter := &ConnWriter{Writer: bufferWriter, Target: dest, Account: account}\n\t\t\tpacketWriter := &PacketWriter{Writer: connWriter, Target: dest}\n\n\t\t\t// write some request payload to buffer\n\t\t\tif _, err := packetWriter.WriteTo(buffer[:n], addr); err != nil {\n\t\t\t\treturn newError(\"failed to write a request payload\").Base(err)\n\t\t\t}\n\n\t\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\t\tif err = bufferWriter.SetBuffered(false); err != nil {\n\t\t\t\treturn newError(\"failed to flush payload\").Base(err).AtWarning()\n\t\t\t}\n\n\t\t\treturn udp.CopyPacketConn(packetWriter, packetConn, udp.UpdateActivity(timer))\n\t\t}\n\n\t\tgetResponse := func() error {\n\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\t\tpacketReader := &PacketReader{Reader: conn}\n\t\t\tpacketConnectionReader := &PacketConnectionReader{reader: packetReader}\n\n\t\t\treturn udp.CopyPacketConn(packetConn, packetConnectionReader, udp.UpdateActivity(timer))\n\t\t}\n\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tpostRequest := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tvar bodyWriter buf.Writer\n\t\tbufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\tconnWriter := &ConnWriter{Writer: bufferWriter, Target: destination, Account: account}\n\n\t\tif destination.Network == net.Network_UDP {\n\t\t\tbodyWriter = &PacketWriter{Writer: connWriter, Target: destination}\n\t\t} else {\n\t\t\tbodyWriter = connWriter\n\t\t}\n\n\t\t// write some request payload to buffer\n\t\terr = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout)\n\t\tswitch err {\n\t\tcase buf.ErrNotTimeoutReader, buf.ErrReadTimeout:\n\t\t\tif err := connWriter.WriteHeader(); err != nil {\n\t\t\t\treturn newError(\"failed to write request header\").Base(err).AtWarning()\n\t\t\t}\n\t\tcase nil:\n\t\tdefault:\n\t\t\treturn newError(\"failed to write a request payload\").Base(err).AtWarning()\n\t\t}\n\n\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\tif err = bufferWriter.SetBuffered(false); err != nil {\n\t\t\treturn newError(\"failed to flush payload\").Base(err).AtWarning()\n\t\t}\n\n\t\tif err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tvar reader buf.Reader\n\t\tif network == net.Network_UDP {\n\t\t\treader = &PacketReader{\n\t\t\t\tReader: conn,\n\t\t\t}\n\t\t} else {\n\t\t\treader = buf.NewReader(conn)\n\t\t}\n\t\treturn buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))\n\t}\n\n\tresponseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))\n\tif err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewClient(ctx, config.(*ClientConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/trojan/config.go",
    "content": "package trojan\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n// MemoryAccount is an account type converted from Account.\ntype MemoryAccount struct {\n\tPassword string\n\tKey      []byte\n}\n\n// AsAccount implements protocol.AsAccount.\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\tpassword := a.GetPassword()\n\tkey := hexSha224(password)\n\treturn &MemoryAccount{\n\t\tPassword: password,\n\t\tKey:      key,\n\t}, nil\n}\n\n// Equals implements protocol.Account.Equals().\nfunc (a *MemoryAccount) Equals(another protocol.Account) bool {\n\tif account, ok := another.(*MemoryAccount); ok {\n\t\treturn a.Password == account.Password\n\t}\n\treturn false\n}\n\nfunc hexSha224(password string) []byte {\n\tbuf := make([]byte, 56)\n\thash := sha256.New224()\n\tcommon.Must2(hash.Write([]byte(password)))\n\thex.Encode(buf, hash.Sum(nil))\n\treturn buf\n}\n\nfunc hexString(data []byte) string {\n\tstr := \"\"\n\tfor _, v := range data {\n\t\tstr += fmt.Sprintf(\"%02x\", v)\n\t}\n\treturn str\n}\n"
  },
  {
    "path": "proxy/trojan/config.pb.go",
    "content": "package trojan\n\nimport (\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Account struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tPassword      string                 `protobuf:\"bytes,1,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_trojan_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_trojan_config_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_trojan_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Account) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\ntype Fallback struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAlpn          string                 `protobuf:\"bytes,1,opt,name=alpn,proto3\" json:\"alpn,omitempty\"`\n\tPath          string                 `protobuf:\"bytes,2,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tType          string                 `protobuf:\"bytes,3,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tDest          string                 `protobuf:\"bytes,4,opt,name=dest,proto3\" json:\"dest,omitempty\"`\n\tXver          uint64                 `protobuf:\"varint,5,opt,name=xver,proto3\" json:\"xver,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Fallback) Reset() {\n\t*x = Fallback{}\n\tmi := &file_proxy_trojan_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Fallback) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Fallback) ProtoMessage() {}\n\nfunc (x *Fallback) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_trojan_config_proto_msgTypes[1]\n\tif 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 Fallback.ProtoReflect.Descriptor instead.\nfunc (*Fallback) Descriptor() ([]byte, []int) {\n\treturn file_proxy_trojan_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Fallback) GetAlpn() string {\n\tif x != nil {\n\t\treturn x.Alpn\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetDest() string {\n\tif x != nil {\n\t\treturn x.Dest\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetXver() uint64 {\n\tif x != nil {\n\t\treturn x.Xver\n\t}\n\treturn 0\n}\n\ntype ClientConfig struct {\n\tstate         protoimpl.MessageState     `protogen:\"open.v1\"`\n\tServer        []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=server,proto3\" json:\"server,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_trojan_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_trojan_config_proto_msgTypes[2]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_trojan_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\ntype ServerConfig struct {\n\tstate          protoimpl.MessageState    `protogen:\"open.v1\"`\n\tUsers          []*protocol.User          `protobuf:\"bytes,1,rep,name=users,proto3\" json:\"users,omitempty\"`\n\tFallbacks      []*Fallback               `protobuf:\"bytes,3,rep,name=fallbacks,proto3\" json:\"fallbacks,omitempty\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,4,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_trojan_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_trojan_config_proto_msgTypes[3]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_trojan_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *ServerConfig) GetUsers() []*protocol.User {\n\tif x != nil {\n\t\treturn x.Users\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetFallbacks() []*Fallback {\n\tif x != nil {\n\t\treturn x.Fallbacks\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\nvar File_proxy_trojan_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_trojan_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x19proxy/trojan/config.proto\\x12\\x17v2ray.core.proxy.trojan\\x1a\\x1acommon/protocol/user.proto\\x1a!common/protocol/server_spec.proto\\x1a\\\"common/net/packetaddr/config.proto\\\"%\\n\" +\n\t\"\\aAccount\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x01 \\x01(\\tR\\bpassword\\\"n\\n\" +\n\t\"\\bFallback\\x12\\x12\\n\" +\n\t\"\\x04alpn\\x18\\x01 \\x01(\\tR\\x04alpn\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x02 \\x01(\\tR\\x04path\\x12\\x12\\n\" +\n\t\"\\x04type\\x18\\x03 \\x01(\\tR\\x04type\\x12\\x12\\n\" +\n\t\"\\x04dest\\x18\\x04 \\x01(\\tR\\x04dest\\x12\\x12\\n\" +\n\t\"\\x04xver\\x18\\x05 \\x01(\\x04R\\x04xver\\\"R\\n\" +\n\t\"\\fClientConfig\\x12B\\n\" +\n\t\"\\x06server\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x06server\\\"\\xdb\\x01\\n\" +\n\t\"\\fServerConfig\\x126\\n\" +\n\t\"\\x05users\\x18\\x01 \\x03(\\v2 .v2ray.core.common.protocol.UserR\\x05users\\x12?\\n\" +\n\t\"\\tfallbacks\\x18\\x03 \\x03(\\v2!.v2ray.core.proxy.trojan.FallbackR\\tfallbacks\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\x04 \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncodingBf\\n\" +\n\t\"\\x1bcom.v2ray.core.proxy.trojanP\\x01Z+github.com/v2fly/v2ray-core/v5/proxy/trojan\\xaa\\x02\\x17V2Ray.Core.Proxy.Trojanb\\x06proto3\"\n\nvar (\n\tfile_proxy_trojan_config_proto_rawDescOnce sync.Once\n\tfile_proxy_trojan_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_trojan_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_trojan_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_trojan_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_trojan_config_proto_rawDesc), len(file_proxy_trojan_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_trojan_config_proto_rawDescData\n}\n\nvar file_proxy_trojan_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_proxy_trojan_config_proto_goTypes = []any{\n\t(*Account)(nil),                 // 0: v2ray.core.proxy.trojan.Account\n\t(*Fallback)(nil),                // 1: v2ray.core.proxy.trojan.Fallback\n\t(*ClientConfig)(nil),            // 2: v2ray.core.proxy.trojan.ClientConfig\n\t(*ServerConfig)(nil),            // 3: v2ray.core.proxy.trojan.ServerConfig\n\t(*protocol.ServerEndpoint)(nil), // 4: v2ray.core.common.protocol.ServerEndpoint\n\t(*protocol.User)(nil),           // 5: v2ray.core.common.protocol.User\n\t(packetaddr.PacketAddrType)(0),  // 6: v2ray.core.net.packetaddr.PacketAddrType\n}\nvar file_proxy_trojan_config_proto_depIdxs = []int32{\n\t4, // 0: v2ray.core.proxy.trojan.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t5, // 1: v2ray.core.proxy.trojan.ServerConfig.users:type_name -> v2ray.core.common.protocol.User\n\t1, // 2: v2ray.core.proxy.trojan.ServerConfig.fallbacks:type_name -> v2ray.core.proxy.trojan.Fallback\n\t6, // 3: v2ray.core.proxy.trojan.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t4, // [4:4] is the sub-list for method output_type\n\t4, // [4:4] is the sub-list for method input_type\n\t4, // [4:4] is the sub-list for extension type_name\n\t4, // [4:4] is the sub-list for extension extendee\n\t0, // [0:4] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_trojan_config_proto_init() }\nfunc file_proxy_trojan_config_proto_init() {\n\tif File_proxy_trojan_config_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: unsafe.Slice(unsafe.StringData(file_proxy_trojan_config_proto_rawDesc), len(file_proxy_trojan_config_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_proxy_trojan_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_trojan_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_trojan_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_trojan_config_proto = out.File\n\tfile_proxy_trojan_config_proto_goTypes = nil\n\tfile_proxy_trojan_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/trojan/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.trojan;\noption csharp_namespace = \"V2Ray.Core.Proxy.Trojan\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/trojan\";\noption java_package = \"com.v2ray.core.proxy.trojan\";\noption java_multiple_files = true;\n\nimport \"common/protocol/user.proto\";\nimport \"common/protocol/server_spec.proto\";\nimport \"common/net/packetaddr/config.proto\";\n\nmessage Account {\n  string password = 1;\n}\n\nmessage Fallback {\n  string alpn = 1;\n  string path = 2;\n  string type = 3;\n  string dest = 4;\n  uint64 xver = 5;\n}\n\nmessage ClientConfig {\n  repeated v2ray.core.common.protocol.ServerEndpoint server = 1;\n}\n\nmessage ServerConfig {\n  repeated v2ray.core.common.protocol.User users = 1;\n  repeated Fallback fallbacks = 3;\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 4;\n}\n"
  },
  {
    "path": "proxy/trojan/errors.generated.go",
    "content": "package trojan\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/trojan/protocol.go",
    "content": "package trojan\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\tgonet \"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\nvar (\n\tcrlf = []byte{'\\r', '\\n'}\n\n\taddrParser = protocol.NewAddressParser(\n\t\tprotocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4),\n\t\tprotocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6),\n\t\tprotocol.AddressFamilyByte(0x03, net.AddressFamilyDomain),\n\t)\n)\n\nconst (\n\tcommandTCP byte = 1\n\tcommandUDP byte = 3\n)\n\n// ConnWriter is TCP Connection Writer Wrapper for trojan protocol\ntype ConnWriter struct {\n\tio.Writer\n\tTarget     net.Destination\n\tAccount    *MemoryAccount\n\theaderSent bool\n}\n\n// Write implements io.Writer\nfunc (c *ConnWriter) Write(p []byte) (n int, err error) {\n\tif !c.headerSent {\n\t\tif err := c.writeHeader(); err != nil {\n\t\t\treturn 0, newError(\"failed to write request header\").Base(err)\n\t\t}\n\t}\n\n\treturn c.Writer.Write(p)\n}\n\n// WriteMultiBuffer implements buf.Writer\nfunc (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tdefer buf.ReleaseMulti(mb)\n\n\tfor _, b := range mb {\n\t\tif !b.IsEmpty() {\n\t\t\tif _, err := c.Write(b.Bytes()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *ConnWriter) WriteHeader() error {\n\tif !c.headerSent {\n\t\tif err := c.writeHeader(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (c *ConnWriter) writeHeader() error {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tcommand := commandTCP\n\tif c.Target.Network == net.Network_UDP {\n\t\tcommand = commandUDP\n\t}\n\n\tif _, err := buffer.Write(c.Account.Key); err != nil {\n\t\treturn err\n\t}\n\tif _, err := buffer.Write(crlf); err != nil {\n\t\treturn err\n\t}\n\tif err := buffer.WriteByte(command); err != nil {\n\t\treturn err\n\t}\n\tif err := addrParser.WriteAddressPort(&buffer, c.Target.Address, c.Target.Port); err != nil {\n\t\treturn err\n\t}\n\tif _, err := buffer.Write(crlf); err != nil {\n\t\treturn err\n\t}\n\n\t_, err := c.Writer.Write(buffer.Bytes())\n\tif err == nil {\n\t\tc.headerSent = true\n\t}\n\n\treturn err\n}\n\n// PacketWriter UDP Connection Writer Wrapper for trojan protocol\ntype PacketWriter struct {\n\tio.Writer\n\tTarget net.Destination\n}\n\n// WriteMultiBuffer implements buf.Writer\nfunc (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tfor _, b := range mb {\n\t\tif b.IsEmpty() {\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := w.writePacket(b.Bytes(), w.Target); err != nil {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// WriteMultiBufferWithMetadata writes udp packet with destination specified\nfunc (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {\n\tfor _, b := range mb {\n\t\tif b.IsEmpty() {\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := w.writePacket(b.Bytes(), dest); err != nil {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (w *PacketWriter) WriteTo(payload []byte, addr gonet.Addr) (int, error) {\n\tdest := net.DestinationFromAddr(addr)\n\n\treturn w.writePacket(payload, dest)\n}\n\nfunc (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) { // nolint: unparam\n\tvar addrPortLen int32\n\tswitch dest.Address.Family() {\n\tcase net.AddressFamilyDomain:\n\t\tif protocol.IsDomainTooLong(dest.Address.Domain()) {\n\t\t\treturn 0, newError(\"Super long domain is not supported: \", dest.Address.Domain())\n\t\t}\n\t\taddrPortLen = 1 + 1 + int32(len(dest.Address.Domain())) + 2\n\tcase net.AddressFamilyIPv4:\n\t\taddrPortLen = 1 + 4 + 2\n\tcase net.AddressFamilyIPv6:\n\t\taddrPortLen = 1 + 16 + 2\n\tdefault:\n\t\tpanic(\"Unknown address type.\")\n\t}\n\n\tlength := len(payload)\n\tlengthBuf := [2]byte{}\n\tbinary.BigEndian.PutUint16(lengthBuf[:], uint16(length))\n\n\tbuffer := buf.NewWithSize(addrPortLen + 2 + 2 + int32(length))\n\tdefer buffer.Release()\n\n\tif err := addrParser.WriteAddressPort(buffer, dest.Address, dest.Port); err != nil {\n\t\treturn 0, err\n\t}\n\tif _, err := buffer.Write(lengthBuf[:]); err != nil {\n\t\treturn 0, err\n\t}\n\tif _, err := buffer.Write(crlf); err != nil {\n\t\treturn 0, err\n\t}\n\tif _, err := buffer.Write(payload); err != nil {\n\t\treturn 0, err\n\t}\n\t_, err := w.Write(buffer.Bytes())\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn length, nil\n}\n\n// ConnReader is TCP Connection Reader Wrapper for trojan protocol\ntype ConnReader struct {\n\tio.Reader\n\tTarget       net.Destination\n\theaderParsed bool\n}\n\n// ParseHeader parses the trojan protocol header\nfunc (c *ConnReader) ParseHeader() error {\n\tvar crlf [2]byte\n\tvar command [1]byte\n\tvar hash [56]byte\n\tif _, err := io.ReadFull(c.Reader, hash[:]); err != nil {\n\t\treturn newError(\"failed to read user hash\").Base(err)\n\t}\n\n\tif _, err := io.ReadFull(c.Reader, crlf[:]); err != nil {\n\t\treturn newError(\"failed to read crlf\").Base(err)\n\t}\n\n\tif _, err := io.ReadFull(c.Reader, command[:]); err != nil {\n\t\treturn newError(\"failed to read command\").Base(err)\n\t}\n\n\tnetwork := net.Network_TCP\n\tif command[0] == commandUDP {\n\t\tnetwork = net.Network_UDP\n\t}\n\n\taddr, port, err := addrParser.ReadAddressPort(nil, c.Reader)\n\tif err != nil {\n\t\treturn newError(\"failed to read address and port\").Base(err)\n\t}\n\tc.Target = net.Destination{Network: network, Address: addr, Port: port}\n\n\tif _, err := io.ReadFull(c.Reader, crlf[:]); err != nil {\n\t\treturn newError(\"failed to read crlf\").Base(err)\n\t}\n\n\tc.headerParsed = true\n\treturn nil\n}\n\n// Read implements io.Reader\nfunc (c *ConnReader) Read(p []byte) (int, error) {\n\tif !c.headerParsed {\n\t\tif err := c.ParseHeader(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\treturn c.Reader.Read(p)\n}\n\n// ReadMultiBuffer implements buf.Reader\nfunc (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tb := buf.New()\n\t_, err := b.ReadFrom(c)\n\treturn buf.MultiBuffer{b}, err\n}\n\n// PacketPayload combines udp payload and destination\ntype PacketPayload struct {\n\tTarget net.Destination\n\tBuffer buf.MultiBuffer\n}\n\n// PacketReader is UDP Connection Reader Wrapper for trojan protocol\ntype PacketReader struct {\n\tio.Reader\n}\n\n// ReadMultiBuffer implements buf.Reader\nfunc (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tp, err := r.ReadMultiBufferWithMetadata()\n\tif p != nil {\n\t\treturn p.Buffer, err\n\t}\n\treturn nil, err\n}\n\n// ReadMultiBufferWithMetadata reads udp packet with destination\nfunc (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {\n\taddr, port, err := addrParser.ReadAddressPort(nil, r)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read address and port\").Base(err)\n\t}\n\n\tvar lengthBuf [2]byte\n\tif _, err := io.ReadFull(r, lengthBuf[:]); err != nil {\n\t\treturn nil, newError(\"failed to read payload length\").Base(err)\n\t}\n\n\tlength := binary.BigEndian.Uint16(lengthBuf[:])\n\n\tvar crlf [2]byte\n\tif _, err := io.ReadFull(r, crlf[:]); err != nil {\n\t\treturn nil, newError(\"failed to read crlf\").Base(err)\n\t}\n\n\tdest := net.UDPDestination(addr, port)\n\n\tb := buf.NewWithSize(int32(length))\n\t_, err = b.ReadFullFrom(r, int32(length))\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read payload\").Base(err)\n\t}\n\n\treturn &PacketPayload{Target: dest, Buffer: buf.MultiBuffer{b}}, nil\n}\n\ntype PacketConnectionReader struct {\n\treader  *PacketReader\n\tpayload *PacketPayload\n}\n\nfunc (r *PacketConnectionReader) ReadFrom(p []byte) (n int, addr gonet.Addr, err error) {\n\tif r.payload == nil || r.payload.Buffer.IsEmpty() {\n\t\tr.payload, err = r.reader.ReadMultiBufferWithMetadata()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\taddr = &gonet.UDPAddr{\n\t\tIP:   r.payload.Target.Address.IP(),\n\t\tPort: int(r.payload.Target.Port),\n\t}\n\n\tr.payload.Buffer, n = buf.SplitFirstBytes(r.payload.Buffer, p)\n\n\treturn\n}\n"
  },
  {
    "path": "proxy/trojan/protocol_test.go",
    "content": "package trojan_test\n\nimport (\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/trojan\"\n)\n\nfunc toAccount(a *Account) protocol.Account {\n\taccount, err := a.AsAccount()\n\tcommon.Must(err)\n\treturn account\n}\n\nfunc TestTCPRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tEmail: \"love@v2fly.org\",\n\t\tAccount: toAccount(&Account{\n\t\t\tPassword: \"password\",\n\t\t}),\n\t}\n\tpayload := []byte(\"test string\")\n\tdata := buf.New()\n\tcommon.Must2(data.Write(payload))\n\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\n\tdestination := net.Destination{Network: net.Network_TCP, Address: net.LocalHostIP, Port: 1234}\n\twriter := &ConnWriter{Writer: buffer, Target: destination, Account: user.Account.(*MemoryAccount)}\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{data}))\n\n\treader := &ConnReader{Reader: buffer}\n\tcommon.Must(reader.ParseHeader())\n\n\tif r := cmp.Diff(reader.Target, destination); r != \"\" {\n\t\tt.Error(\"destination: \", r)\n\t}\n\n\tdecodedData, err := reader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif r := cmp.Diff(decodedData[0].Bytes(), payload); r != \"\" {\n\t\tt.Error(\"data: \", r)\n\t}\n}\n\nfunc TestUDPRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tEmail: \"love@v2fly.org\",\n\t\tAccount: toAccount(&Account{\n\t\t\tPassword: \"password\",\n\t\t}),\n\t}\n\tpayload := []byte(\"test string\")\n\tdata := buf.New()\n\tcommon.Must2(data.Write(payload))\n\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\n\tdestination := net.Destination{Network: net.Network_UDP, Address: net.LocalHostIP, Port: 1234}\n\twriter := &PacketWriter{Writer: &ConnWriter{Writer: buffer, Target: destination, Account: user.Account.(*MemoryAccount)}, Target: destination}\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{data}))\n\n\tconnReader := &ConnReader{Reader: buffer}\n\tcommon.Must(connReader.ParseHeader())\n\n\tpacketReader := &PacketReader{Reader: connReader}\n\tp, err := packetReader.ReadMultiBufferWithMetadata()\n\tcommon.Must(err)\n\n\tif p.Buffer.IsEmpty() {\n\t\tt.Error(\"no request data\")\n\t}\n\n\tif r := cmp.Diff(p.Target, destination); r != \"\" {\n\t\tt.Error(\"destination: \", r)\n\t}\n\n\tmb, decoded := buf.SplitFirst(p.Buffer)\n\tbuf.ReleaseMulti(mb)\n\n\tif r := cmp.Diff(decoded.Bytes(), payload); r != \"\" {\n\t\tt.Error(\"data: \", r)\n\t}\n}\n\nfunc TestLargeUDPRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tEmail: \"love@v2fly.org\",\n\t\tAccount: toAccount(&Account{\n\t\t\tPassword: \"password\",\n\t\t}),\n\t}\n\n\tpayload := make([]byte, 4096)\n\tcommon.Must2(rand.Read(payload))\n\tdata := buf.NewWithSize(int32(len(payload)))\n\tcommon.Must2(data.Write(payload))\n\n\tbuffer := buf.NewWithSize(2*data.Len() + 1)\n\tdefer buffer.Release()\n\n\tdestination := net.Destination{Network: net.Network_UDP, Address: net.LocalHostIP, Port: 1234}\n\twriter := &PacketWriter{Writer: &ConnWriter{Writer: buffer, Target: destination, Account: user.Account.(*MemoryAccount)}, Target: destination}\n\tcommon.Must(writer.WriteMultiBuffer(buf.MultiBuffer{data, data}))\n\n\tconnReader := &ConnReader{Reader: buffer}\n\tcommon.Must(connReader.ParseHeader())\n\n\tpacketReader := &PacketReader{Reader: connReader}\n\tfor i := 0; i < 2; i++ {\n\t\tp, err := packetReader.ReadMultiBufferWithMetadata()\n\t\tcommon.Must(err)\n\n\t\tif p.Buffer.IsEmpty() {\n\t\t\tt.Error(\"no request data\")\n\t\t}\n\n\t\tif r := cmp.Diff(p.Target, destination); r != \"\" {\n\t\t\tt.Error(\"destination: \", r)\n\t\t}\n\n\t\tmb, decoded := buf.SplitFirst(p.Buffer)\n\t\tbuf.ReleaseMulti(mb)\n\n\t\tif r := cmp.Diff(decoded.Bytes(), payload); r != \"\" {\n\t\t\tt.Error(\"data: \", r)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "proxy/trojan/server.go",
    "content": "package trojan\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"strconv\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tudp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServer(ctx, config.(*ServerConfig))\n\t}))\n}\n\n// Server is an inbound connection handler that handles messages in trojan protocol.\ntype Server struct {\n\tpolicyManager  policy.Manager\n\tvalidator      *Validator\n\tfallbacks      map[string]map[string]*Fallback // or nil\n\tpacketEncoding packetaddr.PacketAddrType\n}\n\n// NewServer creates a new trojan inbound handler.\nfunc NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {\n\tvalidator := new(Validator)\n\tfor _, user := range config.Users {\n\t\tu, err := user.ToMemoryUser()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get trojan user\").Base(err).AtError()\n\t\t}\n\n\t\tif err := validator.Add(u); err != nil {\n\t\t\treturn nil, newError(\"failed to add user\").Base(err).AtError()\n\t\t}\n\t}\n\n\tv := core.MustFromContext(ctx)\n\tserver := &Server{\n\t\tpolicyManager:  v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t\tvalidator:      validator,\n\t\tpacketEncoding: config.PacketEncoding,\n\t}\n\n\tif config.Fallbacks != nil {\n\t\tserver.fallbacks = make(map[string]map[string]*Fallback)\n\t\tfor _, fb := range config.Fallbacks {\n\t\t\tif server.fallbacks[fb.Alpn] == nil {\n\t\t\t\tserver.fallbacks[fb.Alpn] = make(map[string]*Fallback)\n\t\t\t}\n\t\t\tserver.fallbacks[fb.Alpn][fb.Path] = fb\n\t\t}\n\t\tif server.fallbacks[\"\"] != nil {\n\t\t\tfor alpn, pfb := range server.fallbacks {\n\t\t\t\tif alpn != \"\" { // && alpn != \"h2\" {\n\t\t\t\t\tfor path, fb := range server.fallbacks[\"\"] {\n\t\t\t\t\t\tif pfb[path] == nil {\n\t\t\t\t\t\t\tpfb[path] = fb\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 server, nil\n}\n\n// AddUser implements proxy.UserManager.AddUser().\nfunc (s *Server) AddUser(ctx context.Context, u *protocol.MemoryUser) error {\n\treturn s.validator.Add(u)\n}\n\n// RemoveUser implements proxy.UserManager.RemoveUser().\nfunc (s *Server) RemoveUser(ctx context.Context, e string) error {\n\treturn s.validator.Del(e)\n}\n\n// Network implements proxy.Inbound.Network().\nfunc (s *Server) Network() []net.Network {\n\treturn []net.Network{net.Network_TCP, net.Network_UNIX}\n}\n\n// Process implements proxy.Inbound.Process().\nfunc (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tsid := session.ExportIDToError(ctx)\n\n\tiConn := conn\n\tif statConn, ok := iConn.(*internet.StatCouterConnection); ok {\n\t\tiConn = statConn.Connection\n\t}\n\n\tsessionPolicy := s.policyManager.ForLevel(0)\n\tif err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {\n\t\treturn newError(\"unable to set read deadline\").Base(err).AtWarning()\n\t}\n\n\tfirst := buf.New()\n\tdefer first.Release()\n\n\tfirstLen, err := first.ReadFrom(conn)\n\tif err != nil {\n\t\treturn newError(\"failed to read first request\").Base(err)\n\t}\n\tnewError(\"firstLen = \", firstLen).AtInfo().WriteToLog(sid)\n\n\tbufferedReader := &buf.BufferedReader{\n\t\tReader: buf.NewReader(conn),\n\t\tBuffer: buf.MultiBuffer{first},\n\t}\n\n\tvar user *protocol.MemoryUser\n\n\tapfb := s.fallbacks\n\tisfb := apfb != nil\n\n\tshouldFallback := false\n\tif firstLen < 58 || first.Byte(56) != '\\r' {\n\t\t// invalid protocol\n\t\terr = newError(\"not trojan protocol\")\n\t\tlog.Record(&log.AccessMessage{\n\t\t\tFrom:   conn.RemoteAddr(),\n\t\t\tTo:     \"\",\n\t\t\tStatus: log.AccessRejected,\n\t\t\tReason: err,\n\t\t})\n\n\t\tshouldFallback = true\n\t} else {\n\t\tuser = s.validator.Get(hexString(first.BytesTo(56)))\n\t\tif user == nil {\n\t\t\t// invalid user, let's fallback\n\t\t\terr = newError(\"not a valid user\")\n\t\t\tlog.Record(&log.AccessMessage{\n\t\t\t\tFrom:   conn.RemoteAddr(),\n\t\t\t\tTo:     \"\",\n\t\t\t\tStatus: log.AccessRejected,\n\t\t\t\tReason: err,\n\t\t\t})\n\n\t\t\tshouldFallback = true\n\t\t}\n\t}\n\n\tif isfb && shouldFallback {\n\t\treturn s.fallback(ctx, sid, err, sessionPolicy, conn, iConn, apfb, first, firstLen, bufferedReader)\n\t} else if shouldFallback {\n\t\treturn newError(\"invalid protocol or invalid user\")\n\t}\n\n\tclientReader := &ConnReader{Reader: bufferedReader}\n\tif err := clientReader.ParseHeader(); err != nil {\n\t\tlog.Record(&log.AccessMessage{\n\t\t\tFrom:   conn.RemoteAddr(),\n\t\t\tTo:     \"\",\n\t\t\tStatus: log.AccessRejected,\n\t\t\tReason: err,\n\t\t})\n\t\treturn newError(\"failed to create request from: \", conn.RemoteAddr()).Base(err)\n\t}\n\n\tdestination := clientReader.Target\n\tif err := conn.SetReadDeadline(time.Time{}); err != nil {\n\t\treturn newError(\"unable to set read deadline\").Base(err).AtWarning()\n\t}\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil {\n\t\tpanic(\"no inbound metadata\")\n\t}\n\tinbound.User = user\n\tsessionPolicy = s.policyManager.ForLevel(user.Level)\n\n\tif destination.Network == net.Network_UDP { // handle udp request\n\t\treturn s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher)\n\t}\n\n\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\tFrom:   conn.RemoteAddr(),\n\t\tTo:     destination,\n\t\tStatus: log.AccessAccepted,\n\t\tReason: \"\",\n\t\tEmail:  user.Email,\n\t})\n\n\tnewError(\"received request for \", destination).WriteToLog(sid)\n\treturn s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher)\n}\n\nfunc (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error {\n\tudpDispatcherConstructor := udp.NewSplitDispatcher\n\tswitch s.packetEncoding {\n\tcase packetaddr.PacketAddrType_None:\n\tcase packetaddr.PacketAddrType_Packet:\n\t\tpacketAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)\n\t\tudpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher\n\t}\n\n\tudpServer := udpDispatcherConstructor(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {\n\t\tif err := clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source); err != nil {\n\t\t\tnewError(\"failed to write response\").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t})\n\n\tinbound := session.InboundFromContext(ctx)\n\tuser := inbound.User\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil\n\t\tdefault:\n\t\t\tp, err := clientReader.ReadMultiBufferWithMetadata()\n\t\t\tif err != nil {\n\t\t\t\tif errors.Cause(err) != io.EOF {\n\t\t\t\t\treturn newError(\"unexpected EOF\").Base(err)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tcurrentPacketCtx := ctx\n\t\t\tcurrentPacketCtx = log.ContextWithAccessMessage(currentPacketCtx, &log.AccessMessage{\n\t\t\t\tFrom:   inbound.Source,\n\t\t\t\tTo:     p.Target,\n\t\t\t\tStatus: log.AccessAccepted,\n\t\t\t\tReason: \"\",\n\t\t\t\tEmail:  user.Email,\n\t\t\t})\n\t\t\tnewError(\"tunnelling request to \", p.Target).WriteToLog(session.ExportIDToError(ctx))\n\n\t\t\tfor _, b := range p.Buffer {\n\t\t\t\tudpServer.Dispatch(currentPacketCtx, p.Target, b)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session,\n\tdestination net.Destination,\n\tclientReader buf.Reader,\n\tclientWriter buf.Writer, dispatcher routing.Dispatcher,\n) error {\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\n\tlink, err := dispatcher.Dispatch(ctx, destination)\n\tif err != nil {\n\t\treturn newError(\"failed to dispatch request to \", destination).Base(err)\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tif err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tif err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to write response\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\trequestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestDonePost, responseDone); err != nil {\n\t\tcommon.Must(common.Interrupt(link.Reader))\n\t\tcommon.Must(common.Interrupt(link.Writer))\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err error, sessionPolicy policy.Session, connection internet.Connection, iConn internet.Connection, apfb map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error {\n\tif err := connection.SetReadDeadline(time.Time{}); err != nil {\n\t\tnewError(\"unable to set back read deadline\").Base(err).AtWarning().WriteToLog(sid)\n\t}\n\tnewError(\"fallback starts\").Base(err).AtInfo().WriteToLog(sid)\n\n\talpn := \"\"\n\tif len(apfb) > 1 || apfb[\"\"] == nil {\n\t\tif tlsConn, ok := iConn.(*tls.Conn); ok {\n\t\t\talpn = tlsConn.ConnectionState().NegotiatedProtocol\n\t\t\tnewError(\"realAlpn = \" + alpn).AtInfo().WriteToLog(sid)\n\t\t}\n\t\tif apfb[alpn] == nil {\n\t\t\talpn = \"\"\n\t\t}\n\t}\n\tpfb := apfb[alpn]\n\tif pfb == nil {\n\t\treturn newError(`failed to find the default \"alpn\" config`).AtWarning()\n\t}\n\n\tpath := \"\"\n\tif len(pfb) > 1 || pfb[\"\"] == nil {\n\t\tif firstLen >= 18 && first.Byte(4) != '*' { // not h2c\n\t\t\tfirstBytes := first.Bytes()\n\t\t\tfor i := 4; i <= 8; i++ { // 5 -> 9\n\t\t\t\tif firstBytes[i] == '/' && firstBytes[i-1] == ' ' {\n\t\t\t\t\tsearch := len(firstBytes)\n\t\t\t\t\tif search > 64 {\n\t\t\t\t\t\tsearch = 64 // up to about 60\n\t\t\t\t\t}\n\t\t\t\t\tfor j := i + 1; j < search; j++ {\n\t\t\t\t\t\tk := firstBytes[j]\n\t\t\t\t\t\tif k == '\\r' || k == '\\n' { // avoid logging \\r or \\n\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif k == ' ' {\n\t\t\t\t\t\t\tpath = string(firstBytes[i:j])\n\t\t\t\t\t\t\tnewError(\"realPath = \" + path).AtInfo().WriteToLog(sid)\n\t\t\t\t\t\t\tif pfb[path] == nil {\n\t\t\t\t\t\t\t\tpath = \"\"\n\t\t\t\t\t\t\t}\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}\n\t\t}\n\t}\n\tfb := pfb[path]\n\tif fb == nil {\n\t\treturn newError(`failed to find the default \"path\" config`).AtWarning()\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\n\tvar conn net.Conn\n\tif err := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tvar dialer net.Dialer\n\t\tconn, err = dialer.DialContext(ctx, fb.Type, fb.Dest)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}); err != nil {\n\t\treturn newError(\"failed to dial to \" + fb.Dest).Base(err).AtWarning()\n\t}\n\tdefer conn.Close()\n\n\tserverReader := buf.NewReader(conn)\n\tserverWriter := buf.NewWriter(conn)\n\n\tpostRequest := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\t\tif fb.Xver != 0 {\n\t\t\tremoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tlocalAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tipv4 := true\n\t\t\tfor i := 0; i < len(remoteAddr); i++ {\n\t\t\t\tif remoteAddr[i] == ':' {\n\t\t\t\t\tipv4 = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tpro := buf.New()\n\t\t\tdefer pro.Release()\n\t\t\tswitch fb.Xver {\n\t\t\tcase 1:\n\t\t\t\tif ipv4 {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"PROXY TCP4 \" + remoteAddr + \" \" + localAddr + \" \" + remotePort + \" \" + localPort + \"\\r\\n\")))\n\t\t\t\t} else {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"PROXY TCP6 \" + remoteAddr + \" \" + localAddr + \" \" + remotePort + \" \" + localPort + \"\\r\\n\")))\n\t\t\t\t}\n\t\t\tcase 2:\n\t\t\t\tcommon.Must2(pro.Write([]byte(\"\\x0D\\x0A\\x0D\\x0A\\x00\\x0D\\x0A\\x51\\x55\\x49\\x54\\x0A\\x21\"))) // signature + v2 + PROXY\n\t\t\t\tif ipv4 {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"\\x11\\x00\\x0C\"))) // AF_INET + STREAM + 12 bytes\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(remoteAddr).To4()))\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(localAddr).To4()))\n\t\t\t\t} else {\n\t\t\t\t\tcommon.Must2(pro.Write([]byte(\"\\x21\\x00\\x24\"))) // AF_INET6 + STREAM + 36 bytes\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(remoteAddr).To16()))\n\t\t\t\t\tcommon.Must2(pro.Write(net.ParseIP(localAddr).To16()))\n\t\t\t\t}\n\t\t\t\tp1, _ := strconv.ParseUint(remotePort, 10, 16)\n\t\t\t\tp2, _ := strconv.ParseUint(localPort, 10, 16)\n\t\t\t\tcommon.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)}))\n\t\t\t}\n\t\t\tif err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {\n\t\t\t\treturn newError(\"failed to set PROXY protocol v\", fb.Xver).Base(err).AtWarning()\n\t\t\t}\n\t\t}\n\t\tif err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to fallback request payload\").Base(err).AtInfo()\n\t\t}\n\t\treturn nil\n\t}\n\n\twriter := buf.NewWriter(connection)\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\t\tif err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to deliver response payload\").Base(err).AtInfo()\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil {\n\t\tcommon.Must(common.Interrupt(serverReader))\n\t\tcommon.Must(common.Interrupt(serverWriter))\n\t\treturn newError(\"fallback ends\").Base(err).AtInfo()\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/trojan/simplified/config.go",
    "content": "package simplified\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/trojan\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*ServerConfig)\n\t\tfullServer := &trojan.ServerConfig{\n\t\t\tUsers: func() (users []*protocol.User) {\n\t\t\t\tfor _, v := range simplifiedServer.Users {\n\t\t\t\t\taccount := &trojan.Account{Password: v}\n\t\t\t\t\tusers = append(users, &protocol.User{\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}(),\n\t\t\tPacketEncoding: simplifiedServer.PacketEncoding,\n\t\t}\n\t\treturn common.CreateObject(ctx, fullServer)\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedClient := config.(*ClientConfig)\n\t\tfullClient := &trojan.ClientConfig{\n\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t{\n\t\t\t\t\tAddress: simplifiedClient.Address,\n\t\t\t\t\tPort:    simplifiedClient.Port,\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&trojan.Account{Password: simplifiedClient.Password}),\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\treturn common.CreateObject(ctx, fullClient)\n\t}))\n}\n"
  },
  {
    "path": "proxy/trojan/simplified/config.pb.go",
    "content": "package simplified\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tpacketaddr \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ServerConfig struct {\n\tstate          protoimpl.MessageState    `protogen:\"open.v1\"`\n\tUsers          []string                  `protobuf:\"bytes,1,rep,name=users,proto3\" json:\"users,omitempty\"`\n\tPacketEncoding packetaddr.PacketAddrType `protobuf:\"varint,2,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType\" json:\"packet_encoding,omitempty\"`\n\tunknownFields  protoimpl.UnknownFields\n\tsizeCache      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_proxy_trojan_simplified_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_trojan_simplified_config_proto_msgTypes[0]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_trojan_simplified_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ServerConfig) GetUsers() []string {\n\tif x != nil {\n\t\treturn x.Users\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {\n\tif x != nil {\n\t\treturn x.PacketEncoding\n\t}\n\treturn packetaddr.PacketAddrType(0)\n}\n\ntype ClientConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress       *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tPassword      string                 `protobuf:\"bytes,3,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_proxy_trojan_simplified_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_trojan_simplified_config_proto_msgTypes[1]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_trojan_simplified_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ClientConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nvar File_proxy_trojan_simplified_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_trojan_simplified_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$proxy/trojan/simplified/config.proto\\x12\\\"v2ray.core.proxy.trojan.simplified\\x1a common/protoext/extensions.proto\\x1a\\x18common/net/address.proto\\x1a\\\"common/net/packetaddr/config.proto\\\"\\x8f\\x01\\n\" +\n\t\"\\fServerConfig\\x12\\x14\\n\" +\n\t\"\\x05users\\x18\\x01 \\x03(\\tR\\x05users\\x12R\\n\" +\n\t\"\\x0fpacket_encoding\\x18\\x02 \\x01(\\x0e2).v2ray.core.net.packetaddr.PacketAddrTypeR\\x0epacketEncoding:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\ainbound\\x12\\x06trojan\\\"\\x93\\x01\\n\" +\n\t\"\\fClientConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x03 \\x01(\\tR\\bpassword:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\boutbound\\x12\\x06trojanB\\x87\\x01\\n\" +\n\t\"&com.v2ray.core.proxy.trojan.simplifiedP\\x01Z6github.com/v2fly/v2ray-core/v5/proxy/trojan/simplified\\xaa\\x02\\\"V2Ray.Core.Proxy.Trojan.Simplifiedb\\x06proto3\"\n\nvar (\n\tfile_proxy_trojan_simplified_config_proto_rawDescOnce sync.Once\n\tfile_proxy_trojan_simplified_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_trojan_simplified_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_trojan_simplified_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_trojan_simplified_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_trojan_simplified_config_proto_rawDesc), len(file_proxy_trojan_simplified_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_trojan_simplified_config_proto_rawDescData\n}\n\nvar file_proxy_trojan_simplified_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_trojan_simplified_config_proto_goTypes = []any{\n\t(*ServerConfig)(nil),           // 0: v2ray.core.proxy.trojan.simplified.ServerConfig\n\t(*ClientConfig)(nil),           // 1: v2ray.core.proxy.trojan.simplified.ClientConfig\n\t(packetaddr.PacketAddrType)(0), // 2: v2ray.core.net.packetaddr.PacketAddrType\n\t(*net.IPOrDomain)(nil),         // 3: v2ray.core.common.net.IPOrDomain\n}\nvar file_proxy_trojan_simplified_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.trojan.simplified.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType\n\t3, // 1: v2ray.core.proxy.trojan.simplified.ClientConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_trojan_simplified_config_proto_init() }\nfunc file_proxy_trojan_simplified_config_proto_init() {\n\tif File_proxy_trojan_simplified_config_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: unsafe.Slice(unsafe.StringData(file_proxy_trojan_simplified_config_proto_rawDesc), len(file_proxy_trojan_simplified_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_trojan_simplified_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_trojan_simplified_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_trojan_simplified_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_trojan_simplified_config_proto = out.File\n\tfile_proxy_trojan_simplified_config_proto_goTypes = nil\n\tfile_proxy_trojan_simplified_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/trojan/simplified/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.trojan.simplified;\noption csharp_namespace = \"V2Ray.Core.Proxy.Trojan.Simplified\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/trojan/simplified\";\noption java_package = \"com.v2ray.core.proxy.trojan.simplified\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"common/net/address.proto\";\nimport \"common/net/packetaddr/config.proto\";\n\nmessage ServerConfig{\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"trojan\";\n\n  repeated string users = 1;\n  v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 2;\n}\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"trojan\";\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  string password = 3;\n}"
  },
  {
    "path": "proxy/trojan/trojan.go",
    "content": "package trojan\n"
  },
  {
    "path": "proxy/trojan/validator.go",
    "content": "package trojan\n\nimport (\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n// Validator stores valid trojan users.\ntype Validator struct {\n\t// Considering email's usage here, map + sync.Mutex/RWMutex may have better performance.\n\temail sync.Map\n\tusers sync.Map\n}\n\n// Add a trojan user, Email must be empty or unique.\nfunc (v *Validator) Add(u *protocol.MemoryUser) error {\n\tif u.Email != \"\" {\n\t\t_, loaded := v.email.LoadOrStore(strings.ToLower(u.Email), u)\n\t\tif loaded {\n\t\t\treturn newError(\"User \", u.Email, \" already exists.\")\n\t\t}\n\t}\n\tv.users.Store(hexString(u.Account.(*MemoryAccount).Key), u)\n\treturn nil\n}\n\n// Del a trojan user with a non-empty Email.\nfunc (v *Validator) Del(e string) error {\n\tif e == \"\" {\n\t\treturn newError(\"Email must not be empty.\")\n\t}\n\tle := strings.ToLower(e)\n\tu, _ := v.email.Load(le)\n\tif u == nil {\n\t\treturn newError(\"User \", e, \" not found.\")\n\t}\n\tv.email.Delete(le)\n\tv.users.Delete(hexString(u.(*protocol.MemoryUser).Account.(*MemoryAccount).Key))\n\treturn nil\n}\n\n// Get a trojan user with hashed key, nil if user doesn't exist.\nfunc (v *Validator) Get(hash string) *protocol.MemoryUser {\n\tu, _ := v.users.Load(hash)\n\tif u != nil {\n\t\treturn u.(*protocol.MemoryUser)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/vless/account.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage vless\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\n// AsAccount implements protocol.Account.AsAccount().\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\tid, err := uuid.ParseString(a.Id)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse ID\").Base(err).AtError()\n\t}\n\treturn &MemoryAccount{\n\t\tID:         protocol.NewID(id),\n\t\tFlow:       a.Flow,       // needs parser here?\n\t\tEncryption: a.Encryption, // needs parser here?\n\t}, nil\n}\n\n// MemoryAccount is an in-memory form of VLess account.\ntype MemoryAccount struct {\n\t// ID of the account.\n\tID *protocol.ID\n\t// Flow of the account.\n\tFlow string\n\t// Encryption of the account. Used for client connections, and only accepts \"none\" for now.\n\tEncryption string\n}\n\n// Equals implements protocol.Account.Equals().\nfunc (a *MemoryAccount) Equals(account protocol.Account) bool {\n\tvlessAccount, ok := account.(*MemoryAccount)\n\tif !ok {\n\t\treturn false\n\t}\n\treturn a.ID.Equals(vlessAccount.ID)\n}\n"
  },
  {
    "path": "proxy/vless/account.pb.go",
    "content": "package vless\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Account struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// ID of the account, in the form of a UUID, e.g., \"66ad4540-b58c-4ad2-9926-ea63445a9b57\".\n\tId string `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\t// Flow settings.\n\tFlow string `protobuf:\"bytes,2,opt,name=flow,proto3\" json:\"flow,omitempty\"`\n\t// Encryption settings. Only applies to client side, and only accepts \"none\" for now.\n\tEncryption    string `protobuf:\"bytes,3,opt,name=encryption,proto3\" json:\"encryption,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_vless_account_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_account_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_account_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Account) GetId() string {\n\tif x != nil {\n\t\treturn x.Id\n\t}\n\treturn \"\"\n}\n\nfunc (x *Account) GetFlow() string {\n\tif x != nil {\n\t\treturn x.Flow\n\t}\n\treturn \"\"\n}\n\nfunc (x *Account) GetEncryption() string {\n\tif x != nil {\n\t\treturn x.Encryption\n\t}\n\treturn \"\"\n}\n\nvar File_proxy_vless_account_proto protoreflect.FileDescriptor\n\nconst file_proxy_vless_account_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x19proxy/vless/account.proto\\x12\\x16v2ray.core.proxy.vless\\\"M\\n\" +\n\t\"\\aAccount\\x12\\x0e\\n\" +\n\t\"\\x02id\\x18\\x01 \\x01(\\tR\\x02id\\x12\\x12\\n\" +\n\t\"\\x04flow\\x18\\x02 \\x01(\\tR\\x04flow\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"encryption\\x18\\x03 \\x01(\\tR\\n\" +\n\t\"encryptionBc\\n\" +\n\t\"\\x1acom.v2ray.core.proxy.vlessP\\x01Z*github.com/v2fly/v2ray-core/v5/proxy/vless\\xaa\\x02\\x16V2Ray.Core.Proxy.Vlessb\\x06proto3\"\n\nvar (\n\tfile_proxy_vless_account_proto_rawDescOnce sync.Once\n\tfile_proxy_vless_account_proto_rawDescData []byte\n)\n\nfunc file_proxy_vless_account_proto_rawDescGZIP() []byte {\n\tfile_proxy_vless_account_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vless_account_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vless_account_proto_rawDesc), len(file_proxy_vless_account_proto_rawDesc)))\n\t})\n\treturn file_proxy_vless_account_proto_rawDescData\n}\n\nvar file_proxy_vless_account_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_vless_account_proto_goTypes = []any{\n\t(*Account)(nil), // 0: v2ray.core.proxy.vless.Account\n}\nvar file_proxy_vless_account_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_proxy_vless_account_proto_init() }\nfunc file_proxy_vless_account_proto_init() {\n\tif File_proxy_vless_account_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: unsafe.Slice(unsafe.StringData(file_proxy_vless_account_proto_rawDesc), len(file_proxy_vless_account_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vless_account_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vless_account_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vless_account_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vless_account_proto = out.File\n\tfile_proxy_vless_account_proto_goTypes = nil\n\tfile_proxy_vless_account_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vless/account.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vless;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vless\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vless\";\noption java_package = \"com.v2ray.core.proxy.vless\";\noption java_multiple_files = true;\n\nmessage Account {\n  // ID of the account, in the form of a UUID, e.g., \"66ad4540-b58c-4ad2-9926-ea63445a9b57\".\n  string id = 1;\n  // Flow settings.\n  string flow = 2;\n  // Encryption settings. Only applies to client side, and only accepts \"none\" for now.\n  string encryption = 3;\n}\n"
  },
  {
    "path": "proxy/vless/encoding/addons.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage encoding\n\nimport (\n\t\"io\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n// EncodeHeaderAddons Add addons byte to the header\nfunc EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error {\n\tif err := buffer.WriteByte(0); err != nil {\n\t\treturn newError(\"failed to write addons protobuf length\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) {\n\taddons := new(Addons)\n\tbuffer.Clear()\n\tif _, err := buffer.ReadFullFrom(reader, 1); err != nil {\n\t\treturn nil, newError(\"failed to read addons protobuf length\").Base(err)\n\t}\n\n\tif length := int32(buffer.Byte(0)); length != 0 {\n\t\tbuffer.Clear()\n\t\tif _, err := buffer.ReadFullFrom(reader, length); err != nil {\n\t\t\treturn nil, newError(\"failed to read addons protobuf value\").Base(err)\n\t\t}\n\n\t\tif err := proto.Unmarshal(buffer.Bytes(), addons); err != nil {\n\t\t\treturn nil, newError(\"failed to unmarshal addons protobuf value\").Base(err)\n\t\t}\n\t}\n\n\treturn addons, nil\n}\n\n// EncodeBodyAddons returns a Writer that auto-encrypt content written by caller.\nfunc EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, addons *Addons) buf.Writer {\n\tif request.Command == protocol.RequestCommandUDP {\n\t\treturn NewMultiLengthPacketWriter(writer.(buf.Writer))\n\t}\n\treturn buf.NewWriter(writer)\n}\n\n// DecodeBodyAddons returns a Reader from which caller can fetch decrypted body.\nfunc DecodeBodyAddons(reader io.Reader, request *protocol.RequestHeader, addons *Addons) buf.Reader {\n\tif request.Command == protocol.RequestCommandUDP {\n\t\treturn NewLengthPacketReader(reader)\n\t}\n\treturn buf.NewReader(reader)\n}\n\nfunc NewMultiLengthPacketWriter(writer buf.Writer) *MultiLengthPacketWriter {\n\treturn &MultiLengthPacketWriter{\n\t\tWriter: writer,\n\t}\n}\n\ntype MultiLengthPacketWriter struct {\n\tbuf.Writer\n}\n\nfunc (w *MultiLengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tdefer buf.ReleaseMulti(mb)\n\n\tif len(mb)+1 > 64*1024*1024 {\n\t\treturn errors.New(\"value too large\")\n\t}\n\tsliceSize := len(mb) + 1\n\tmb2Write := make(buf.MultiBuffer, 0, sliceSize)\n\tfor _, b := range mb {\n\t\tlength := b.Len()\n\t\tif length == 0 || length+2 > buf.Size {\n\t\t\tcontinue\n\t\t}\n\t\teb := buf.New()\n\t\tif err := eb.WriteByte(byte(length >> 8)); err != nil {\n\t\t\teb.Release()\n\t\t\tcontinue\n\t\t}\n\t\tif err := eb.WriteByte(byte(length)); err != nil {\n\t\t\teb.Release()\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := eb.Write(b.Bytes()); err != nil {\n\t\t\teb.Release()\n\t\t\tcontinue\n\t\t}\n\t\tmb2Write = append(mb2Write, eb)\n\t}\n\tif mb2Write.IsEmpty() {\n\t\treturn nil\n\t}\n\treturn w.Writer.WriteMultiBuffer(mb2Write)\n}\n\ntype LengthPacketWriter struct {\n\tio.Writer\n\tcache []byte\n}\n\nfunc (w *LengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tlength := mb.Len() // none of mb is nil\n\tif length == 0 {\n\t\treturn nil\n\t}\n\tdefer func() {\n\t\tw.cache = w.cache[:0]\n\t}()\n\tw.cache = append(w.cache, byte(length>>8), byte(length))\n\tfor i, b := range mb {\n\t\tw.cache = append(w.cache, b.Bytes()...)\n\t\tb.Release()\n\t\tmb[i] = nil\n\t}\n\tif _, err := w.Write(w.cache); err != nil {\n\t\treturn newError(\"failed to write a packet\").Base(err)\n\t}\n\treturn nil\n}\n\nfunc NewLengthPacketReader(reader io.Reader) *LengthPacketReader {\n\treturn &LengthPacketReader{\n\t\tReader: reader,\n\t\tcache:  make([]byte, 2),\n\t}\n}\n\ntype LengthPacketReader struct {\n\tio.Reader\n\tcache []byte\n}\n\nfunc (r *LengthPacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tif _, err := io.ReadFull(r.Reader, r.cache); err != nil { // maybe EOF\n\t\treturn nil, newError(\"failed to read packet length\").Base(err)\n\t}\n\tlength := int32(r.cache[0])<<8 | int32(r.cache[1])\n\tmb := make(buf.MultiBuffer, 0, length/buf.Size+1)\n\tfor length > 0 {\n\t\tsize := length\n\t\tif size > buf.Size {\n\t\t\tsize = buf.Size\n\t\t}\n\t\tlength -= size\n\t\tb := buf.New()\n\t\tif _, err := b.ReadFullFrom(r.Reader, size); err != nil {\n\t\t\treturn nil, newError(\"failed to read packet payload\").Base(err)\n\t\t}\n\t\tmb = append(mb, b)\n\t}\n\treturn mb, nil\n}\n"
  },
  {
    "path": "proxy/vless/encoding/addons.pb.go",
    "content": "package encoding\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Addons struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tFlow          string                 `protobuf:\"bytes,1,opt,name=Flow,proto3\" json:\"Flow,omitempty\"`\n\tSeed          []byte                 `protobuf:\"bytes,2,opt,name=Seed,proto3\" json:\"Seed,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Addons) Reset() {\n\t*x = Addons{}\n\tmi := &file_proxy_vless_encoding_addons_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Addons) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Addons) ProtoMessage() {}\n\nfunc (x *Addons) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_encoding_addons_proto_msgTypes[0]\n\tif 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 Addons.ProtoReflect.Descriptor instead.\nfunc (*Addons) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_encoding_addons_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Addons) GetFlow() string {\n\tif x != nil {\n\t\treturn x.Flow\n\t}\n\treturn \"\"\n}\n\nfunc (x *Addons) GetSeed() []byte {\n\tif x != nil {\n\t\treturn x.Seed\n\t}\n\treturn nil\n}\n\nvar File_proxy_vless_encoding_addons_proto protoreflect.FileDescriptor\n\nconst file_proxy_vless_encoding_addons_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!proxy/vless/encoding/addons.proto\\x12\\x1fv2ray.core.proxy.vless.encoding\\\"0\\n\" +\n\t\"\\x06Addons\\x12\\x12\\n\" +\n\t\"\\x04Flow\\x18\\x01 \\x01(\\tR\\x04Flow\\x12\\x12\\n\" +\n\t\"\\x04Seed\\x18\\x02 \\x01(\\fR\\x04SeedB~\\n\" +\n\t\"#com.v2ray.core.proxy.vless.encodingP\\x01Z3github.com/v2fly/v2ray-core/v5/proxy/vless/encoding\\xaa\\x02\\x1fV2Ray.Core.Proxy.Vless.Encodingb\\x06proto3\"\n\nvar (\n\tfile_proxy_vless_encoding_addons_proto_rawDescOnce sync.Once\n\tfile_proxy_vless_encoding_addons_proto_rawDescData []byte\n)\n\nfunc file_proxy_vless_encoding_addons_proto_rawDescGZIP() []byte {\n\tfile_proxy_vless_encoding_addons_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vless_encoding_addons_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vless_encoding_addons_proto_rawDesc), len(file_proxy_vless_encoding_addons_proto_rawDesc)))\n\t})\n\treturn file_proxy_vless_encoding_addons_proto_rawDescData\n}\n\nvar file_proxy_vless_encoding_addons_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_vless_encoding_addons_proto_goTypes = []any{\n\t(*Addons)(nil), // 0: v2ray.core.proxy.vless.encoding.Addons\n}\nvar file_proxy_vless_encoding_addons_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_proxy_vless_encoding_addons_proto_init() }\nfunc file_proxy_vless_encoding_addons_proto_init() {\n\tif File_proxy_vless_encoding_addons_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: unsafe.Slice(unsafe.StringData(file_proxy_vless_encoding_addons_proto_rawDesc), len(file_proxy_vless_encoding_addons_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vless_encoding_addons_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vless_encoding_addons_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vless_encoding_addons_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vless_encoding_addons_proto = out.File\n\tfile_proxy_vless_encoding_addons_proto_goTypes = nil\n\tfile_proxy_vless_encoding_addons_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vless/encoding/addons.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vless.encoding;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vless.Encoding\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vless/encoding\";\noption java_package = \"com.v2ray.core.proxy.vless.encoding\";\noption java_multiple_files = true;\n\nmessage Addons {\n  string Flow = 1;\n  bytes Seed = 2;\n}\n"
  },
  {
    "path": "proxy/vless/encoding/encoding.go",
    "content": "package encoding\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless\"\n)\n\nconst (\n\tVersion = byte(0)\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain),\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6),\n\tprotocol.PortThenAddress(),\n)\n\n// EncodeRequestHeader writes encoded request header into the given writer.\nfunc EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requestAddons *Addons) error {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tif err := buffer.WriteByte(request.Version); err != nil {\n\t\treturn newError(\"failed to write request version\").Base(err)\n\t}\n\n\tif _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil {\n\t\treturn newError(\"failed to write request user id\").Base(err)\n\t}\n\n\tif err := EncodeHeaderAddons(&buffer, requestAddons); err != nil {\n\t\treturn newError(\"failed to encode request header addons\").Base(err)\n\t}\n\n\tif err := buffer.WriteByte(byte(request.Command)); err != nil {\n\t\treturn newError(\"failed to write request command\").Base(err)\n\t}\n\n\tif request.Command != protocol.RequestCommandMux {\n\t\tif err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil {\n\t\t\treturn newError(\"failed to write request address and port\").Base(err)\n\t\t}\n\t}\n\n\tif _, err := writer.Write(buffer.Bytes()); err != nil {\n\t\treturn newError(\"failed to write request header\").Base(err)\n\t}\n\n\treturn nil\n}\n\n// DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream.\nfunc DecodeRequestHeader(isfb bool, first *buf.Buffer, reader io.Reader, validator *vless.Validator) (*protocol.RequestHeader, *Addons, bool, error) {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\trequest := new(protocol.RequestHeader)\n\n\tif isfb {\n\t\trequest.Version = first.Byte(0)\n\t} else {\n\t\tif _, err := buffer.ReadFullFrom(reader, 1); err != nil {\n\t\t\treturn nil, nil, false, newError(\"failed to read request version\").Base(err)\n\t\t}\n\t\trequest.Version = buffer.Byte(0)\n\t}\n\n\tswitch request.Version {\n\tcase 0:\n\n\t\tvar id [16]byte\n\n\t\tif isfb {\n\t\t\tcopy(id[:], first.BytesRange(1, 17))\n\t\t} else {\n\t\t\tbuffer.Clear()\n\t\t\tif _, err := buffer.ReadFullFrom(reader, 16); err != nil {\n\t\t\t\treturn nil, nil, false, newError(\"failed to read request user id\").Base(err)\n\t\t\t}\n\t\t\tcopy(id[:], buffer.Bytes())\n\t\t}\n\n\t\tif request.User = validator.Get(id); request.User == nil {\n\t\t\treturn nil, nil, isfb, newError(\"invalid request user id\")\n\t\t}\n\n\t\tif isfb {\n\t\t\tfirst.Advance(17)\n\t\t}\n\n\t\trequestAddons, err := DecodeHeaderAddons(&buffer, reader)\n\t\tif err != nil {\n\t\t\treturn nil, nil, false, newError(\"failed to decode request header addons\").Base(err)\n\t\t}\n\n\t\tbuffer.Clear()\n\t\tif _, err := buffer.ReadFullFrom(reader, 1); err != nil {\n\t\t\treturn nil, nil, false, newError(\"failed to read request command\").Base(err)\n\t\t}\n\n\t\trequest.Command = protocol.RequestCommand(buffer.Byte(0))\n\t\tswitch request.Command {\n\t\tcase protocol.RequestCommandMux:\n\t\t\trequest.Address = net.DomainAddress(\"v1.mux.cool\")\n\t\t\trequest.Port = 0\n\t\tcase protocol.RequestCommandTCP, protocol.RequestCommandUDP:\n\t\t\tif addr, port, err := addrParser.ReadAddressPort(&buffer, reader); err == nil {\n\t\t\t\trequest.Address = addr\n\t\t\t\trequest.Port = port\n\t\t\t}\n\t\t}\n\t\tif request.Address == nil {\n\t\t\treturn nil, nil, false, newError(\"invalid request address\")\n\t\t}\n\t\treturn request, requestAddons, false, nil\n\tdefault:\n\t\treturn nil, nil, isfb, newError(\"invalid request version\")\n\t}\n}\n\n// EncodeResponseHeader writes encoded response header into the given writer.\nfunc EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, responseAddons *Addons) error {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tif err := buffer.WriteByte(request.Version); err != nil {\n\t\treturn newError(\"failed to write response version\").Base(err)\n\t}\n\n\tif err := EncodeHeaderAddons(&buffer, responseAddons); err != nil {\n\t\treturn newError(\"failed to encode response header addons\").Base(err)\n\t}\n\n\tif _, err := writer.Write(buffer.Bytes()); err != nil {\n\t\treturn newError(\"failed to write response header\").Base(err)\n\t}\n\n\treturn nil\n}\n\n// DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream.\nfunc DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) {\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tif _, err := buffer.ReadFullFrom(reader, 1); err != nil {\n\t\treturn nil, newError(\"failed to read response version\").Base(err)\n\t}\n\n\tif buffer.Byte(0) != request.Version {\n\t\treturn nil, newError(\"unexpected response version. Expecting \", int(request.Version), \" but actually \", int(buffer.Byte(0)))\n\t}\n\n\tresponseAddons, err := DecodeHeaderAddons(&buffer, reader)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to decode response header addons\").Base(err)\n\t}\n\n\treturn responseAddons, nil\n}\n"
  },
  {
    "path": "proxy/vless/encoding/encoding_test.go",
    "content": "package encoding_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"google.golang.org/protobuf/testing/protocmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/vless/encoding\"\n)\n\nfunc toAccount(a *vless.Account) protocol.Account {\n\taccount, err := a.AsAccount()\n\tcommon.Must(err)\n\treturn account\n}\n\nfunc TestRequestSerialization(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tLevel: 0,\n\t\tEmail: \"test@v2fly.org\",\n\t}\n\tid := uuid.New()\n\taccount := &vless.Account{\n\t\tId: id.String(),\n\t}\n\tuser.Account = toAccount(account)\n\n\texpectedRequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tUser:    user,\n\t\tCommand: protocol.RequestCommandTCP,\n\t\tAddress: net.DomainAddress(\"www.v2fly.org\"),\n\t\tPort:    net.Port(443),\n\t}\n\texpectedAddons := &Addons{}\n\n\tbuffer := buf.StackNew()\n\tcommon.Must(EncodeRequestHeader(&buffer, expectedRequest, expectedAddons))\n\n\tValidator := new(vless.Validator)\n\tValidator.Add(user)\n\n\tactualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator)\n\tcommon.Must(err)\n\n\tif r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tif r := cmp.Diff(actualAddons, expectedAddons, protocmp.Transform()); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestInvalidRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tLevel: 0,\n\t\tEmail: \"test@v2fly.org\",\n\t}\n\tid := uuid.New()\n\taccount := &vless.Account{\n\t\tId: id.String(),\n\t}\n\tuser.Account = toAccount(account)\n\n\texpectedRequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tUser:    user,\n\t\tCommand: protocol.RequestCommand(100),\n\t\tAddress: net.DomainAddress(\"www.v2fly.org\"),\n\t\tPort:    net.Port(443),\n\t}\n\texpectedAddons := &Addons{}\n\n\tbuffer := buf.StackNew()\n\tcommon.Must(EncodeRequestHeader(&buffer, expectedRequest, expectedAddons))\n\n\tValidator := new(vless.Validator)\n\tValidator.Add(user)\n\n\t_, _, _, err := DecodeRequestHeader(false, nil, &buffer, Validator)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestMuxRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tLevel: 0,\n\t\tEmail: \"test@v2fly.org\",\n\t}\n\tid := uuid.New()\n\taccount := &vless.Account{\n\t\tId: id.String(),\n\t}\n\tuser.Account = toAccount(account)\n\n\texpectedRequest := &protocol.RequestHeader{\n\t\tVersion: Version,\n\t\tUser:    user,\n\t\tCommand: protocol.RequestCommandMux,\n\t\tAddress: net.DomainAddress(\"v1.mux.cool\"),\n\t}\n\texpectedAddons := &Addons{}\n\n\tbuffer := buf.StackNew()\n\tcommon.Must(EncodeRequestHeader(&buffer, expectedRequest, expectedAddons))\n\n\tValidator := new(vless.Validator)\n\tValidator.Add(user)\n\n\tactualRequest, actualAddons, _, err := DecodeRequestHeader(false, nil, &buffer, Validator)\n\tcommon.Must(err)\n\n\tif r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tif r := cmp.Diff(actualAddons, expectedAddons, protocmp.Transform()); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "proxy/vless/encoding/errors.generated.go",
    "content": "package encoding\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vless/errors.generated.go",
    "content": "package vless\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vless/inbound/config.go",
    "content": "package inbound\n"
  },
  {
    "path": "proxy/vless/inbound/config.pb.go",
    "content": "package inbound\n\nimport (\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Fallback struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAlpn          string                 `protobuf:\"bytes,1,opt,name=alpn,proto3\" json:\"alpn,omitempty\"`\n\tPath          string                 `protobuf:\"bytes,2,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tType          string                 `protobuf:\"bytes,3,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tDest          string                 `protobuf:\"bytes,4,opt,name=dest,proto3\" json:\"dest,omitempty\"`\n\tXver          uint64                 `protobuf:\"varint,5,opt,name=xver,proto3\" json:\"xver,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Fallback) Reset() {\n\t*x = Fallback{}\n\tmi := &file_proxy_vless_inbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Fallback) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Fallback) ProtoMessage() {}\n\nfunc (x *Fallback) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_inbound_config_proto_msgTypes[0]\n\tif 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 Fallback.ProtoReflect.Descriptor instead.\nfunc (*Fallback) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Fallback) GetAlpn() string {\n\tif x != nil {\n\t\treturn x.Alpn\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetDest() string {\n\tif x != nil {\n\t\treturn x.Dest\n\t}\n\treturn \"\"\n}\n\nfunc (x *Fallback) GetXver() uint64 {\n\tif x != nil {\n\t\treturn x.Xver\n\t}\n\treturn 0\n}\n\ntype Config struct {\n\tstate   protoimpl.MessageState `protogen:\"open.v1\"`\n\tClients []*protocol.User       `protobuf:\"bytes,1,rep,name=clients,proto3\" json:\"clients,omitempty\"`\n\t// Decryption settings. Only applies to server side, and only accepts \"none\"\n\t// for now.\n\tDecryption    string      `protobuf:\"bytes,2,opt,name=decryption,proto3\" json:\"decryption,omitempty\"`\n\tFallbacks     []*Fallback `protobuf:\"bytes,3,rep,name=fallbacks,proto3\" json:\"fallbacks,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_vless_inbound_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_inbound_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetClients() []*protocol.User {\n\tif x != nil {\n\t\treturn x.Clients\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetDecryption() string {\n\tif x != nil {\n\t\treturn x.Decryption\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetFallbacks() []*Fallback {\n\tif x != nil {\n\t\treturn x.Fallbacks\n\t}\n\treturn nil\n}\n\ntype SimplifiedConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUsers         []string               `protobuf:\"bytes,1,rep,name=users,proto3\" json:\"users,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_vless_inbound_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_inbound_config_proto_msgTypes[2]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *SimplifiedConfig) GetUsers() []string {\n\tif x != nil {\n\t\treturn x.Users\n\t}\n\treturn nil\n}\n\nvar File_proxy_vless_inbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_vless_inbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\" proxy/vless/inbound/config.proto\\x12\\x1ev2ray.core.proxy.vless.inbound\\x1a\\x1acommon/protocol/user.proto\\x1a common/protoext/extensions.proto\\\"n\\n\" +\n\t\"\\bFallback\\x12\\x12\\n\" +\n\t\"\\x04alpn\\x18\\x01 \\x01(\\tR\\x04alpn\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x02 \\x01(\\tR\\x04path\\x12\\x12\\n\" +\n\t\"\\x04type\\x18\\x03 \\x01(\\tR\\x04type\\x12\\x12\\n\" +\n\t\"\\x04dest\\x18\\x04 \\x01(\\tR\\x04dest\\x12\\x12\\n\" +\n\t\"\\x04xver\\x18\\x05 \\x01(\\x04R\\x04xver\\\"\\xac\\x01\\n\" +\n\t\"\\x06Config\\x12:\\n\" +\n\t\"\\aclients\\x18\\x01 \\x03(\\v2 .v2ray.core.common.protocol.UserR\\aclients\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"decryption\\x18\\x02 \\x01(\\tR\\n\" +\n\t\"decryption\\x12F\\n\" +\n\t\"\\tfallbacks\\x18\\x03 \\x03(\\v2(.v2ray.core.proxy.vless.inbound.FallbackR\\tfallbacks\\\">\\n\" +\n\t\"\\x10SimplifiedConfig\\x12\\x14\\n\" +\n\t\"\\x05users\\x18\\x01 \\x03(\\tR\\x05users:\\x14\\x82\\xb5\\x18\\x10\\n\" +\n\t\"\\ainbound\\x12\\x05vlessB{\\n\" +\n\t\"\\\"com.v2ray.core.proxy.vless.inboundP\\x01Z2github.com/v2fly/v2ray-core/v5/proxy/vless/inbound\\xaa\\x02\\x1eV2Ray.Core.Proxy.Vless.Inboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_vless_inbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_vless_inbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_vless_inbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_vless_inbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vless_inbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vless_inbound_config_proto_rawDesc), len(file_proxy_vless_inbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_vless_inbound_config_proto_rawDescData\n}\n\nvar file_proxy_vless_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_proxy_vless_inbound_config_proto_goTypes = []any{\n\t(*Fallback)(nil),         // 0: v2ray.core.proxy.vless.inbound.Fallback\n\t(*Config)(nil),           // 1: v2ray.core.proxy.vless.inbound.Config\n\t(*SimplifiedConfig)(nil), // 2: v2ray.core.proxy.vless.inbound.SimplifiedConfig\n\t(*protocol.User)(nil),    // 3: v2ray.core.common.protocol.User\n}\nvar file_proxy_vless_inbound_config_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.proxy.vless.inbound.Config.clients:type_name -> v2ray.core.common.protocol.User\n\t0, // 1: v2ray.core.proxy.vless.inbound.Config.fallbacks:type_name -> v2ray.core.proxy.vless.inbound.Fallback\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_vless_inbound_config_proto_init() }\nfunc file_proxy_vless_inbound_config_proto_init() {\n\tif File_proxy_vless_inbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_vless_inbound_config_proto_rawDesc), len(file_proxy_vless_inbound_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vless_inbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vless_inbound_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vless_inbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vless_inbound_config_proto = out.File\n\tfile_proxy_vless_inbound_config_proto_goTypes = nil\n\tfile_proxy_vless_inbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vless/inbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vless.inbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vless.Inbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vless/inbound\";\noption java_package = \"com.v2ray.core.proxy.vless.inbound\";\noption java_multiple_files = true;\n\nimport \"common/protocol/user.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Fallback {\n  string alpn = 1;\n  string path = 2;\n  string type = 3;\n  string dest = 4;\n  uint64 xver = 5;\n}\n\nmessage Config {\n  repeated v2ray.core.common.protocol.User clients = 1;\n  // Decryption settings. Only applies to server side, and only accepts \"none\"\n  // for now.\n  string decryption = 2;\n  repeated Fallback fallbacks = 3;\n}\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"vless\";\n\n  repeated string users = 1;\n}\n"
  },
  {
    "path": "proxy/vless/inbound/errors.generated.go",
    "content": "package inbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vless/inbound/inbound.go",
    "content": "package inbound\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"strconv\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\tfeature_inbound \"github.com/v2fly/v2ray-core/v5/features/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless/encoding\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tvar dc dns.Client\n\t\tif err := core.RequireFeatures(ctx, func(d dns.Client) error {\n\t\t\tdc = d\n\t\t\treturn nil\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn New(ctx, config.(*Config), dc)\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*SimplifiedConfig)\n\t\tfullConfig := &Config{\n\t\t\tClients: func() (users []*protocol.User) {\n\t\t\t\tfor _, v := range simplifiedServer.Users {\n\t\t\t\t\taccount := &vless.Account{Id: v}\n\t\t\t\t\tusers = append(users, &protocol.User{\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}(),\n\t\t\tDecryption: \"none\",\n\t\t}\n\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n}\n\n// Handler is an inbound connection handler that handles messages in VLess protocol.\ntype Handler struct {\n\tinboundHandlerManager feature_inbound.Manager\n\tpolicyManager         policy.Manager\n\tvalidator             *vless.Validator\n\tdns                   dns.Client\n\tfallbacks             map[string]map[string]*Fallback // or nil\n\t// regexps               map[string]*regexp.Regexp       // or nil\n}\n\n// New creates a new VLess inbound handler.\nfunc New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) {\n\tv := core.MustFromContext(ctx)\n\thandler := &Handler{\n\t\tinboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager),\n\t\tpolicyManager:         v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t\tvalidator:             new(vless.Validator),\n\t\tdns:                   dc,\n\t}\n\n\tfor _, user := range config.Clients {\n\t\tu, err := user.ToMemoryUser()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get VLESS user\").Base(err).AtError()\n\t\t}\n\t\tif err := handler.AddUser(ctx, u); err != nil {\n\t\t\treturn nil, newError(\"failed to initiate user\").Base(err).AtError()\n\t\t}\n\t}\n\n\tif config.Fallbacks != nil {\n\t\thandler.fallbacks = make(map[string]map[string]*Fallback)\n\t\t// handler.regexps = make(map[string]*regexp.Regexp)\n\t\tfor _, fb := range config.Fallbacks {\n\t\t\tif handler.fallbacks[fb.Alpn] == nil {\n\t\t\t\thandler.fallbacks[fb.Alpn] = make(map[string]*Fallback)\n\t\t\t}\n\t\t\thandler.fallbacks[fb.Alpn][fb.Path] = fb\n\t\t\t/*\n\t\t\t\tif fb.Path != \"\" {\n\t\t\t\t\tif r, err := regexp.Compile(fb.Path); err != nil {\n\t\t\t\t\t\treturn nil, newError(\"invalid path regexp\").Base(err).AtError()\n\t\t\t\t\t} else {\n\t\t\t\t\t\thandler.regexps[fb.Path] = r\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t*/\n\t\t}\n\t\tif handler.fallbacks[\"\"] != nil {\n\t\t\tfor alpn, pfb := range handler.fallbacks {\n\t\t\t\tif alpn != \"\" { // && alpn != \"h2\" {\n\t\t\t\t\tfor path, fb := range handler.fallbacks[\"\"] {\n\t\t\t\t\t\tif pfb[path] == nil {\n\t\t\t\t\t\t\tpfb[path] = fb\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 handler, nil\n}\n\n// Close implements common.Closable.Close().\nfunc (h *Handler) Close() error {\n\treturn errors.Combine(common.Close(h.validator))\n}\n\n// AddUser implements proxy.UserManager.AddUser().\nfunc (h *Handler) AddUser(ctx context.Context, u *protocol.MemoryUser) error {\n\treturn h.validator.Add(u)\n}\n\n// RemoveUser implements proxy.UserManager.RemoveUser().\nfunc (h *Handler) RemoveUser(ctx context.Context, e string) error {\n\treturn h.validator.Del(e)\n}\n\n// Network implements proxy.Inbound.Network().\nfunc (*Handler) Network() []net.Network {\n\treturn []net.Network{net.Network_TCP, net.Network_UNIX}\n}\n\n// Process implements proxy.Inbound.Process().\nfunc (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error {\n\tsid := session.ExportIDToError(ctx)\n\n\tiConn := connection\n\tstatConn, ok := iConn.(*internet.StatCouterConnection)\n\tif ok {\n\t\tiConn = statConn.Connection\n\t}\n\n\tsessionPolicy := h.policyManager.ForLevel(0)\n\tif err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {\n\t\treturn newError(\"unable to set read deadline\").Base(err).AtWarning()\n\t}\n\n\tfirst := buf.New()\n\tdefer first.Release()\n\n\tfirstLen, _ := first.ReadFrom(connection)\n\tnewError(\"firstLen = \", firstLen).AtInfo().WriteToLog(sid)\n\n\treader := &buf.BufferedReader{\n\t\tReader: buf.NewReader(connection),\n\t\tBuffer: buf.MultiBuffer{first},\n\t}\n\n\tvar request *protocol.RequestHeader\n\tvar requestAddons *encoding.Addons\n\tvar err error\n\n\tapfb := h.fallbacks\n\tisfb := apfb != nil\n\n\tif isfb && firstLen < 18 {\n\t\terr = newError(\"fallback directly\")\n\t} else {\n\t\trequest, requestAddons, isfb, err = encoding.DecodeRequestHeader(isfb, first, reader, h.validator)\n\t}\n\n\tif err != nil {\n\t\tif isfb {\n\t\t\tif err := connection.SetReadDeadline(time.Time{}); err != nil {\n\t\t\t\tnewError(\"unable to set back read deadline\").Base(err).AtWarning().WriteToLog(sid)\n\t\t\t}\n\t\t\tnewError(\"fallback starts\").Base(err).AtInfo().WriteToLog(sid)\n\n\t\t\talpn := \"\"\n\t\t\tif len(apfb) > 1 || apfb[\"\"] == nil {\n\t\t\t\tif tlsConn, ok := iConn.(*tls.Conn); ok {\n\t\t\t\t\talpn = tlsConn.ConnectionState().NegotiatedProtocol\n\t\t\t\t\tnewError(\"realAlpn = \" + alpn).AtInfo().WriteToLog(sid)\n\t\t\t\t}\n\t\t\t\tif apfb[alpn] == nil {\n\t\t\t\t\talpn = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t\tpfb := apfb[alpn]\n\t\t\tif pfb == nil {\n\t\t\t\treturn newError(`failed to find the default \"alpn\" config`).AtWarning()\n\t\t\t}\n\n\t\t\tpath := \"\"\n\t\t\tif len(pfb) > 1 || pfb[\"\"] == nil {\n\t\t\t\t/*\n\t\t\t\t\tif lines := bytes.Split(firstBytes, []byte{'\\r', '\\n'}); len(lines) > 1 {\n\t\t\t\t\t\tif s := bytes.Split(lines[0], []byte{' '}); len(s) == 3 {\n\t\t\t\t\t\t\tif len(s[0]) < 8 && len(s[1]) > 0 && len(s[2]) == 8 {\n\t\t\t\t\t\t\t\tnewError(\"realPath = \" + string(s[1])).AtInfo().WriteToLog(sid)\n\t\t\t\t\t\t\t\tfor _, fb := range pfb {\n\t\t\t\t\t\t\t\t\tif fb.Path != \"\" && h.regexps[fb.Path].Match(s[1]) {\n\t\t\t\t\t\t\t\t\t\tpath = fb.Path\n\t\t\t\t\t\t\t\t\t\tbreak\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\tif firstLen >= 18 && first.Byte(4) != '*' { // not h2c\n\t\t\t\t\tfirstBytes := first.Bytes()\n\t\t\t\t\tfor i := 4; i <= 8; i++ { // 5 -> 9\n\t\t\t\t\t\tif firstBytes[i] == '/' && firstBytes[i-1] == ' ' {\n\t\t\t\t\t\t\tsearch := len(firstBytes)\n\t\t\t\t\t\t\tif search > 64 {\n\t\t\t\t\t\t\t\tsearch = 64 // up to about 60\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor j := i + 1; j < search; j++ {\n\t\t\t\t\t\t\t\tk := firstBytes[j]\n\t\t\t\t\t\t\t\tif k == '\\r' || k == '\\n' { // avoid logging \\r or \\n\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\tif k == ' ' {\n\t\t\t\t\t\t\t\t\tpath = string(firstBytes[i:j])\n\t\t\t\t\t\t\t\t\tnewError(\"realPath = \" + path).AtInfo().WriteToLog(sid)\n\t\t\t\t\t\t\t\t\tif pfb[path] == nil {\n\t\t\t\t\t\t\t\t\t\tpath = \"\"\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}\n\t\t\t\t\t\t\t}\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\tfb := pfb[path]\n\t\t\tif fb == nil {\n\t\t\t\treturn newError(`failed to find the default \"path\" config`).AtWarning()\n\t\t\t}\n\n\t\t\tctx, cancel := context.WithCancel(ctx)\n\t\t\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\t\t\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\n\t\t\tvar conn net.Conn\n\t\t\tif err := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\t\t\tvar dialer net.Dialer\n\t\t\t\tconn, err = dialer.DialContext(ctx, fb.Type, fb.Dest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}); err != nil {\n\t\t\t\treturn newError(\"failed to dial to \" + fb.Dest).Base(err).AtWarning()\n\t\t\t}\n\t\t\tdefer conn.Close()\n\n\t\t\tserverReader := buf.NewReader(conn)\n\t\t\tserverWriter := buf.NewWriter(conn)\n\n\t\t\tpostRequest := func() error {\n\t\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\t\t\t\tif fb.Xver != 0 {\n\t\t\t\t\tremoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String())\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\tlocalAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String())\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\tipv4 := true\n\t\t\t\t\tfor i := 0; i < len(remoteAddr); i++ {\n\t\t\t\t\t\tif remoteAddr[i] == ':' {\n\t\t\t\t\t\t\tipv4 = false\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\tpro := buf.New()\n\t\t\t\t\tdefer pro.Release()\n\t\t\t\t\tswitch fb.Xver {\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tif ipv4 {\n\t\t\t\t\t\t\tpro.Write([]byte(\"PROXY TCP4 \" + remoteAddr + \" \" + localAddr + \" \" + remotePort + \" \" + localPort + \"\\r\\n\"))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpro.Write([]byte(\"PROXY TCP6 \" + remoteAddr + \" \" + localAddr + \" \" + remotePort + \" \" + localPort + \"\\r\\n\"))\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tpro.Write([]byte(\"\\x0D\\x0A\\x0D\\x0A\\x00\\x0D\\x0A\\x51\\x55\\x49\\x54\\x0A\\x21\")) // signature + v2 + PROXY\n\t\t\t\t\t\tif ipv4 {\n\t\t\t\t\t\t\tpro.Write([]byte(\"\\x11\\x00\\x0C\")) // AF_INET + STREAM + 12 bytes\n\t\t\t\t\t\t\tpro.Write(net.ParseIP(remoteAddr).To4())\n\t\t\t\t\t\t\tpro.Write(net.ParseIP(localAddr).To4())\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpro.Write([]byte(\"\\x21\\x00\\x24\")) // AF_INET6 + STREAM + 36 bytes\n\t\t\t\t\t\t\tpro.Write(net.ParseIP(remoteAddr).To16())\n\t\t\t\t\t\t\tpro.Write(net.ParseIP(localAddr).To16())\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp1, _ := strconv.ParseUint(remotePort, 10, 16)\n\t\t\t\t\t\tp2, _ := strconv.ParseUint(localPort, 10, 16)\n\t\t\t\t\t\tpro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})\n\t\t\t\t\t}\n\t\t\t\t\tif err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {\n\t\t\t\t\t\treturn newError(\"failed to set PROXY protocol v\", fb.Xver).Base(err).AtWarning()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\t\treturn newError(\"failed to fallback request payload\").Base(err).AtInfo()\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\twriter := buf.NewWriter(connection)\n\n\t\t\tgetResponse := func() error {\n\t\t\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\t\t\t\tif err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\t\treturn newError(\"failed to deliver response payload\").Base(err).AtInfo()\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil {\n\t\t\t\tcommon.Interrupt(serverReader)\n\t\t\t\tcommon.Interrupt(serverWriter)\n\t\t\t\treturn newError(\"fallback ends\").Base(err).AtInfo()\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif errors.Cause(err) != io.EOF {\n\t\t\tlog.Record(&log.AccessMessage{\n\t\t\t\tFrom:   connection.RemoteAddr(),\n\t\t\t\tTo:     \"\",\n\t\t\t\tStatus: log.AccessRejected,\n\t\t\t\tReason: err,\n\t\t\t})\n\t\t\terr = newError(\"invalid request from \", connection.RemoteAddr()).Base(err).AtInfo()\n\t\t}\n\t\treturn err\n\t}\n\n\tif err := connection.SetReadDeadline(time.Time{}); err != nil {\n\t\tnewError(\"unable to set back read deadline\").Base(err).AtWarning().WriteToLog(sid)\n\t}\n\tnewError(\"received request for \", request.Destination()).AtInfo().WriteToLog(sid)\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil {\n\t\tpanic(\"no inbound metadata\")\n\t}\n\tinbound.User = request.User\n\n\tresponseAddons := &encoding.Addons{}\n\n\tif request.Command != protocol.RequestCommandMux {\n\t\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\t\tFrom:   connection.RemoteAddr(),\n\t\t\tTo:     request.Destination(),\n\t\t\tStatus: log.AccessAccepted,\n\t\t\tReason: \"\",\n\t\t\tEmail:  request.User.Email,\n\t\t})\n\t}\n\n\tsessionPolicy = h.policyManager.ForLevel(request.User.Level)\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\n\tlink, err := dispatcher.Dispatch(ctx, request.Destination())\n\tif err != nil {\n\t\treturn newError(\"failed to dispatch request to \", request.Destination()).Base(err).AtWarning()\n\t}\n\n\tserverReader := link.Reader // .(*pipe.Reader)\n\tserverWriter := link.Writer // .(*pipe.Writer)\n\n\tpostRequest := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\t// default: clientReader := reader\n\t\tclientReader := encoding.DecodeBodyAddons(reader, request, requestAddons)\n\n\t\t// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBuffer\n\t\tif err := buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tbufferWriter := buf.NewBufferedWriter(buf.NewWriter(connection))\n\t\tif err := encoding.EncodeResponseHeader(bufferWriter, request, responseAddons); err != nil {\n\t\t\treturn newError(\"failed to encode response header\").Base(err).AtWarning()\n\t\t}\n\n\t\t// default: clientWriter := bufferWriter\n\t\tclientWriter := encoding.EncodeBodyAddons(bufferWriter, request, responseAddons)\n\t\t{\n\t\t\tmultiBuffer, err := serverReader.ReadMultiBuffer()\n\t\t\tif err != nil {\n\t\t\t\treturn err // ...\n\t\t\t}\n\t\t\tif err := clientWriter.WriteMultiBuffer(multiBuffer); err != nil {\n\t\t\t\treturn err // ...\n\t\t\t}\n\t\t}\n\n\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\tif err := bufferWriter.SetBuffered(false); err != nil {\n\t\t\treturn newError(\"failed to write A response payload\").Base(err).AtWarning()\n\t\t}\n\n\t\t// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBuffer\n\t\tif err := buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer response payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), getResponse); err != nil {\n\t\tcommon.Interrupt(serverReader)\n\t\tcommon.Interrupt(serverWriter)\n\t\treturn newError(\"connection ends\").Base(err).AtInfo()\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/vless/outbound/config.go",
    "content": "package outbound\n"
  },
  {
    "path": "proxy/vless/outbound/config.pb.go",
    "content": "package outbound\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState     `protogen:\"open.v1\"`\n\tVnext         []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=vnext,proto3\" json:\"vnext,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_vless_outbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_outbound_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_outbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetVnext() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Vnext\n\t}\n\treturn nil\n}\n\ntype SimplifiedConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress       *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tUuid          string                 `protobuf:\"bytes,3,opt,name=uuid,proto3\" json:\"uuid,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_vless_outbound_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vless_outbound_config_proto_msgTypes[1]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vless_outbound_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SimplifiedConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *SimplifiedConfig) GetUuid() string {\n\tif x != nil {\n\t\treturn x.Uuid\n\t}\n\treturn \"\"\n}\n\nvar File_proxy_vless_outbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_vless_outbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!proxy/vless/outbound/config.proto\\x12\\x1fv2ray.core.proxy.vless.outbound\\x1a!common/protocol/server_spec.proto\\x1a\\x18common/net/address.proto\\x1a common/protoext/extensions.proto\\\"J\\n\" +\n\t\"\\x06Config\\x12@\\n\" +\n\t\"\\x05vnext\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\x05vnext\\\"\\x8e\\x01\\n\" +\n\t\"\\x10SimplifiedConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12\\x12\\n\" +\n\t\"\\x04uuid\\x18\\x03 \\x01(\\tR\\x04uuid:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\boutbound\\x12\\x05vlessB~\\n\" +\n\t\"#com.v2ray.core.proxy.vless.outboundP\\x01Z3github.com/v2fly/v2ray-core/v5/proxy/vless/outbound\\xaa\\x02\\x1fV2Ray.Core.Proxy.Vless.Outboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_vless_outbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_vless_outbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_vless_outbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_vless_outbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vless_outbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vless_outbound_config_proto_rawDesc), len(file_proxy_vless_outbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_vless_outbound_config_proto_rawDescData\n}\n\nvar file_proxy_vless_outbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_vless_outbound_config_proto_goTypes = []any{\n\t(*Config)(nil),                  // 0: v2ray.core.proxy.vless.outbound.Config\n\t(*SimplifiedConfig)(nil),        // 1: v2ray.core.proxy.vless.outbound.SimplifiedConfig\n\t(*protocol.ServerEndpoint)(nil), // 2: v2ray.core.common.protocol.ServerEndpoint\n\t(*net.IPOrDomain)(nil),          // 3: v2ray.core.common.net.IPOrDomain\n}\nvar file_proxy_vless_outbound_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.vless.outbound.Config.vnext:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t3, // 1: v2ray.core.proxy.vless.outbound.SimplifiedConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_vless_outbound_config_proto_init() }\nfunc file_proxy_vless_outbound_config_proto_init() {\n\tif File_proxy_vless_outbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_vless_outbound_config_proto_rawDesc), len(file_proxy_vless_outbound_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vless_outbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vless_outbound_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vless_outbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vless_outbound_config_proto = out.File\n\tfile_proxy_vless_outbound_config_proto_goTypes = nil\n\tfile_proxy_vless_outbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vless/outbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vless.outbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vless.Outbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vless/outbound\";\noption java_package = \"com.v2ray.core.proxy.vless.outbound\";\noption java_multiple_files = true;\n\nimport \"common/protocol/server_spec.proto\";\nimport \"common/net/address.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  repeated v2ray.core.common.protocol.ServerEndpoint vnext = 1;\n}\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"vless\";\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  string uuid = 3;\n}"
  },
  {
    "path": "proxy/vless/outbound/errors.generated.go",
    "content": "package outbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vless/outbound/outbound.go",
    "content": "package outbound\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vless/encoding\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedClient := config.(*SimplifiedConfig)\n\t\tfullClient := &Config{Vnext: []*protocol.ServerEndpoint{\n\t\t\t{\n\t\t\t\tAddress: simplifiedClient.Address,\n\t\t\t\tPort:    simplifiedClient.Port,\n\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t{\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vless.Account{Id: simplifiedClient.Uuid, Encryption: \"none\"}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}}\n\n\t\treturn common.CreateObject(ctx, fullClient)\n\t}))\n}\n\n// Handler is an outbound connection handler for VLess protocol.\ntype Handler struct {\n\tserverList    *protocol.ServerList\n\tserverPicker  protocol.ServerPicker\n\tpolicyManager policy.Manager\n}\n\n// New creates a new VLess outbound handler.\nfunc New(ctx context.Context, config *Config) (*Handler, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Vnext {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse server spec\").Base(err).AtError()\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\n\tv := core.MustFromContext(ctx)\n\thandler := &Handler{\n\t\tserverList:    serverList,\n\t\tserverPicker:  protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\n\treturn handler, nil\n}\n\n// Process implements proxy.Outbound.Process().\nfunc (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\tvar rec *protocol.ServerSpec\n\tvar conn internet.Connection\n\n\tif err := retry.ExponentialBackoff(5, 200).On(func() error {\n\t\trec = h.serverPicker.PickServer()\n\t\tvar err error\n\t\tconn, err = dialer.Dial(ctx, rec.Destination())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}); err != nil {\n\t\treturn newError(\"failed to find an available destination\").Base(err).AtWarning()\n\t}\n\tdefer conn.Close()\n\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\").AtError()\n\t}\n\n\ttarget := outbound.Target\n\tnewError(\"tunneling request to \", target, \" via \", rec.Destination().NetAddr()).AtInfo().WriteToLog(session.ExportIDToError(ctx))\n\n\tcommand := protocol.RequestCommandTCP\n\tif target.Network == net.Network_UDP {\n\t\tcommand = protocol.RequestCommandUDP\n\t}\n\tif target.Address.Family().IsDomain() && target.Address.Domain() == \"v1.mux.cool\" {\n\t\tcommand = protocol.RequestCommandMux\n\t}\n\n\trequest := &protocol.RequestHeader{\n\t\tVersion: encoding.Version,\n\t\tUser:    rec.PickUser(),\n\t\tCommand: command,\n\t\tAddress: target.Address,\n\t\tPort:    target.Port,\n\t}\n\n\taccount := request.User.Account.(*vless.MemoryAccount)\n\n\trequestAddons := &encoding.Addons{\n\t\tFlow: account.Flow,\n\t}\n\n\tsessionPolicy := h.policyManager.ForLevel(request.User.Level)\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\tclientReader := link.Reader // .(*pipe.Reader)\n\tclientWriter := link.Writer // .(*pipe.Writer)\n\n\tpostRequest := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tbufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\tif err := encoding.EncodeRequestHeader(bufferWriter, request, requestAddons); err != nil {\n\t\t\treturn newError(\"failed to encode request header\").Base(err).AtWarning()\n\t\t}\n\n\t\t// default: serverWriter := bufferWriter\n\t\tserverWriter := encoding.EncodeBodyAddons(bufferWriter, request, requestAddons)\n\t\tif err := buf.CopyOnceTimeout(clientReader, serverWriter, proxy.FirstPayloadTimeout); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {\n\t\t\treturn err // ...\n\t\t}\n\n\t\t// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer\n\t\tif err := bufferWriter.SetBuffered(false); err != nil {\n\t\t\treturn newError(\"failed to write A request payload\").Base(err).AtWarning()\n\t\t}\n\n\t\t// from clientReader.ReadMultiBuffer to serverWriter.WriteMultiBuffer\n\t\tif err := buf.Copy(clientReader, serverWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tgetResponse := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\tresponseAddons, err := encoding.DecodeResponseHeader(conn, request)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to decode response header\").Base(err).AtInfo()\n\t\t}\n\n\t\t// default: serverReader := buf.NewReader(conn)\n\t\tserverReader := encoding.DecodeBodyAddons(conn, request, responseAddons)\n\n\t\t// from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBuffer\n\t\tif err := buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer response payload\").Base(err).AtInfo()\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif err := task.Run(ctx, postRequest, task.OnSuccess(getResponse, task.Close(clientWriter))); err != nil {\n\t\treturn newError(\"connection ends\").Base(err).AtInfo()\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/vless/validator.go",
    "content": "package vless\n\nimport (\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\n// Validator stores valid VLESS users.\ntype Validator struct {\n\t// Considering email's usage here, map + sync.Mutex/RWMutex may have better performance.\n\temail sync.Map\n\tusers sync.Map\n}\n\n// Add a VLESS user, Email must be empty or unique.\nfunc (v *Validator) Add(u *protocol.MemoryUser) error {\n\tif u.Email != \"\" {\n\t\t_, loaded := v.email.LoadOrStore(strings.ToLower(u.Email), u)\n\t\tif loaded {\n\t\t\treturn newError(\"User \", u.Email, \" already exists.\")\n\t\t}\n\t}\n\tv.users.Store(u.Account.(*MemoryAccount).ID.UUID(), u)\n\treturn nil\n}\n\n// Del a VLESS user with a non-empty Email.\nfunc (v *Validator) Del(e string) error {\n\tif e == \"\" {\n\t\treturn newError(\"Email must not be empty.\")\n\t}\n\tle := strings.ToLower(e)\n\tu, _ := v.email.Load(le)\n\tif u == nil {\n\t\treturn newError(\"User \", e, \" not found.\")\n\t}\n\tv.email.Delete(le)\n\tv.users.Delete(u.(*protocol.MemoryUser).Account.(*MemoryAccount).ID.UUID())\n\treturn nil\n}\n\n// Get a VLESS user with UUID, nil if user doesn't exist.\nfunc (v *Validator) Get(id uuid.UUID) *protocol.MemoryUser {\n\tu, _ := v.users.Load(id)\n\tif u != nil {\n\t\treturn u.(*protocol.MemoryUser)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "proxy/vless/vless.go",
    "content": "// Package vless contains the implementation of VLess protocol and transportation.\n//\n// VLess contains both inbound and outbound connections. VLess inbound is usually used on servers\n// together with 'freedom' to talk to final destination, while VLess outbound is usually used on\n// clients with 'socks' for proxying.\npackage vless\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/vlite/inbound/config.pb.go",
    "content": "package inbound\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 UDPProtocolConfig struct {\n\tstate                       protoimpl.MessageState `protogen:\"open.v1\"`\n\tPassword                    string                 `protobuf:\"bytes,3,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tScramblePacket              bool                   `protobuf:\"varint,4,opt,name=scramble_packet,json=scramblePacket,proto3\" json:\"scramble_packet,omitempty\"`\n\tEnableFec                   bool                   `protobuf:\"varint,5,opt,name=enable_fec,json=enableFec,proto3\" json:\"enable_fec,omitempty\"`\n\tEnableStabilization         bool                   `protobuf:\"varint,6,opt,name=enable_stabilization,json=enableStabilization,proto3\" json:\"enable_stabilization,omitempty\"`\n\tEnableRenegotiation         bool                   `protobuf:\"varint,7,opt,name=enable_renegotiation,json=enableRenegotiation,proto3\" json:\"enable_renegotiation,omitempty\"`\n\tHandshakeMaskingPaddingSize uint32                 `protobuf:\"varint,8,opt,name=handshake_masking_padding_size,json=handshakeMaskingPaddingSize,proto3\" json:\"handshake_masking_padding_size,omitempty\"`\n\tunknownFields               protoimpl.UnknownFields\n\tsizeCache                   protoimpl.SizeCache\n}\n\nfunc (x *UDPProtocolConfig) Reset() {\n\t*x = UDPProtocolConfig{}\n\tmi := &file_proxy_vlite_inbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *UDPProtocolConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*UDPProtocolConfig) ProtoMessage() {}\n\nfunc (x *UDPProtocolConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vlite_inbound_config_proto_msgTypes[0]\n\tif 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 UDPProtocolConfig.ProtoReflect.Descriptor instead.\nfunc (*UDPProtocolConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vlite_inbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *UDPProtocolConfig) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nfunc (x *UDPProtocolConfig) GetScramblePacket() bool {\n\tif x != nil {\n\t\treturn x.ScramblePacket\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetEnableFec() bool {\n\tif x != nil {\n\t\treturn x.EnableFec\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetEnableStabilization() bool {\n\tif x != nil {\n\t\treturn x.EnableStabilization\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetEnableRenegotiation() bool {\n\tif x != nil {\n\t\treturn x.EnableRenegotiation\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetHandshakeMaskingPaddingSize() uint32 {\n\tif x != nil {\n\t\treturn x.HandshakeMaskingPaddingSize\n\t}\n\treturn 0\n}\n\nvar File_proxy_vlite_inbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_vlite_inbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\" proxy/vlite/inbound/config.proto\\x12\\x1ev2ray.core.proxy.vlite.inbound\\x1a common/protoext/extensions.proto\\\"\\xb9\\x02\\n\" +\n\t\"\\x11UDPProtocolConfig\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x03 \\x01(\\tR\\bpassword\\x12'\\n\" +\n\t\"\\x0fscramble_packet\\x18\\x04 \\x01(\\bR\\x0escramblePacket\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"enable_fec\\x18\\x05 \\x01(\\bR\\tenableFec\\x121\\n\" +\n\t\"\\x14enable_stabilization\\x18\\x06 \\x01(\\bR\\x13enableStabilization\\x121\\n\" +\n\t\"\\x14enable_renegotiation\\x18\\a \\x01(\\bR\\x13enableRenegotiation\\x12C\\n\" +\n\t\"\\x1ehandshake_masking_padding_size\\x18\\b \\x01(\\rR\\x1bhandshakeMaskingPaddingSize:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\ainbound\\x12\\x06vliteuB{\\n\" +\n\t\"\\\"com.v2ray.core.proxy.vlite.inboundP\\x01Z2github.com/v2fly/v2ray-core/v5/proxy/vlite/inbound\\xaa\\x02\\x1eV2Ray.Core.Proxy.Vlite.Inboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_vlite_inbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_vlite_inbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_vlite_inbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_vlite_inbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vlite_inbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vlite_inbound_config_proto_rawDesc), len(file_proxy_vlite_inbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_vlite_inbound_config_proto_rawDescData\n}\n\nvar file_proxy_vlite_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_vlite_inbound_config_proto_goTypes = []any{\n\t(*UDPProtocolConfig)(nil), // 0: v2ray.core.proxy.vlite.inbound.UDPProtocolConfig\n}\nvar file_proxy_vlite_inbound_config_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_proxy_vlite_inbound_config_proto_init() }\nfunc file_proxy_vlite_inbound_config_proto_init() {\n\tif File_proxy_vlite_inbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_vlite_inbound_config_proto_rawDesc), len(file_proxy_vlite_inbound_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vlite_inbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vlite_inbound_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vlite_inbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vlite_inbound_config_proto = out.File\n\tfile_proxy_vlite_inbound_config_proto_goTypes = nil\n\tfile_proxy_vlite_inbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vlite/inbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vlite.inbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vlite.Inbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vlite/inbound\";\noption java_package = \"com.v2ray.core.proxy.vlite.inbound\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage UDPProtocolConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"vliteu\";\n\n  string password = 3;\n  bool scramble_packet = 4;\n  bool enable_fec = 5;\n  bool enable_stabilization = 6;\n  bool enable_renegotiation = 7;\n  uint32 handshake_masking_padding_size = 8;\n}"
  },
  {
    "path": "proxy/vlite/inbound/connAdp.go",
    "content": "package inbound\n\nimport (\n\t\"io\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n)\n\nfunc newUDPConnAdaptor(conn net.Conn, done *done.Instance) net.Conn {\n\treturn &udpConnAdp{\n\t\tConn:              conn,\n\t\treader:            buf.NewPacketReader(conn),\n\t\tcachedMultiBuffer: nil,\n\t\tfinished:          done,\n\t}\n}\n\ntype udpConnAdp struct {\n\tnet.Conn\n\treader buf.Reader\n\n\tcachedMultiBuffer buf.MultiBuffer\n\n\tfinished *done.Instance\n}\n\nfunc (u *udpConnAdp) Read(p []byte) (n int, err error) {\n\tif u.cachedMultiBuffer.IsEmpty() {\n\t\tu.cachedMultiBuffer, err = u.reader.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\treturn 0, newError(\"unable to read from connection\").Base(err)\n\t\t}\n\t}\n\tvar buffer *buf.Buffer\n\tu.cachedMultiBuffer, buffer = buf.SplitFirst(u.cachedMultiBuffer)\n\tdefer buffer.Release()\n\tn = copy(p, buffer.Bytes())\n\tif n != int(buffer.Len()) {\n\t\treturn 0, io.ErrShortBuffer\n\t}\n\treturn n, nil\n}\n\nfunc (u *udpConnAdp) Close() error {\n\tu.finished.Close()\n\treturn u.Conn.Close()\n}\n"
  },
  {
    "path": "proxy/vlite/inbound/errors.generated.go",
    "content": "package inbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vlite/inbound/inbound.go",
    "content": "package inbound\n\nimport (\n\t\"context\"\n\t\"io\"\n\tgonet \"net\"\n\t\"strconv\"\n\t\"sync\"\n\n\t\"github.com/mustafaturan/bus\"\n\t\"github.com/xiaokangwang/VLite/interfaces\"\n\t\"github.com/xiaokangwang/VLite/interfaces/ibus\"\n\t\"github.com/xiaokangwang/VLite/transport\"\n\tudpsctpserver \"github.com/xiaokangwang/VLite/transport/packetsctp/sctprelay\"\n\t\"github.com/xiaokangwang/VLite/transport/packetuni/puniServer\"\n\t\"github.com/xiaokangwang/VLite/transport/udp/udpServer\"\n\t\"github.com/xiaokangwang/VLite/transport/udp/udpuni/udpunis\"\n\t\"github.com/xiaokangwang/VLite/transport/uni/uniserver\"\n\t\"github.com/xiaokangwang/VLite/workers/server\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc NewUDPInboundHandler(ctx context.Context, config *UDPProtocolConfig) (*Handler, error) {\n\tproxyEnvironment := envctx.EnvironmentFromContext(ctx).(environment.ProxyEnvironment)\n\tstatusInstance, err := createStatusFromConfig(config)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to initialize vlite\").Base(err)\n\t}\n\tproxyEnvironment.TransientStorage().Put(ctx, \"status\", statusInstance)\n\treturn &Handler{ctx: ctx}, nil\n}\n\ntype Handler struct {\n\tctx context.Context\n}\n\nfunc (h *Handler) Network() []net.Network {\n\tlist := []net.Network{net.Network_UDP}\n\treturn list\n}\n\ntype status struct {\n\tconfig *UDPProtocolConfig\n\n\tpassword []byte\n\tmsgbus   *bus.Bus\n\n\tctx context.Context\n\n\ttransport transport.UnderlayTransportListener\n\n\taccess sync.Mutex\n}\n\nfunc (s *status) RelayStream(conn io.ReadWriteCloser, ctx context.Context) { //nolint:revive\n}\n\nfunc (s *status) Connection(conn gonet.Conn, connctx context.Context) context.Context { //nolint:revive,stylecheck\n\tS_S2CTraffic := make(chan server.UDPServerTxToClientTraffic, 8)         //nolint:revive,stylecheck\n\tS_S2CDataTraffic := make(chan server.UDPServerTxToClientDataTraffic, 8) //nolint:revive,stylecheck\n\tS_C2STraffic := make(chan server.UDPServerRxFromClientTraffic, 8)       //nolint:revive,stylecheck\n\n\tS_S2CTraffic2 := make(chan interfaces.TrafficWithChannelTag, 8)     //nolint:revive,stylecheck\n\tS_S2CDataTraffic2 := make(chan interfaces.TrafficWithChannelTag, 8) //nolint:revive,stylecheck\n\tS_C2STraffic2 := make(chan interfaces.TrafficWithChannelTag, 8)     //nolint:revive,stylecheck\n\n\tgo func(ctx context.Context) {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase data := <-S_S2CTraffic:\n\t\t\t\tS_S2CTraffic2 <- interfaces.TrafficWithChannelTag(data)\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}(connctx)\n\n\tgo func(ctx context.Context) {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase data := <-S_S2CDataTraffic:\n\t\t\t\tS_S2CDataTraffic2 <- interfaces.TrafficWithChannelTag(data)\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}(connctx)\n\n\tgo func(ctx context.Context) {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase data := <-S_C2STraffic2:\n\t\t\t\tS_C2STraffic <- server.UDPServerRxFromClientTraffic(data)\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}(connctx)\n\n\tif !s.config.EnableStabilization || !s.config.EnableRenegotiation {\n\t\trelay := udpsctpserver.NewPacketRelayServer(conn, S_S2CTraffic2, S_S2CDataTraffic2, S_C2STraffic2, s, s.password, connctx)\n\t\tudpserver := server.UDPServer(connctx, S_S2CTraffic, S_S2CDataTraffic, S_C2STraffic, relay)\n\t\t_ = udpserver\n\t} else {\n\t\trelay := puniServer.NewPacketUniServer(S_S2CTraffic2, S_S2CDataTraffic2, S_C2STraffic2, s, s.password, connctx)\n\t\trelay.OnAutoCarrier(conn, connctx)\n\t\tudpserver := server.UDPServer(connctx, S_S2CTraffic, S_S2CDataTraffic, S_C2STraffic, relay)\n\t\t_ = udpserver\n\t}\n\treturn connctx\n}\n\nfunc createStatusFromConfig(config *UDPProtocolConfig) (*status, error) { //nolint:unparam\n\ts := &status{ctx: context.Background(), config: config}\n\n\ts.password = []byte(config.Password)\n\n\ts.msgbus = ibus.NewMessageBus()\n\ts.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsMessageBus, s.msgbus) //nolint:revive,staticcheck\n\n\tif config.ScramblePacket {\n\t\ts.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUDPShouldMask, true) //nolint:revive,staticcheck\n\t}\n\n\tif s.config.EnableFec {\n\t\ts.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUDPFECEnabled, true) //nolint:revive,staticcheck\n\t}\n\n\ts.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUDPMask, string(s.password)) //nolint:revive,staticcheck\n\n\tif config.HandshakeMaskingPaddingSize != 0 {\n\t\tctxv := &interfaces.ExtraOptionsUsePacketArmorValue{PacketArmorPaddingTo: int(config.HandshakeMaskingPaddingSize), UsePacketArmor: true}\n\t\ts.ctx = context.WithValue(s.ctx, interfaces.ExtraOptionsUsePacketArmor, ctxv) //nolint:revive,staticcheck\n\t}\n\n\treturn s, nil\n}\n\nfunc enableInterface(s *status) error { //nolint: unparam\n\ts.transport = s\n\tif s.config.EnableStabilization {\n\t\ts.transport = uniserver.NewUnifiedConnectionTransportHub(s, s.ctx)\n\t}\n\tif s.config.EnableStabilization {\n\t\ts.transport = udpunis.NewUdpUniServer(string(s.password), s.ctx, s.transport)\n\t}\n\treturn nil\n}\n\nfunc (h *Handler) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {\n\tproxyEnvironment := envctx.EnvironmentFromContext(h.ctx).(environment.ProxyEnvironment)\n\tstatusInstanceIfce, err := proxyEnvironment.TransientStorage().Get(ctx, \"status\")\n\tif err != nil {\n\t\treturn newError(\"uninitialized handler\").Base(err)\n\t}\n\tstatusInstance := statusInstanceIfce.(*status)\n\terr = h.ensureStarted(statusInstance)\n\tif err != nil {\n\t\treturn newError(\"unable to initialize\").Base(err)\n\t}\n\tfinish := done.New()\n\tconn = newUDPConnAdaptor(conn, finish)\n\tvar initialData [1600]byte\n\tc, err := conn.Read(initialData[:])\n\tif err != nil {\n\t\treturn newError(\"unable to read initial data\").Base(err)\n\t}\n\tconnID := session.IDFromContext(ctx)\n\tvconn, connctx := udpServer.PrepareIncomingUDPConnection(conn, statusInstance.ctx, initialData[:c], strconv.FormatInt(int64(connID), 10))\n\tconnctx = statusInstance.transport.Connection(vconn, connctx)\n\tif connctx == nil {\n\t\treturn newError(\"invalid connection discarded\")\n\t}\n\t<-finish.Wait()\n\treturn nil\n}\n\nfunc (h *Handler) ensureStarted(s *status) error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tif s.transport == nil {\n\t\terr := enableInterface(s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*UDPProtocolConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewUDPInboundHandler(ctx, config.(*UDPProtocolConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/vlite/outbound/config.pb.go",
    "content": "package outbound\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 UDPProtocolConfig struct {\n\tstate                       protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress                     *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort                        uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tPassword                    string                 `protobuf:\"bytes,3,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tScramblePacket              bool                   `protobuf:\"varint,4,opt,name=scramble_packet,json=scramblePacket,proto3\" json:\"scramble_packet,omitempty\"`\n\tEnableFec                   bool                   `protobuf:\"varint,5,opt,name=enable_fec,json=enableFec,proto3\" json:\"enable_fec,omitempty\"`\n\tEnableStabilization         bool                   `protobuf:\"varint,6,opt,name=enable_stabilization,json=enableStabilization,proto3\" json:\"enable_stabilization,omitempty\"`\n\tEnableRenegotiation         bool                   `protobuf:\"varint,7,opt,name=enable_renegotiation,json=enableRenegotiation,proto3\" json:\"enable_renegotiation,omitempty\"`\n\tHandshakeMaskingPaddingSize uint32                 `protobuf:\"varint,8,opt,name=handshake_masking_padding_size,json=handshakeMaskingPaddingSize,proto3\" json:\"handshake_masking_padding_size,omitempty\"`\n\tunknownFields               protoimpl.UnknownFields\n\tsizeCache                   protoimpl.SizeCache\n}\n\nfunc (x *UDPProtocolConfig) Reset() {\n\t*x = UDPProtocolConfig{}\n\tmi := &file_proxy_vlite_outbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *UDPProtocolConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*UDPProtocolConfig) ProtoMessage() {}\n\nfunc (x *UDPProtocolConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vlite_outbound_config_proto_msgTypes[0]\n\tif 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 UDPProtocolConfig.ProtoReflect.Descriptor instead.\nfunc (*UDPProtocolConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vlite_outbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *UDPProtocolConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *UDPProtocolConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *UDPProtocolConfig) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nfunc (x *UDPProtocolConfig) GetScramblePacket() bool {\n\tif x != nil {\n\t\treturn x.ScramblePacket\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetEnableFec() bool {\n\tif x != nil {\n\t\treturn x.EnableFec\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetEnableStabilization() bool {\n\tif x != nil {\n\t\treturn x.EnableStabilization\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetEnableRenegotiation() bool {\n\tif x != nil {\n\t\treturn x.EnableRenegotiation\n\t}\n\treturn false\n}\n\nfunc (x *UDPProtocolConfig) GetHandshakeMaskingPaddingSize() uint32 {\n\tif x != nil {\n\t\treturn x.HandshakeMaskingPaddingSize\n\t}\n\treturn 0\n}\n\nvar File_proxy_vlite_outbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_vlite_outbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!proxy/vlite/outbound/config.proto\\x12\\x1fv2ray.core.proxy.vlite.outbound\\x1a\\x18common/net/address.proto\\x1a common/protoext/extensions.proto\\\"\\x8b\\x03\\n\" +\n\t\"\\x11UDPProtocolConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x03 \\x01(\\tR\\bpassword\\x12'\\n\" +\n\t\"\\x0fscramble_packet\\x18\\x04 \\x01(\\bR\\x0escramblePacket\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"enable_fec\\x18\\x05 \\x01(\\bR\\tenableFec\\x121\\n\" +\n\t\"\\x14enable_stabilization\\x18\\x06 \\x01(\\bR\\x13enableStabilization\\x121\\n\" +\n\t\"\\x14enable_renegotiation\\x18\\a \\x01(\\bR\\x13enableRenegotiation\\x12C\\n\" +\n\t\"\\x1ehandshake_masking_padding_size\\x18\\b \\x01(\\rR\\x1bhandshakeMaskingPaddingSize:\\x16\\x82\\xb5\\x18\\x12\\n\" +\n\t\"\\boutbound\\x12\\x06vliteuB~\\n\" +\n\t\"#com.v2ray.core.proxy.vlite.outboundP\\x01Z3github.com/v2fly/v2ray-core/v5/proxy/vlite/outbound\\xaa\\x02\\x1fV2Ray.Core.Proxy.Vlite.Outboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_vlite_outbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_vlite_outbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_vlite_outbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_vlite_outbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vlite_outbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vlite_outbound_config_proto_rawDesc), len(file_proxy_vlite_outbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_vlite_outbound_config_proto_rawDescData\n}\n\nvar file_proxy_vlite_outbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_vlite_outbound_config_proto_goTypes = []any{\n\t(*UDPProtocolConfig)(nil), // 0: v2ray.core.proxy.vlite.outbound.UDPProtocolConfig\n\t(*net.IPOrDomain)(nil),    // 1: v2ray.core.common.net.IPOrDomain\n}\nvar file_proxy_vlite_outbound_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.proxy.vlite.outbound.UDPProtocolConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_vlite_outbound_config_proto_init() }\nfunc file_proxy_vlite_outbound_config_proto_init() {\n\tif File_proxy_vlite_outbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_vlite_outbound_config_proto_rawDesc), len(file_proxy_vlite_outbound_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vlite_outbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vlite_outbound_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vlite_outbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vlite_outbound_config_proto = out.File\n\tfile_proxy_vlite_outbound_config_proto_goTypes = nil\n\tfile_proxy_vlite_outbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vlite/outbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vlite.outbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vlite.Outbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vlite/outbound\";\noption java_package = \"com.v2ray.core.proxy.vlite.outbound\";\noption java_multiple_files = true;\n\nimport \"common/net/address.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage UDPProtocolConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"vliteu\";\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n\n  string password = 3;\n  bool scramble_packet = 4;\n  bool enable_fec = 5;\n  bool enable_stabilization = 6;\n  bool enable_renegotiation = 7;\n  uint32 handshake_masking_padding_size = 8;\n}"
  },
  {
    "path": "proxy/vlite/outbound/errors.generated.go",
    "content": "package outbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vlite/outbound/outbound.go",
    "content": "package outbound\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/mustafaturan/bus\"\n\t\"github.com/xiaokangwang/VLite/ass/udpconn2tun\"\n\t\"github.com/xiaokangwang/VLite/interfaces\"\n\t\"github.com/xiaokangwang/VLite/interfaces/ibus\"\n\tvltransport \"github.com/xiaokangwang/VLite/transport\"\n\tudpsctpserver \"github.com/xiaokangwang/VLite/transport/packetsctp/sctprelay\"\n\t\"github.com/xiaokangwang/VLite/transport/packetuni/puniClient\"\n\t\"github.com/xiaokangwang/VLite/transport/udp/udpClient\"\n\t\"github.com/xiaokangwang/VLite/transport/udp/udpuni/udpunic\"\n\t\"github.com/xiaokangwang/VLite/transport/uni/uniclient\"\n\tclient2 \"github.com/xiaokangwang/VLite/workers/client\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc NewUDPOutboundHandler(ctx context.Context, config *UDPProtocolConfig) (*Handler, error) {\n\tproxyEnvironment := envctx.EnvironmentFromContext(ctx).(environment.ProxyEnvironment)\n\tstatusInstance, err := createStatusFromConfig(config)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to initialize vlite\").Base(err)\n\t}\n\tproxyEnvironment.TransientStorage().Put(ctx, \"status\", statusInstance)\n\treturn &Handler{ctx: ctx}, nil\n}\n\ntype Handler struct {\n\tctx context.Context\n}\n\n// Process implements proxy.Outbound.Process().\nfunc (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\tproxyEnvironment := envctx.EnvironmentFromContext(h.ctx).(environment.ProxyEnvironment)\n\tstatusInstanceIfce, err := proxyEnvironment.TransientStorage().Get(ctx, \"status\")\n\tif err != nil {\n\t\treturn newError(\"uninitialized handler\").Base(err)\n\t}\n\tstatusInstance := statusInstanceIfce.(*status)\n\terr = h.ensureStarted(statusInstance)\n\tif err != nil {\n\t\treturn newError(\"unable to initialize\").Base(err)\n\t}\n\tconnid := session.IDFromContext(ctx)\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\")\n\t}\n\tdestination := outbound.Target\n\tpacketConnOut := statusInstance.connAdp.DialUDP(net.UDPAddr{Port: int(connid % 65535)})\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, time.Second*600)\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\trequestDone := func() error {\n\t\t\treturn udp.CopyPacketConn(packetConnOut, packetConn, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\treturn udp.CopyPacketConn(packetConn, packetConnOut, udp.UpdateActivity(timer))\n\t\t}\n\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\tif err := task.Run(ctx, requestDone, responseDoneAndCloseWriter); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t}\n\treturn newError(\"unrecognized connection\")\n}\n\nfunc (h *Handler) ensureStarted(s *status) error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\tif s.TunnelRxFromTun == nil {\n\t\terr := enableInterface(s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\ntype status struct {\n\tctx      context.Context\n\tpassword []byte\n\tmsgbus   *bus.Bus\n\n\tudpdialer vltransport.UnderlayTransportDialer\n\tpuni      *puniClient.PacketUniClient\n\tudprelay  *udpsctpserver.PacketSCTPRelay\n\tudpserver *client2.UDPClientContext\n\n\tTunnelTxToTun   chan interfaces.UDPPacket\n\tTunnelRxFromTun chan interfaces.UDPPacket\n\n\tconnAdp *udpconn2tun.UDPConn2Tun\n\n\tconfig UDPProtocolConfig\n\n\taccess sync.Mutex\n}\n\nfunc createStatusFromConfig(config *UDPProtocolConfig) (*status, error) { //nolint:unparam\n\ts := &status{password: []byte(config.Password)}\n\tctx := context.Background()\n\n\ts.msgbus = ibus.NewMessageBus()\n\tctx = context.WithValue(ctx, interfaces.ExtraOptionsMessageBus, s.msgbus) //nolint:revive,staticcheck\n\n\tctx = context.WithValue(ctx, interfaces.ExtraOptionsDisableAutoQuitForClient, true) //nolint:revive,staticcheck\n\n\tif config.EnableFec {\n\t\tctx = context.WithValue(ctx, interfaces.ExtraOptionsUDPFECEnabled, true) //nolint:revive,staticcheck\n\t}\n\n\tif config.ScramblePacket {\n\t\tctx = context.WithValue(ctx, interfaces.ExtraOptionsUDPShouldMask, true) //nolint:revive,staticcheck\n\t}\n\n\tctx = context.WithValue(ctx, interfaces.ExtraOptionsUDPMask, string(s.password)) //nolint:revive,staticcheck\n\n\tif config.HandshakeMaskingPaddingSize != 0 {\n\t\tctxv := &interfaces.ExtraOptionsUsePacketArmorValue{PacketArmorPaddingTo: int(config.HandshakeMaskingPaddingSize), UsePacketArmor: true}\n\t\tctx = context.WithValue(ctx, interfaces.ExtraOptionsUsePacketArmor, ctxv) //nolint:revive,staticcheck\n\t}\n\n\tdestinationString := fmt.Sprintf(\"%v:%v\", config.Address.AsAddress().String(), config.Port)\n\n\ts.udpdialer = udpClient.NewUdpClient(destinationString, ctx)\n\tif config.EnableStabilization {\n\t\ts.udpdialer = udpunic.NewUdpUniClient(string(s.password), ctx, s.udpdialer)\n\t\ts.udpdialer = uniclient.NewUnifiedConnectionClient(s.udpdialer, ctx)\n\t}\n\ts.ctx = ctx\n\treturn s, nil\n}\n\nfunc enableInterface(s *status) error {\n\tconn, err, connctx := s.udpdialer.Connect(s.ctx)\n\tif err != nil {\n\t\treturn newError(\"unable to connect to remote\").Base(err)\n\t}\n\n\tC_C2STraffic := make(chan client2.UDPClientTxToServerTraffic, 8)         //nolint:revive,stylecheck\n\tC_C2SDataTraffic := make(chan client2.UDPClientTxToServerDataTraffic, 8) //nolint:revive,stylecheck\n\tC_S2CTraffic := make(chan client2.UDPClientRxFromServerTraffic, 8)       //nolint:revive,stylecheck\n\n\tC_C2STraffic2 := make(chan interfaces.TrafficWithChannelTag, 8)     //nolint:revive,stylecheck\n\tC_C2SDataTraffic2 := make(chan interfaces.TrafficWithChannelTag, 8) //nolint:revive,stylecheck\n\tC_S2CTraffic2 := make(chan interfaces.TrafficWithChannelTag, 8)     //nolint:revive,stylecheck\n\n\tgo func(ctx context.Context) {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase data := <-C_C2STraffic:\n\t\t\t\tC_C2STraffic2 <- interfaces.TrafficWithChannelTag(data)\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}(connctx)\n\n\tgo func(ctx context.Context) {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase data := <-C_C2SDataTraffic:\n\t\t\t\tC_C2SDataTraffic2 <- interfaces.TrafficWithChannelTag(data)\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}(connctx)\n\n\tgo func(ctx context.Context) {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase data := <-C_S2CTraffic2:\n\t\t\t\tC_S2CTraffic <- client2.UDPClientRxFromServerTraffic(data)\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}(connctx)\n\n\tTunnelTxToTun := make(chan interfaces.UDPPacket)\n\tTunnelRxFromTun := make(chan interfaces.UDPPacket)\n\n\ts.TunnelTxToTun = TunnelTxToTun\n\ts.TunnelRxFromTun = TunnelRxFromTun\n\n\tif s.config.EnableStabilization && s.config.EnableRenegotiation {\n\t\ts.puni = puniClient.NewPacketUniClient(C_C2STraffic2, C_C2SDataTraffic2, C_S2CTraffic2, s.password, connctx)\n\t\ts.puni.OnAutoCarrier(conn, connctx)\n\t\ts.udpserver = client2.UDPClient(connctx, C_C2STraffic, C_C2SDataTraffic, C_S2CTraffic, TunnelTxToTun, TunnelRxFromTun, s.puni)\n\t} else {\n\t\ts.udprelay = udpsctpserver.NewPacketRelayClient(conn, C_C2STraffic2, C_C2SDataTraffic2, C_S2CTraffic2, s.password, connctx)\n\t\ts.udpserver = client2.UDPClient(connctx, C_C2STraffic, C_C2SDataTraffic, C_S2CTraffic, TunnelTxToTun, TunnelRxFromTun, s.udprelay)\n\t}\n\n\ts.ctx = connctx\n\n\ts.connAdp = udpconn2tun.NewUDPConn2Tun(TunnelTxToTun, TunnelRxFromTun)\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*UDPProtocolConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewUDPOutboundHandler(ctx, config.(*UDPProtocolConfig))\n\t}))\n}\n"
  },
  {
    "path": "proxy/vlite/vlite.go",
    "content": "// Package vlite contains the integration code for VLite protocol variety\n//\n// VLite is currently an experimental protocol, its stability is not guaranteed.\npackage vlite\n"
  },
  {
    "path": "proxy/vmess/account.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage vmess\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\n// MemoryAccount is an in-memory form of VMess account.\ntype MemoryAccount struct {\n\t// ID is the main ID of the account.\n\tID *protocol.ID\n\t// AlterIDs are the alternative IDs of the account.\n\tAlterIDs []*protocol.ID\n\t// Security type of the account. Used for client connections.\n\tSecurity protocol.SecurityType\n\n\tAuthenticatedLengthExperiment bool\n\tNoTerminationSignal           bool\n}\n\n// AnyValidID returns an ID that is either the main ID or one of the alternative IDs if any.\nfunc (a *MemoryAccount) AnyValidID() *protocol.ID {\n\tif len(a.AlterIDs) == 0 {\n\t\treturn a.ID\n\t}\n\treturn a.AlterIDs[dice.Roll(len(a.AlterIDs))]\n}\n\n// Equals implements protocol.Account.\nfunc (a *MemoryAccount) Equals(account protocol.Account) bool {\n\tvmessAccount, ok := account.(*MemoryAccount)\n\tif !ok {\n\t\treturn false\n\t}\n\t// TODO: handle AlterIds difference\n\treturn a.ID.Equals(vmessAccount.ID)\n}\n\n// AsAccount implements protocol.Account.\nfunc (a *Account) AsAccount() (protocol.Account, error) {\n\tid, err := uuid.ParseString(a.Id)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse ID\").Base(err).AtError()\n\t}\n\tprotoID := protocol.NewID(id)\n\tvar AuthenticatedLength, NoTerminationSignal bool\n\tif strings.Contains(a.TestsEnabled, \"AuthenticatedLength\") {\n\t\tAuthenticatedLength = true\n\t}\n\tif strings.Contains(a.TestsEnabled, \"NoTerminationSignal\") {\n\t\tNoTerminationSignal = true\n\t}\n\treturn &MemoryAccount{\n\t\tID:                            protoID,\n\t\tAlterIDs:                      protocol.NewAlterIDs(protoID, uint16(a.AlterId)),\n\t\tSecurity:                      a.SecuritySettings.GetSecurityType(),\n\t\tAuthenticatedLengthExperiment: AuthenticatedLength,\n\t\tNoTerminationSignal:           NoTerminationSignal,\n\t}, nil\n}\n"
  },
  {
    "path": "proxy/vmess/account.pb.go",
    "content": "package vmess\n\nimport (\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Account struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// ID of the account, in the form of a UUID, e.g.,\n\t// \"66ad4540-b58c-4ad2-9926-ea63445a9b57\".\n\tId string `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\t// Number of alternative IDs. Client and server must share the same number.\n\tAlterId uint32 `protobuf:\"varint,2,opt,name=alter_id,json=alterId,proto3\" json:\"alter_id,omitempty\"`\n\t// Security settings. Only applies to client side.\n\tSecuritySettings *protocol.SecurityConfig `protobuf:\"bytes,3,opt,name=security_settings,json=securitySettings,proto3\" json:\"security_settings,omitempty\"`\n\t// Define tests enabled for this account\n\tTestsEnabled  string `protobuf:\"bytes,4,opt,name=tests_enabled,json=testsEnabled,proto3\" json:\"tests_enabled,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Account) Reset() {\n\t*x = Account{}\n\tmi := &file_proxy_vmess_account_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Account) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Account) ProtoMessage() {}\n\nfunc (x *Account) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_account_proto_msgTypes[0]\n\tif 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 Account.ProtoReflect.Descriptor instead.\nfunc (*Account) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_account_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Account) GetId() string {\n\tif x != nil {\n\t\treturn x.Id\n\t}\n\treturn \"\"\n}\n\nfunc (x *Account) GetAlterId() uint32 {\n\tif x != nil {\n\t\treturn x.AlterId\n\t}\n\treturn 0\n}\n\nfunc (x *Account) GetSecuritySettings() *protocol.SecurityConfig {\n\tif x != nil {\n\t\treturn x.SecuritySettings\n\t}\n\treturn nil\n}\n\nfunc (x *Account) GetTestsEnabled() string {\n\tif x != nil {\n\t\treturn x.TestsEnabled\n\t}\n\treturn \"\"\n}\n\nvar File_proxy_vmess_account_proto protoreflect.FileDescriptor\n\nconst file_proxy_vmess_account_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x19proxy/vmess/account.proto\\x12\\x16v2ray.core.proxy.vmess\\x1a\\x1dcommon/protocol/headers.proto\\\"\\xb2\\x01\\n\" +\n\t\"\\aAccount\\x12\\x0e\\n\" +\n\t\"\\x02id\\x18\\x01 \\x01(\\tR\\x02id\\x12\\x19\\n\" +\n\t\"\\balter_id\\x18\\x02 \\x01(\\rR\\aalterId\\x12W\\n\" +\n\t\"\\x11security_settings\\x18\\x03 \\x01(\\v2*.v2ray.core.common.protocol.SecurityConfigR\\x10securitySettings\\x12#\\n\" +\n\t\"\\rtests_enabled\\x18\\x04 \\x01(\\tR\\ftestsEnabledBc\\n\" +\n\t\"\\x1acom.v2ray.core.proxy.vmessP\\x01Z*github.com/v2fly/v2ray-core/v5/proxy/vmess\\xaa\\x02\\x16V2Ray.Core.Proxy.Vmessb\\x06proto3\"\n\nvar (\n\tfile_proxy_vmess_account_proto_rawDescOnce sync.Once\n\tfile_proxy_vmess_account_proto_rawDescData []byte\n)\n\nfunc file_proxy_vmess_account_proto_rawDescGZIP() []byte {\n\tfile_proxy_vmess_account_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vmess_account_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vmess_account_proto_rawDesc), len(file_proxy_vmess_account_proto_rawDesc)))\n\t})\n\treturn file_proxy_vmess_account_proto_rawDescData\n}\n\nvar file_proxy_vmess_account_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_vmess_account_proto_goTypes = []any{\n\t(*Account)(nil),                 // 0: v2ray.core.proxy.vmess.Account\n\t(*protocol.SecurityConfig)(nil), // 1: v2ray.core.common.protocol.SecurityConfig\n}\nvar file_proxy_vmess_account_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.proxy.vmess.Account.security_settings:type_name -> v2ray.core.common.protocol.SecurityConfig\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_vmess_account_proto_init() }\nfunc file_proxy_vmess_account_proto_init() {\n\tif File_proxy_vmess_account_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: unsafe.Slice(unsafe.StringData(file_proxy_vmess_account_proto_rawDesc), len(file_proxy_vmess_account_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vmess_account_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vmess_account_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vmess_account_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vmess_account_proto = out.File\n\tfile_proxy_vmess_account_proto_goTypes = nil\n\tfile_proxy_vmess_account_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vmess/account.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vmess;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vmess\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vmess\";\noption java_package = \"com.v2ray.core.proxy.vmess\";\noption java_multiple_files = true;\n\nimport \"common/protocol/headers.proto\";\n\nmessage Account {\n  // ID of the account, in the form of a UUID, e.g.,\n  // \"66ad4540-b58c-4ad2-9926-ea63445a9b57\".\n  string id = 1;\n  // Number of alternative IDs. Client and server must share the same number.\n  uint32 alter_id = 2;\n  // Security settings. Only applies to client side.\n  v2ray.core.common.protocol.SecurityConfig security_settings = 3;\n  // Define tests enabled for this account\n  string tests_enabled = 4;\n}\n"
  },
  {
    "path": "proxy/vmess/aead/authid.go",
    "content": "package aead\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\trand3 \"crypto/rand\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"hash/crc32\"\n\t\"io\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/antireplay\"\n)\n\nvar (\n\tErrNotFound = errors.New(\"user do not exist\")\n\tErrReplay   = errors.New(\"replayed request\")\n)\n\nfunc CreateAuthID(cmdKey []byte, time int64) [16]byte {\n\tbuf := bytes.NewBuffer(nil)\n\tcommon.Must(binary.Write(buf, binary.BigEndian, time))\n\tvar zero uint32\n\tcommon.Must2(io.CopyN(buf, rand3.Reader, 4))\n\tzero = crc32.ChecksumIEEE(buf.Bytes())\n\tcommon.Must(binary.Write(buf, binary.BigEndian, zero))\n\taesBlock := NewCipherFromKey(cmdKey)\n\tif buf.Len() != 16 {\n\t\tpanic(\"Size unexpected\")\n\t}\n\tvar result [16]byte\n\taesBlock.Encrypt(result[:], buf.Bytes())\n\treturn result\n}\n\nfunc NewCipherFromKey(cmdKey []byte) cipher.Block {\n\taesBlock, err := aes.NewCipher(KDF16(cmdKey, KDFSaltConstAuthIDEncryptionKey))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn aesBlock\n}\n\ntype AuthIDDecoder struct {\n\ts cipher.Block\n}\n\nfunc NewAuthIDDecoder(cmdKey []byte) *AuthIDDecoder {\n\treturn &AuthIDDecoder{NewCipherFromKey(cmdKey)}\n}\n\nfunc (aidd *AuthIDDecoder) Decode(data [16]byte) (int64, uint32, int32, []byte) {\n\taidd.s.Decrypt(data[:], data[:])\n\tvar t int64\n\tvar zero uint32\n\tvar rand int32\n\treader := bytes.NewReader(data[:])\n\tcommon.Must(binary.Read(reader, binary.BigEndian, &t))\n\tcommon.Must(binary.Read(reader, binary.BigEndian, &rand))\n\tcommon.Must(binary.Read(reader, binary.BigEndian, &zero))\n\treturn t, zero, rand, data[:]\n}\n\nfunc NewAuthIDDecoderHolder() *AuthIDDecoderHolder {\n\treturn &AuthIDDecoderHolder{make(map[string]*AuthIDDecoderItem), antireplay.NewReplayFilter(120)}\n}\n\ntype AuthIDDecoderHolder struct {\n\tdecoders map[string]*AuthIDDecoderItem\n\tfilter   *antireplay.ReplayFilter\n}\n\ntype AuthIDDecoderItem struct {\n\tdec    *AuthIDDecoder\n\tticket interface{}\n}\n\nfunc NewAuthIDDecoderItem(key [16]byte, ticket interface{}) *AuthIDDecoderItem {\n\treturn &AuthIDDecoderItem{\n\t\tdec:    NewAuthIDDecoder(key[:]),\n\t\tticket: ticket,\n\t}\n}\n\nfunc (a *AuthIDDecoderHolder) AddUser(key [16]byte, ticket interface{}) {\n\ta.decoders[string(key[:])] = NewAuthIDDecoderItem(key, ticket)\n}\n\nfunc (a *AuthIDDecoderHolder) RemoveUser(key [16]byte) {\n\tdelete(a.decoders, string(key[:]))\n}\n\nfunc (a *AuthIDDecoderHolder) Match(authID [16]byte) (interface{}, error) {\n\tfor _, v := range a.decoders {\n\t\tt, z, _, d := v.dec.Decode(authID)\n\t\tif z != crc32.ChecksumIEEE(d[:12]) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif t < 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif math.Abs(math.Abs(float64(t))-float64(time.Now().Unix())) > 120 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif !a.filter.Check(authID[:]) {\n\t\t\treturn nil, ErrReplay\n\t\t}\n\n\t\treturn v.ticket, nil\n\t}\n\treturn nil, ErrNotFound\n}\n"
  },
  {
    "path": "proxy/vmess/aead/authid_test.go",
    "content": "package aead\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCreateAuthID(t *testing.T) {\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tauthid := CreateAuthID(key, time.Now().Unix())\n\n\tfmt.Println(key)\n\tfmt.Println(authid)\n}\n\nfunc TestCreateAuthIDAndDecode(t *testing.T) {\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tauthid := CreateAuthID(key, time.Now().Unix())\n\n\tfmt.Println(key)\n\tfmt.Println(authid)\n\n\tAuthDecoder := NewAuthIDDecoderHolder()\n\tvar keyw [16]byte\n\tcopy(keyw[:], key)\n\tAuthDecoder.AddUser(keyw, \"Demo User\")\n\tres, err := AuthDecoder.Match(authid)\n\tfmt.Println(res)\n\tfmt.Println(err)\n\tassert.Equal(t, \"Demo User\", res)\n\tassert.Nil(t, err)\n}\n\nfunc TestCreateAuthIDAndDecode2(t *testing.T) {\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tauthid := CreateAuthID(key, time.Now().Unix())\n\n\tfmt.Println(key)\n\tfmt.Println(authid)\n\n\tAuthDecoder := NewAuthIDDecoderHolder()\n\tvar keyw [16]byte\n\tcopy(keyw[:], key)\n\tAuthDecoder.AddUser(keyw, \"Demo User\")\n\tres, err := AuthDecoder.Match(authid)\n\tfmt.Println(res)\n\tfmt.Println(err)\n\tassert.Equal(t, \"Demo User\", res)\n\tassert.Nil(t, err)\n\n\tkey2 := KDF16([]byte(\"Demo Key for Auth ID Test2\"), \"Demo Path for Auth ID Test\")\n\tauthid2 := CreateAuthID(key2, time.Now().Unix())\n\n\tres2, err2 := AuthDecoder.Match(authid2)\n\tassert.EqualError(t, err2, \"user do not exist\")\n\tassert.Nil(t, res2)\n}\n\nfunc TestCreateAuthIDAndDecodeMassive(t *testing.T) {\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tauthid := CreateAuthID(key, time.Now().Unix())\n\n\tfmt.Println(key)\n\tfmt.Println(authid)\n\n\tAuthDecoder := NewAuthIDDecoderHolder()\n\tvar keyw [16]byte\n\tcopy(keyw[:], key)\n\tAuthDecoder.AddUser(keyw, \"Demo User\")\n\tres, err := AuthDecoder.Match(authid)\n\tfmt.Println(res)\n\tfmt.Println(err)\n\tassert.Equal(t, \"Demo User\", res)\n\tassert.Nil(t, err)\n\n\tfor i := 0; i <= 10000; i++ {\n\t\tkey2 := KDF16([]byte(\"Demo Key for Auth ID Test2\"), \"Demo Path for Auth ID Test\", strconv.Itoa(i))\n\t\tvar keyw2 [16]byte\n\t\tcopy(keyw2[:], key2)\n\t\tAuthDecoder.AddUser(keyw2, \"Demo User\"+strconv.Itoa(i))\n\t}\n\n\tauthid3 := CreateAuthID(key, time.Now().Unix())\n\n\tres2, err2 := AuthDecoder.Match(authid3)\n\tassert.Equal(t, \"Demo User\", res2)\n\tassert.Nil(t, err2)\n}\n\nfunc TestCreateAuthIDAndDecodeSuperMassive(t *testing.T) {\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tauthid := CreateAuthID(key, time.Now().Unix())\n\n\tfmt.Println(key)\n\tfmt.Println(authid)\n\n\tAuthDecoder := NewAuthIDDecoderHolder()\n\tvar keyw [16]byte\n\tcopy(keyw[:], key)\n\tAuthDecoder.AddUser(keyw, \"Demo User\")\n\tres, err := AuthDecoder.Match(authid)\n\tfmt.Println(res)\n\tfmt.Println(err)\n\tassert.Equal(t, \"Demo User\", res)\n\tassert.Nil(t, err)\n\n\tfor i := 0; i <= 1000000; i++ {\n\t\tkey2 := KDF16([]byte(\"Demo Key for Auth ID Test2\"), \"Demo Path for Auth ID Test\", strconv.Itoa(i))\n\t\tvar keyw2 [16]byte\n\t\tcopy(keyw2[:], key2)\n\t\tAuthDecoder.AddUser(keyw2, \"Demo User\"+strconv.Itoa(i))\n\t}\n\n\tauthid3 := CreateAuthID(key, time.Now().Unix())\n\n\tbefore := time.Now()\n\tres2, err2 := AuthDecoder.Match(authid3)\n\tafter := time.Now()\n\tassert.Equal(t, \"Demo User\", res2)\n\tassert.Nil(t, err2)\n\n\tfmt.Println(after.Sub(before).Seconds())\n}\n"
  },
  {
    "path": "proxy/vmess/aead/consts.go",
    "content": "package aead\n\nconst (\n\tKDFSaltConstAuthIDEncryptionKey             = \"AES Auth ID Encryption\"\n\tKDFSaltConstAEADRespHeaderLenKey            = \"AEAD Resp Header Len Key\"\n\tKDFSaltConstAEADRespHeaderLenIV             = \"AEAD Resp Header Len IV\"\n\tKDFSaltConstAEADRespHeaderPayloadKey        = \"AEAD Resp Header Key\"\n\tKDFSaltConstAEADRespHeaderPayloadIV         = \"AEAD Resp Header IV\"\n\tKDFSaltConstVMessAEADKDF                    = \"VMess AEAD KDF\"\n\tKDFSaltConstVMessHeaderPayloadAEADKey       = \"VMess Header AEAD Key\"\n\tKDFSaltConstVMessHeaderPayloadAEADIV        = \"VMess Header AEAD Nonce\"\n\tKDFSaltConstVMessHeaderPayloadLengthAEADKey = \"VMess Header AEAD Key_Length\"\n\tKDFSaltConstVMessHeaderPayloadLengthAEADIV  = \"VMess Header AEAD Nonce_Length\"\n)\n"
  },
  {
    "path": "proxy/vmess/aead/encrypt.go",
    "content": "package aead\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc SealVMessAEADHeader(key [16]byte, data []byte) []byte {\n\tgeneratedAuthID := CreateAuthID(key[:], time.Now().Unix())\n\n\tconnectionNonce := make([]byte, 8)\n\tif _, err := io.ReadFull(rand.Reader, connectionNonce); err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\taeadPayloadLengthSerializeBuffer := bytes.NewBuffer(nil)\n\n\theaderPayloadDataLen := uint16(len(data))\n\n\tcommon.Must(binary.Write(aeadPayloadLengthSerializeBuffer, binary.BigEndian, headerPayloadDataLen))\n\n\taeadPayloadLengthSerializedByte := aeadPayloadLengthSerializeBuffer.Bytes()\n\tvar payloadHeaderLengthAEADEncrypted []byte\n\n\t{\n\t\tpayloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADKey, string(generatedAuthID[:]), string(connectionNonce))\n\n\t\tpayloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]\n\n\t\tpayloadHeaderLengthAEADAESBlock, err := aes.NewCipher(payloadHeaderLengthAEADKey)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tpayloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderLengthAEADAESBlock)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tpayloadHeaderLengthAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderLengthAEADNonce, aeadPayloadLengthSerializedByte, generatedAuthID[:])\n\t}\n\n\tvar payloadHeaderAEADEncrypted []byte\n\n\t{\n\t\tpayloadHeaderAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadAEADKey, string(generatedAuthID[:]), string(connectionNonce))\n\n\t\tpayloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]\n\n\t\tpayloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tpayloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tpayloadHeaderAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])\n\t}\n\n\toutputBuffer := bytes.NewBuffer(nil)\n\n\tcommon.Must2(outputBuffer.Write(generatedAuthID[:]))               // 16\n\tcommon.Must2(outputBuffer.Write(payloadHeaderLengthAEADEncrypted)) // 2+16\n\tcommon.Must2(outputBuffer.Write(connectionNonce))                  // 8\n\tcommon.Must2(outputBuffer.Write(payloadHeaderAEADEncrypted))\n\n\treturn outputBuffer.Bytes()\n}\n\nfunc OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, bool, int, error) {\n\tvar payloadHeaderLengthAEADEncrypted [18]byte\n\tvar nonce [8]byte\n\n\tvar bytesRead int\n\n\tauthidCheckValueReadBytesCounts, err := io.ReadFull(data, payloadHeaderLengthAEADEncrypted[:])\n\tbytesRead += authidCheckValueReadBytesCounts\n\tif err != nil {\n\t\treturn nil, false, bytesRead, err\n\t}\n\n\tnonceReadBytesCounts, err := io.ReadFull(data, nonce[:])\n\tbytesRead += nonceReadBytesCounts\n\tif err != nil {\n\t\treturn nil, false, bytesRead, err\n\t}\n\n\t// Decrypt Length\n\n\tvar decryptedAEADHeaderLengthPayloadResult []byte\n\n\t{\n\t\tpayloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADKey, string(authid[:]), string(nonce[:]))\n\n\t\tpayloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(authid[:]), string(nonce[:]))[:12]\n\n\t\tpayloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderLengthAEADKey)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tpayloadHeaderLengthAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tdecryptedAEADHeaderLengthPayload, erropenAEAD := payloadHeaderLengthAEAD.Open(nil, payloadHeaderLengthAEADNonce, payloadHeaderLengthAEADEncrypted[:], authid[:])\n\n\t\tif erropenAEAD != nil {\n\t\t\treturn nil, true, bytesRead, erropenAEAD\n\t\t}\n\n\t\tdecryptedAEADHeaderLengthPayloadResult = decryptedAEADHeaderLengthPayload\n\t}\n\n\tvar length uint16\n\n\tcommon.Must(binary.Read(bytes.NewReader(decryptedAEADHeaderLengthPayloadResult), binary.BigEndian, &length))\n\n\tvar decryptedAEADHeaderPayloadR []byte\n\n\tvar payloadHeaderAEADEncryptedReadedBytesCounts int\n\n\t{\n\t\tpayloadHeaderAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadAEADKey, string(authid[:]), string(nonce[:]))\n\n\t\tpayloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(authid[:]), string(nonce[:]))[:12]\n\n\t\t// 16 == AEAD Tag size\n\t\tpayloadHeaderAEADEncrypted := make([]byte, length+16)\n\n\t\tpayloadHeaderAEADEncryptedReadedBytesCounts, err = io.ReadFull(data, payloadHeaderAEADEncrypted)\n\t\tbytesRead += payloadHeaderAEADEncryptedReadedBytesCounts\n\t\tif err != nil {\n\t\t\treturn nil, false, bytesRead, err\n\t\t}\n\n\t\tpayloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tpayloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\n\t\tdecryptedAEADHeaderPayload, erropenAEAD := payloadHeaderAEAD.Open(nil, payloadHeaderAEADNonce, payloadHeaderAEADEncrypted, authid[:])\n\n\t\tif erropenAEAD != nil {\n\t\t\treturn nil, true, bytesRead, erropenAEAD\n\t\t}\n\n\t\tdecryptedAEADHeaderPayloadR = decryptedAEADHeaderPayload\n\t}\n\n\treturn decryptedAEADHeaderPayloadR, false, bytesRead, nil\n}\n"
  },
  {
    "path": "proxy/vmess/aead/encrypt_test.go",
    "content": "package aead\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestOpenVMessAEADHeader(t *testing.T) {\n\tTestHeader := []byte(\"Test Header\")\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tvar keyw [16]byte\n\tcopy(keyw[:], key)\n\tsealed := SealVMessAEADHeader(keyw, TestHeader)\n\n\tAEADR := bytes.NewReader(sealed)\n\n\tvar authid [16]byte\n\n\tio.ReadFull(AEADR, authid[:])\n\n\tout, _, _, err := OpenVMessAEADHeader(keyw, authid, AEADR)\n\n\tfmt.Println(string(out))\n\tfmt.Println(err)\n}\n\nfunc TestOpenVMessAEADHeader2(t *testing.T) {\n\tTestHeader := []byte(\"Test Header\")\n\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\tvar keyw [16]byte\n\tcopy(keyw[:], key)\n\tsealed := SealVMessAEADHeader(keyw, TestHeader)\n\n\tAEADR := bytes.NewReader(sealed)\n\n\tvar authid [16]byte\n\n\tio.ReadFull(AEADR, authid[:])\n\n\tout, _, readen, err := OpenVMessAEADHeader(keyw, authid, AEADR)\n\tassert.Equal(t, len(sealed)-16-AEADR.Len(), readen)\n\tassert.Equal(t, string(TestHeader), string(out))\n\tassert.Nil(t, err)\n}\n\nfunc TestOpenVMessAEADHeader4(t *testing.T) {\n\tfor i := 0; i <= 60; i++ {\n\t\tTestHeader := []byte(\"Test Header\")\n\t\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\t\tvar keyw [16]byte\n\t\tcopy(keyw[:], key)\n\t\tsealed := SealVMessAEADHeader(keyw, TestHeader)\n\t\tvar sealedm [16]byte\n\t\tcopy(sealedm[:], sealed)\n\t\tsealed[i] ^= 0xff\n\t\tAEADR := bytes.NewReader(sealed)\n\n\t\tvar authid [16]byte\n\n\t\tio.ReadFull(AEADR, authid[:])\n\n\t\tout, drain, readen, err := OpenVMessAEADHeader(keyw, authid, AEADR)\n\t\tassert.Equal(t, len(sealed)-16-AEADR.Len(), readen)\n\t\tassert.Equal(t, true, drain)\n\t\tassert.NotNil(t, err)\n\t\tif err == nil {\n\t\t\tfmt.Println(\">\")\n\t\t}\n\t\tassert.Nil(t, out)\n\t}\n}\n\nfunc TestOpenVMessAEADHeader4Massive(t *testing.T) {\n\tfor j := 0; j < 1000; j++ {\n\t\tfor i := 0; i <= 60; i++ {\n\t\t\tTestHeader := []byte(\"Test Header\")\n\t\t\tkey := KDF16([]byte(\"Demo Key for Auth ID Test\"), \"Demo Path for Auth ID Test\")\n\t\t\tvar keyw [16]byte\n\t\t\tcopy(keyw[:], key)\n\t\t\tsealed := SealVMessAEADHeader(keyw, TestHeader)\n\t\t\tvar sealedm [16]byte\n\t\t\tcopy(sealedm[:], sealed)\n\t\t\tsealed[i] ^= 0xff\n\t\t\tAEADR := bytes.NewReader(sealed)\n\n\t\t\tvar authid [16]byte\n\n\t\t\tio.ReadFull(AEADR, authid[:])\n\n\t\t\tout, drain, readen, err := OpenVMessAEADHeader(keyw, authid, AEADR)\n\t\t\tassert.Equal(t, len(sealed)-16-AEADR.Len(), readen)\n\t\t\tassert.Equal(t, true, drain)\n\t\t\tassert.NotNil(t, err)\n\t\t\tif err == nil {\n\t\t\t\tfmt.Println(\">\")\n\t\t\t}\n\t\t\tassert.Nil(t, out)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/aead/kdf.go",
    "content": "package aead\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"hash\"\n)\n\nfunc KDF(key []byte, path ...string) []byte {\n\thmacCreator := &hMacCreator{value: []byte(KDFSaltConstVMessAEADKDF)}\n\tfor _, v := range path {\n\t\thmacCreator = &hMacCreator{value: []byte(v), parent: hmacCreator}\n\t}\n\thmacf := hmacCreator.Create()\n\thmacf.Write(key)\n\treturn hmacf.Sum(nil)\n}\n\ntype hMacCreator struct {\n\tparent *hMacCreator\n\tvalue  []byte\n}\n\nfunc (h *hMacCreator) Create() hash.Hash {\n\tif h.parent == nil {\n\t\treturn hmac.New(sha256.New, h.value)\n\t}\n\treturn hmac.New(h.parent.Create, h.value)\n}\n\nfunc KDF16(key []byte, path ...string) []byte {\n\tr := KDF(key, path...)\n\treturn r[:16]\n}\n"
  },
  {
    "path": "proxy/vmess/aead/kdf_test.go",
    "content": "package aead\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestKDFValue(t *testing.T) {\n\tGeneratedKey := KDF([]byte(\"Demo Key for KDF Value Test\"), \"Demo Path for KDF Value Test\", \"Demo Path for KDF Value Test2\", \"Demo Path for KDF Value Test3\")\n\tfmt.Println(hex.EncodeToString(GeneratedKey))\n\tassert.Equal(t, \"53e9d7e1bd7bd25022b71ead07d8a596efc8a845c7888652fd684b4903dc8892\", hex.EncodeToString(GeneratedKey), \"Should generate expected KDF Value\")\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/auth.go",
    "content": "package encoding\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/binary\"\n\t\"hash/fnv\"\n\n\t\"golang.org/x/crypto/sha3\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\n// Authenticate authenticates a byte array using Fnv hash.\nfunc Authenticate(b []byte) uint32 {\n\tfnv1hash := fnv.New32a()\n\tcommon.Must2(fnv1hash.Write(b))\n\treturn fnv1hash.Sum32()\n}\n\ntype NoOpAuthenticator struct{}\n\nfunc (NoOpAuthenticator) NonceSize() int {\n\treturn 0\n}\n\nfunc (NoOpAuthenticator) Overhead() int {\n\treturn 0\n}\n\n// Seal implements AEAD.Seal().\nfunc (NoOpAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\treturn append(dst[:0], plaintext...)\n}\n\n// Open implements AEAD.Open().\nfunc (NoOpAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\treturn append(dst[:0], ciphertext...), nil\n}\n\n// FnvAuthenticator is an AEAD based on Fnv hash.\ntype FnvAuthenticator struct{}\n\n// NonceSize implements AEAD.NonceSize().\nfunc (*FnvAuthenticator) NonceSize() int {\n\treturn 0\n}\n\n// Overhead impelements AEAD.Overhead().\nfunc (*FnvAuthenticator) Overhead() int {\n\treturn 4\n}\n\n// Seal implements AEAD.Seal().\nfunc (*FnvAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\tdst = append(dst, 0, 0, 0, 0)\n\tbinary.BigEndian.PutUint32(dst, Authenticate(plaintext))\n\treturn append(dst, plaintext...)\n}\n\n// Open implements AEAD.Open().\nfunc (*FnvAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tif binary.BigEndian.Uint32(ciphertext[:4]) != Authenticate(ciphertext[4:]) {\n\t\treturn dst, newError(\"invalid authentication\")\n\t}\n\treturn append(dst, ciphertext[4:]...), nil\n}\n\n// GenerateChacha20Poly1305Key generates a 32-byte key from a given 16-byte array.\nfunc GenerateChacha20Poly1305Key(b []byte) []byte {\n\tkey := make([]byte, 32)\n\tt := md5.Sum(b)\n\tcopy(key, t[:])\n\tt = md5.Sum(key[:16])\n\tcopy(key[16:], t[:])\n\treturn key\n}\n\ntype ShakeSizeParser struct {\n\tshake  sha3.ShakeHash\n\tbuffer [2]byte\n}\n\nfunc NewShakeSizeParser(nonce []byte) *ShakeSizeParser {\n\tshake := sha3.NewShake128()\n\tcommon.Must2(shake.Write(nonce))\n\treturn &ShakeSizeParser{\n\t\tshake: shake,\n\t}\n}\n\nfunc (*ShakeSizeParser) SizeBytes() int32 {\n\treturn 2\n}\n\nfunc (s *ShakeSizeParser) next() uint16 {\n\tcommon.Must2(s.shake.Read(s.buffer[:]))\n\treturn binary.BigEndian.Uint16(s.buffer[:])\n}\n\nfunc (s *ShakeSizeParser) Decode(b []byte) (uint16, error) {\n\tmask := s.next()\n\tsize := binary.BigEndian.Uint16(b)\n\treturn mask ^ size, nil\n}\n\nfunc (s *ShakeSizeParser) Encode(size uint16, b []byte) []byte {\n\tmask := s.next()\n\tbinary.BigEndian.PutUint16(b, mask^size)\n\treturn b[:2]\n}\n\nfunc (s *ShakeSizeParser) NextPaddingLen() uint16 {\n\treturn s.next() % 64\n}\n\nfunc (s *ShakeSizeParser) MaxPaddingLen() uint16 {\n\treturn 64\n}\n\ntype AEADSizeParser struct {\n\tcrypto.AEADChunkSizeParser\n}\n\nfunc NewAEADSizeParser(auth *crypto.AEADAuthenticator) *AEADSizeParser {\n\treturn &AEADSizeParser{crypto.AEADChunkSizeParser{Auth: auth}}\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/auth_test.go",
    "content": "package encoding_test\n\nimport (\n\t\"crypto/rand\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/vmess/encoding\"\n)\n\nfunc TestFnvAuth(t *testing.T) {\n\tfnvAuth := new(FnvAuthenticator)\n\n\texpectedText := make([]byte, 256)\n\t_, err := rand.Read(expectedText)\n\tcommon.Must(err)\n\n\tbuffer := make([]byte, 512)\n\tb := fnvAuth.Seal(buffer[:0], nil, expectedText, nil)\n\tb, err = fnvAuth.Open(buffer[:0], nil, b, nil)\n\tcommon.Must(err)\n\tif r := cmp.Diff(b, expectedText); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/client.go",
    "content": "package encoding\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/md5\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/binary\"\n\t\"hash\"\n\t\"hash/fnv\"\n\t\"io\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/bitmask\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/drain\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\tvmessaead \"github.com/v2fly/v2ray-core/v5/proxy/vmess/aead\"\n)\n\nfunc hashTimestamp(h hash.Hash, t protocol.Timestamp) []byte {\n\tcommon.Must2(serial.WriteUint64(h, uint64(t)))\n\tcommon.Must2(serial.WriteUint64(h, uint64(t)))\n\tcommon.Must2(serial.WriteUint64(h, uint64(t)))\n\tcommon.Must2(serial.WriteUint64(h, uint64(t)))\n\treturn h.Sum(nil)\n}\n\n// ClientSession stores connection session info for VMess client.\ntype ClientSession struct {\n\tisAEAD          bool\n\tidHash          protocol.IDHash\n\trequestBodyKey  [16]byte\n\trequestBodyIV   [16]byte\n\tresponseBodyKey [16]byte\n\tresponseBodyIV  [16]byte\n\tresponseReader  io.Reader\n\tresponseHeader  byte\n\n\treadDrainer drain.Drainer\n}\n\n// NewClientSession creates a new ClientSession.\nfunc NewClientSession(ctx context.Context, isAEAD bool, idHash protocol.IDHash, behaviorSeed int64) *ClientSession {\n\tsession := &ClientSession{\n\t\tisAEAD: isAEAD,\n\t\tidHash: idHash,\n\t}\n\n\trandomBytes := make([]byte, 33) // 16 + 16 + 1\n\tcommon.Must2(rand.Read(randomBytes))\n\tcopy(session.requestBodyKey[:], randomBytes[:16])\n\tcopy(session.requestBodyIV[:], randomBytes[16:32])\n\tsession.responseHeader = randomBytes[32]\n\n\tif !session.isAEAD {\n\t\tsession.responseBodyKey = md5.Sum(session.requestBodyKey[:])\n\t\tsession.responseBodyIV = md5.Sum(session.requestBodyIV[:])\n\t} else {\n\t\tBodyKey := sha256.Sum256(session.requestBodyKey[:])\n\t\tcopy(session.responseBodyKey[:], BodyKey[:16])\n\t\tBodyIV := sha256.Sum256(session.requestBodyIV[:])\n\t\tcopy(session.responseBodyIV[:], BodyIV[:16])\n\t}\n\t{\n\t\tvar err error\n\t\tsession.readDrainer, err = drain.NewBehaviorSeedLimitedDrainer(behaviorSeed, 18, 3266, 64)\n\t\tif err != nil {\n\t\t\tnewError(\"unable to initialize drainer\").Base(err).WriteToLog()\n\t\t\tsession.readDrainer = drain.NewNopDrainer()\n\t\t}\n\t}\n\n\treturn session\n}\n\nfunc (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) error {\n\ttimestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()\n\taccount := header.User.Account.(*vmess.MemoryAccount)\n\tif !c.isAEAD {\n\t\tidHash := c.idHash(account.AnyValidID().Bytes())\n\t\tcommon.Must2(serial.WriteUint64(idHash, uint64(timestamp)))\n\t\tcommon.Must2(writer.Write(idHash.Sum(nil)))\n\t}\n\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\n\tcommon.Must(buffer.WriteByte(Version))\n\tcommon.Must2(buffer.Write(c.requestBodyIV[:]))\n\tcommon.Must2(buffer.Write(c.requestBodyKey[:]))\n\tcommon.Must(buffer.WriteByte(c.responseHeader))\n\tcommon.Must(buffer.WriteByte(byte(header.Option)))\n\n\tpaddingLen := dice.RollWith(16, rand.Reader)\n\tsecurity := byte(paddingLen<<4) | byte(header.Security)\n\tcommon.Must2(buffer.Write([]byte{security, byte(0), byte(header.Command)}))\n\n\tif header.Command != protocol.RequestCommandMux {\n\t\tif err := addrParser.WriteAddressPort(buffer, header.Address, header.Port); err != nil {\n\t\t\treturn newError(\"failed to writer address and port\").Base(err)\n\t\t}\n\t}\n\n\tif paddingLen > 0 {\n\t\tcommon.Must2(buffer.ReadFullFrom(rand.Reader, int32(paddingLen)))\n\t}\n\n\t{\n\t\tfnv1a := fnv.New32a()\n\t\tcommon.Must2(fnv1a.Write(buffer.Bytes()))\n\t\thashBytes := buffer.Extend(int32(fnv1a.Size()))\n\t\tfnv1a.Sum(hashBytes[:0])\n\t}\n\n\tif !c.isAEAD {\n\t\tiv := hashTimestamp(md5.New(), timestamp)\n\t\taesStream := crypto.NewAesEncryptionStream(account.ID.CmdKey(), iv)\n\t\taesStream.XORKeyStream(buffer.Bytes(), buffer.Bytes())\n\t\tcommon.Must2(writer.Write(buffer.Bytes()))\n\t} else {\n\t\tvar fixedLengthCmdKey [16]byte\n\t\tcopy(fixedLengthCmdKey[:], account.ID.CmdKey())\n\t\tvmessout := vmessaead.SealVMessAEADHeader(fixedLengthCmdKey, buffer.Bytes())\n\t\tcommon.Must2(io.Copy(writer, bytes.NewReader(vmessout)))\n\t}\n\n\treturn nil\n}\n\nfunc (c *ClientSession) EncodeRequestBody(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {\n\tvar sizeParser crypto.ChunkSizeEncoder = crypto.PlainChunkSizeParser{}\n\tif request.Option.Has(protocol.RequestOptionChunkMasking) {\n\t\tsizeParser = NewShakeSizeParser(c.requestBodyIV[:])\n\t}\n\tvar padding crypto.PaddingLengthGenerator\n\tif request.Option.Has(protocol.RequestOptionGlobalPadding) {\n\t\tvar ok bool\n\t\tpadding, ok = sizeParser.(crypto.PaddingLengthGenerator)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"invalid option: RequestOptionGlobalPadding\")\n\t\t}\n\t}\n\n\tswitch request.Security {\n\tcase protocol.SecurityType_NONE:\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tif request.Command.TransferType() == protocol.TransferTypeStream {\n\t\t\t\treturn crypto.NewChunkStreamWriter(sizeParser, writer), nil\n\t\t\t}\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(NoOpAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, writer, protocol.TransferTypePacket, padding), nil\n\t\t}\n\n\t\treturn buf.NewWriter(writer), nil\n\tcase protocol.SecurityType_LEGACY:\n\t\taesStream := crypto.NewAesEncryptionStream(c.requestBodyKey[:], c.requestBodyIV[:])\n\t\tcryptionWriter := crypto.NewCryptionWriter(aesStream, writer)\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(FnvAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, cryptionWriter, request.Command.TransferType(), padding), nil\n\t\t}\n\n\t\treturn &buf.SequentialWriter{Writer: cryptionWriter}, nil\n\tcase protocol.SecurityType_AES128_GCM:\n\t\taead := crypto.NewAesGcm(c.requestBodyKey[:])\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(c.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(c.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD := crypto.NewAesGcm(AuthenticatedLengthKey)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(c.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, writer, request.Command.TransferType(), padding), nil\n\tcase protocol.SecurityType_CHACHA20_POLY1305:\n\t\taead, err := chacha20poly1305.New(GenerateChacha20Poly1305Key(c.requestBodyKey[:]))\n\t\tcommon.Must(err)\n\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(c.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(c.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD, err := chacha20poly1305.New(GenerateChacha20Poly1305Key(AuthenticatedLengthKey))\n\t\t\tcommon.Must(err)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(c.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, writer, request.Command.TransferType(), padding), nil\n\tdefault:\n\t\treturn nil, newError(\"invalid option: Security\")\n\t}\n}\n\nfunc (c *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.ResponseHeader, error) {\n\tif !c.isAEAD {\n\t\taesStream := crypto.NewAesDecryptionStream(c.responseBodyKey[:], c.responseBodyIV[:])\n\t\tc.responseReader = crypto.NewCryptionReader(aesStream, reader)\n\t} else {\n\t\taeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)\n\t\taeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]\n\n\t\taeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)\n\t\taeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)\n\n\t\tvar aeadEncryptedResponseHeaderLength [18]byte\n\t\tvar decryptedResponseHeaderLength int\n\t\tvar decryptedResponseHeaderLengthBinaryDeserializeBuffer uint16\n\n\t\tif n, err := io.ReadFull(reader, aeadEncryptedResponseHeaderLength[:]); err != nil {\n\t\t\tc.readDrainer.AcknowledgeReceive(n)\n\t\t\treturn nil, drain.WithError(c.readDrainer, reader, newError(\"Unable to Read Header Len\").Base(err))\n\t\t} else { // nolint: revive\n\t\t\tc.readDrainer.AcknowledgeReceive(n)\n\t\t}\n\t\tif decryptedResponseHeaderLengthBinaryBuffer, err := aeadResponseHeaderLengthEncryptionAEAD.Open(nil, aeadResponseHeaderLengthEncryptionIV, aeadEncryptedResponseHeaderLength[:], nil); err != nil {\n\t\t\treturn nil, drain.WithError(c.readDrainer, reader, newError(\"Failed To Decrypt Length\").Base(err))\n\t\t} else { // nolint: revive\n\t\t\tcommon.Must(binary.Read(bytes.NewReader(decryptedResponseHeaderLengthBinaryBuffer), binary.BigEndian, &decryptedResponseHeaderLengthBinaryDeserializeBuffer))\n\t\t\tdecryptedResponseHeaderLength = int(decryptedResponseHeaderLengthBinaryDeserializeBuffer)\n\t\t}\n\n\t\taeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(c.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)\n\t\taeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(c.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]\n\n\t\taeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)\n\t\taeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)\n\n\t\tencryptedResponseHeaderBuffer := make([]byte, decryptedResponseHeaderLength+16)\n\n\t\tif n, err := io.ReadFull(reader, encryptedResponseHeaderBuffer); err != nil {\n\t\t\tc.readDrainer.AcknowledgeReceive(n)\n\t\t\treturn nil, drain.WithError(c.readDrainer, reader, newError(\"Unable to Read Header Data\").Base(err))\n\t\t} else { // nolint: revive\n\t\t\tc.readDrainer.AcknowledgeReceive(n)\n\t\t}\n\n\t\tif decryptedResponseHeaderBuffer, err := aeadResponseHeaderPayloadEncryptionAEAD.Open(nil, aeadResponseHeaderPayloadEncryptionIV, encryptedResponseHeaderBuffer, nil); err != nil {\n\t\t\treturn nil, drain.WithError(c.readDrainer, reader, newError(\"Failed To Decrypt Payload\").Base(err))\n\t\t} else { // nolint: revive\n\t\t\tc.responseReader = bytes.NewReader(decryptedResponseHeaderBuffer)\n\t\t}\n\t}\n\n\tbuffer := buf.StackNew()\n\tdefer buffer.Release()\n\n\tif _, err := buffer.ReadFullFrom(c.responseReader, 4); err != nil {\n\t\treturn nil, newError(\"failed to read response header\").Base(err).AtWarning()\n\t}\n\n\tif buffer.Byte(0) != c.responseHeader {\n\t\treturn nil, newError(\"unexpected response header. Expecting \", int(c.responseHeader), \" but actually \", int(buffer.Byte(0)))\n\t}\n\n\theader := &protocol.ResponseHeader{\n\t\tOption: bitmask.Byte(buffer.Byte(1)),\n\t}\n\n\tif buffer.Byte(2) != 0 {\n\t\tcmdID := buffer.Byte(2)\n\t\tdataLen := int32(buffer.Byte(3))\n\n\t\tbuffer.Clear()\n\t\tif _, err := buffer.ReadFullFrom(c.responseReader, dataLen); err != nil {\n\t\t\treturn nil, newError(\"failed to read response command\").Base(err)\n\t\t}\n\t\tcommand, err := UnmarshalCommand(cmdID, buffer.Bytes())\n\t\tif err == nil {\n\t\t\theader.Command = command\n\t\t}\n\t}\n\tif c.isAEAD {\n\t\taesStream := crypto.NewAesDecryptionStream(c.responseBodyKey[:], c.responseBodyIV[:])\n\t\tc.responseReader = crypto.NewCryptionReader(aesStream, reader)\n\t}\n\treturn header, nil\n}\n\nfunc (c *ClientSession) DecodeResponseBody(request *protocol.RequestHeader, reader io.Reader) (buf.Reader, error) {\n\tvar sizeParser crypto.ChunkSizeDecoder = crypto.PlainChunkSizeParser{}\n\tif request.Option.Has(protocol.RequestOptionChunkMasking) {\n\t\tsizeParser = NewShakeSizeParser(c.responseBodyIV[:])\n\t}\n\tvar padding crypto.PaddingLengthGenerator\n\tif request.Option.Has(protocol.RequestOptionGlobalPadding) {\n\t\tvar ok bool\n\t\tpadding, ok = sizeParser.(crypto.PaddingLengthGenerator)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"invalid option: RequestOptionGlobalPadding\")\n\t\t}\n\t}\n\n\tswitch request.Security {\n\tcase protocol.SecurityType_NONE:\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tif request.Command.TransferType() == protocol.TransferTypeStream {\n\t\t\t\treturn crypto.NewChunkStreamReader(sizeParser, reader), nil\n\t\t\t}\n\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(NoOpAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\n\t\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, reader, protocol.TransferTypePacket, padding), nil\n\t\t}\n\n\t\treturn buf.NewReader(reader), nil\n\tcase protocol.SecurityType_LEGACY:\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(FnvAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, c.responseReader, request.Command.TransferType(), padding), nil\n\t\t}\n\n\t\treturn buf.NewReader(c.responseReader), nil\n\tcase protocol.SecurityType_AES128_GCM:\n\t\taead := crypto.NewAesGcm(c.responseBodyKey[:])\n\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(c.responseBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(c.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD := crypto.NewAesGcm(AuthenticatedLengthKey)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(c.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, reader, request.Command.TransferType(), padding), nil\n\tcase protocol.SecurityType_CHACHA20_POLY1305:\n\t\taead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(c.responseBodyKey[:]))\n\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(c.responseBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(c.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD, err := chacha20poly1305.New(GenerateChacha20Poly1305Key(AuthenticatedLengthKey))\n\t\t\tcommon.Must(err)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(c.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, reader, request.Command.TransferType(), padding), nil\n\tdefault:\n\t\treturn nil, newError(\"invalid option: Security\")\n\t}\n}\n\nfunc GenerateChunkNonce(nonce []byte, size uint32) crypto.BytesGenerator {\n\tc := append([]byte(nil), nonce...)\n\tcount := uint16(0)\n\treturn func() []byte {\n\t\tbinary.BigEndian.PutUint16(c, count)\n\t\tcount++\n\t\treturn c[:size]\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/commands.go",
    "content": "package encoding\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\nvar (\n\tErrCommandTypeMismatch = newError(\"Command type mismatch.\")\n\tErrUnknownCommand      = newError(\"Unknown command.\")\n\tErrCommandTooLarge     = newError(\"Command too large.\")\n\tErrInsufficientLength  = newError(\"Insufficient length.\")\n\tErrInvalidAuth         = newError(\"Invalid auth.\")\n)\n\nfunc MarshalCommand(command interface{}, writer io.Writer) error {\n\tif command == nil {\n\t\treturn ErrUnknownCommand\n\t}\n\n\tvar cmdID byte\n\tvar factory CommandFactory\n\tswitch command.(type) {\n\tcase *protocol.CommandSwitchAccount:\n\t\tfactory = new(CommandSwitchAccountFactory)\n\t\tcmdID = 1\n\tdefault:\n\t\treturn ErrUnknownCommand\n\t}\n\n\tbuffer := buf.New()\n\tdefer buffer.Release()\n\n\terr := factory.Marshal(command, buffer)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tauth := Authenticate(buffer.Bytes())\n\tlength := buffer.Len() + 4\n\tif length > 255 {\n\t\treturn ErrCommandTooLarge\n\t}\n\n\tcommon.Must2(writer.Write([]byte{cmdID, byte(length), byte(auth >> 24), byte(auth >> 16), byte(auth >> 8), byte(auth)}))\n\tcommon.Must2(writer.Write(buffer.Bytes()))\n\treturn nil\n}\n\nfunc UnmarshalCommand(cmdID byte, data []byte) (protocol.ResponseCommand, error) {\n\tif len(data) <= 4 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\texpectedAuth := Authenticate(data[4:])\n\tactualAuth := binary.BigEndian.Uint32(data[:4])\n\tif expectedAuth != actualAuth {\n\t\treturn nil, ErrInvalidAuth\n\t}\n\n\tvar factory CommandFactory\n\tswitch cmdID {\n\tcase 1:\n\t\tfactory = new(CommandSwitchAccountFactory)\n\tdefault:\n\t\treturn nil, ErrUnknownCommand\n\t}\n\treturn factory.Unmarshal(data[4:])\n}\n\ntype CommandFactory interface {\n\tMarshal(command interface{}, writer io.Writer) error\n\tUnmarshal(data []byte) (interface{}, error)\n}\n\ntype CommandSwitchAccountFactory struct{}\n\nfunc (f *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.Writer) error {\n\tcmd, ok := command.(*protocol.CommandSwitchAccount)\n\tif !ok {\n\t\treturn ErrCommandTypeMismatch\n\t}\n\n\thostStr := \"\"\n\tif cmd.Host != nil {\n\t\thostStr = cmd.Host.String()\n\t}\n\tcommon.Must2(writer.Write([]byte{byte(len(hostStr))}))\n\n\tif len(hostStr) > 0 {\n\t\tcommon.Must2(writer.Write([]byte(hostStr)))\n\t}\n\n\tcommon.Must2(serial.WriteUint16(writer, cmd.Port.Value()))\n\n\tidBytes := cmd.ID.Bytes()\n\tcommon.Must2(writer.Write(idBytes))\n\tcommon.Must2(serial.WriteUint16(writer, cmd.AlterIds))\n\tcommon.Must2(writer.Write([]byte{byte(cmd.Level)}))\n\n\tcommon.Must2(writer.Write([]byte{cmd.ValidMin}))\n\treturn nil\n}\n\nfunc (f *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {\n\tcmd := new(protocol.CommandSwitchAccount)\n\tif len(data) == 0 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tlenHost := int(data[0])\n\tif len(data) < lenHost+1 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tif lenHost > 0 {\n\t\tcmd.Host = net.ParseAddress(string(data[1 : 1+lenHost]))\n\t}\n\tportStart := 1 + lenHost\n\tif len(data) < portStart+2 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tcmd.Port = net.PortFromBytes(data[portStart : portStart+2])\n\tidStart := portStart + 2\n\tif len(data) < idStart+16 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tcmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])\n\talterIDStart := idStart + 16\n\tif len(data) < alterIDStart+2 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tcmd.AlterIds = binary.BigEndian.Uint16(data[alterIDStart : alterIDStart+2])\n\tlevelStart := alterIDStart + 2\n\tif len(data) < levelStart+1 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tcmd.Level = uint32(data[levelStart])\n\ttimeStart := levelStart + 1\n\tif len(data) < timeStart+1 {\n\t\treturn nil, ErrInsufficientLength\n\t}\n\tcmd.ValidMin = data[timeStart]\n\treturn cmd, nil\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/commands_test.go",
    "content": "package encoding_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/vmess/encoding\"\n)\n\nfunc TestSwitchAccount(t *testing.T) {\n\tsa := &protocol.CommandSwitchAccount{\n\t\tPort:     1234,\n\t\tID:       uuid.New(),\n\t\tAlterIds: 1024,\n\t\tLevel:    128,\n\t\tValidMin: 16,\n\t}\n\n\tbuffer := buf.New()\n\tcommon.Must(MarshalCommand(sa, buffer))\n\n\tcmd, err := UnmarshalCommand(1, buffer.BytesFrom(2))\n\tcommon.Must(err)\n\n\tsa2, ok := cmd.(*protocol.CommandSwitchAccount)\n\tif !ok {\n\t\tt.Fatal(\"failed to convert command to CommandSwitchAccount\")\n\t}\n\tif r := cmp.Diff(sa2, sa); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestSwitchAccountBugOffByOne(t *testing.T) {\n\tsa := &protocol.CommandSwitchAccount{\n\t\tPort:     1234,\n\t\tID:       uuid.New(),\n\t\tAlterIds: 1024,\n\t\tLevel:    128,\n\t\tValidMin: 16,\n\t}\n\n\tbuffer := buf.New()\n\tcsaf := CommandSwitchAccountFactory{}\n\tcommon.Must(csaf.Marshal(sa, buffer))\n\n\tPayload := buffer.Bytes()\n\n\tcmd, err := csaf.Unmarshal(Payload[:len(Payload)-1])\n\tassert.Error(t, err)\n\tassert.Nil(t, cmd)\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/encoding.go",
    "content": "package encoding\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst (\n\tVersion = byte(1)\n)\n\nvar addrParser = protocol.NewAddressParser(\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeIPv4), net.AddressFamilyIPv4),\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeDomain), net.AddressFamilyDomain),\n\tprotocol.AddressFamilyByte(byte(protocol.AddressTypeIPv6), net.AddressFamilyIPv6),\n\tprotocol.PortThenAddress(),\n)\n"
  },
  {
    "path": "proxy/vmess/encoding/encoding_test.go",
    "content": "package encoding_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/vmess/encoding\"\n)\n\nfunc toAccount(a *vmess.Account) protocol.Account {\n\taccount, err := a.AsAccount()\n\tcommon.Must(err)\n\treturn account\n}\n\nfunc TestRequestSerialization(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tLevel: 0,\n\t\tEmail: \"test@v2fly.org\",\n\t}\n\tid := uuid.New()\n\taccount := &vmess.Account{\n\t\tId:      id.String(),\n\t\tAlterId: 0,\n\t}\n\tuser.Account = toAccount(account)\n\n\texpectedRequest := &protocol.RequestHeader{\n\t\tVersion:  1,\n\t\tUser:     user,\n\t\tCommand:  protocol.RequestCommandTCP,\n\t\tAddress:  net.DomainAddress(\"www.v2fly.org\"),\n\t\tPort:     net.Port(443),\n\t\tSecurity: protocol.SecurityType_AES128_GCM,\n\t}\n\n\tbuffer := buf.New()\n\tclient := NewClientSession(context.TODO(), true, protocol.DefaultIDHash, 0)\n\tcommon.Must(client.EncodeRequestHeader(expectedRequest, buffer))\n\n\tbuffer2 := buf.New()\n\tbuffer2.Write(buffer.Bytes())\n\n\tsessionHistory := NewSessionHistory()\n\tdefer common.Close(sessionHistory)\n\n\tuserValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)\n\tuserValidator.Add(user)\n\tdefer common.Close(userValidator)\n\n\tserver := NewServerSession(userValidator, sessionHistory)\n\tactualRequest, err := server.DecodeRequestHeader(buffer)\n\tcommon.Must(err)\n\n\tif r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\t_, err = server.DecodeRequestHeader(buffer2)\n\t// anti replay attack\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestInvalidRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tLevel: 0,\n\t\tEmail: \"test@v2fly.org\",\n\t}\n\tid := uuid.New()\n\taccount := &vmess.Account{\n\t\tId:      id.String(),\n\t\tAlterId: 0,\n\t}\n\tuser.Account = toAccount(account)\n\n\texpectedRequest := &protocol.RequestHeader{\n\t\tVersion:  1,\n\t\tUser:     user,\n\t\tCommand:  protocol.RequestCommand(100),\n\t\tAddress:  net.DomainAddress(\"www.v2fly.org\"),\n\t\tPort:     net.Port(443),\n\t\tSecurity: protocol.SecurityType_AES128_GCM,\n\t}\n\n\tbuffer := buf.New()\n\tclient := NewClientSession(context.TODO(), true, protocol.DefaultIDHash, 0)\n\tcommon.Must(client.EncodeRequestHeader(expectedRequest, buffer))\n\n\tbuffer2 := buf.New()\n\tbuffer2.Write(buffer.Bytes())\n\n\tsessionHistory := NewSessionHistory()\n\tdefer common.Close(sessionHistory)\n\n\tuserValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)\n\tuserValidator.Add(user)\n\tdefer common.Close(userValidator)\n\n\tserver := NewServerSession(userValidator, sessionHistory)\n\t_, err := server.DecodeRequestHeader(buffer)\n\tif err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestMuxRequest(t *testing.T) {\n\tuser := &protocol.MemoryUser{\n\t\tLevel: 0,\n\t\tEmail: \"test@v2fly.org\",\n\t}\n\tid := uuid.New()\n\taccount := &vmess.Account{\n\t\tId:      id.String(),\n\t\tAlterId: 0,\n\t}\n\tuser.Account = toAccount(account)\n\n\texpectedRequest := &protocol.RequestHeader{\n\t\tVersion:  1,\n\t\tUser:     user,\n\t\tCommand:  protocol.RequestCommandMux,\n\t\tSecurity: protocol.SecurityType_AES128_GCM,\n\t\tAddress:  net.DomainAddress(\"v1.mux.cool\"),\n\t}\n\n\tbuffer := buf.New()\n\tclient := NewClientSession(context.TODO(), true, protocol.DefaultIDHash, 0)\n\tcommon.Must(client.EncodeRequestHeader(expectedRequest, buffer))\n\n\tbuffer2 := buf.New()\n\tbuffer2.Write(buffer.Bytes())\n\n\tsessionHistory := NewSessionHistory()\n\tdefer common.Close(sessionHistory)\n\n\tuserValidator := vmess.NewTimedUserValidator(protocol.DefaultIDHash)\n\tuserValidator.Add(user)\n\tdefer common.Close(userValidator)\n\n\tserver := NewServerSession(userValidator, sessionHistory)\n\tactualRequest, err := server.DecodeRequestHeader(buffer)\n\tcommon.Must(err)\n\n\tif r := cmp.Diff(actualRequest, expectedRequest, cmp.AllowUnexported(protocol.ID{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/errors.generated.go",
    "content": "package encoding\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vmess/encoding/server.go",
    "content": "package encoding\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/md5\"\n\t\"crypto/sha256\"\n\t\"encoding/binary\"\n\t\"hash/fnv\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/bitmask\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/common/drain\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\tvmessaead \"github.com/v2fly/v2ray-core/v5/proxy/vmess/aead\"\n)\n\ntype sessionID struct {\n\tuser  [16]byte\n\tkey   [16]byte\n\tnonce [16]byte\n}\n\n// SessionHistory keeps track of historical session ids, to prevent replay attacks.\ntype SessionHistory struct {\n\tsync.RWMutex\n\tcache map[sessionID]time.Time\n\ttask  *task.Periodic\n}\n\n// NewSessionHistory creates a new SessionHistory object.\nfunc NewSessionHistory() *SessionHistory {\n\th := &SessionHistory{\n\t\tcache: make(map[sessionID]time.Time, 128),\n\t}\n\th.task = &task.Periodic{\n\t\tInterval: time.Second * 30,\n\t\tExecute:  h.removeExpiredEntries,\n\t}\n\treturn h\n}\n\n// Close implements common.Closable.\nfunc (h *SessionHistory) Close() error {\n\treturn h.task.Close()\n}\n\nfunc (h *SessionHistory) addIfNotExits(session sessionID) bool {\n\th.Lock()\n\n\tif expire, found := h.cache[session]; found && expire.After(time.Now()) {\n\t\th.Unlock()\n\t\treturn false\n\t}\n\n\th.cache[session] = time.Now().Add(time.Minute * 3)\n\th.Unlock()\n\tcommon.Must(h.task.Start())\n\treturn true\n}\n\nfunc (h *SessionHistory) removeExpiredEntries() error {\n\tnow := time.Now()\n\n\th.Lock()\n\tdefer h.Unlock()\n\n\tif len(h.cache) == 0 {\n\t\treturn newError(\"nothing to do\")\n\t}\n\n\tfor session, expire := range h.cache {\n\t\tif expire.Before(now) {\n\t\t\tdelete(h.cache, session)\n\t\t}\n\t}\n\n\tif len(h.cache) == 0 {\n\t\th.cache = make(map[sessionID]time.Time, 128)\n\t}\n\n\treturn nil\n}\n\n// ServerSession keeps information for a session in VMess server.\ntype ServerSession struct {\n\tuserValidator   *vmess.TimedUserValidator\n\tsessionHistory  *SessionHistory\n\trequestBodyKey  [16]byte\n\trequestBodyIV   [16]byte\n\tresponseBodyKey [16]byte\n\tresponseBodyIV  [16]byte\n\tresponseWriter  io.Writer\n\tresponseHeader  byte\n\n\tisAEADRequest bool\n\n\tisAEADForced bool\n}\n\n// NewServerSession creates a new ServerSession, using the given UserValidator.\n// The ServerSession instance doesn't take ownership of the validator.\nfunc NewServerSession(validator *vmess.TimedUserValidator, sessionHistory *SessionHistory) *ServerSession {\n\treturn &ServerSession{\n\t\tuserValidator:  validator,\n\t\tsessionHistory: sessionHistory,\n\t}\n}\n\n// SetAEADForced sets isAEADForced for a ServerSession.\nfunc (s *ServerSession) SetAEADForced(isAEADForced bool) {\n\ts.isAEADForced = isAEADForced\n}\n\nfunc parseSecurityType(b byte) protocol.SecurityType {\n\tif _, f := protocol.SecurityType_name[int32(b)]; f {\n\t\tst := protocol.SecurityType(b)\n\t\t// For backward compatibility.\n\t\tif st == protocol.SecurityType_UNKNOWN {\n\t\t\tst = protocol.SecurityType_LEGACY\n\t\t}\n\t\treturn st\n\t}\n\treturn protocol.SecurityType_UNKNOWN\n}\n\n// DecodeRequestHeader decodes and returns (if successful) a RequestHeader from an input stream.\nfunc (s *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {\n\tbuffer := buf.New()\n\n\tdrainer, err := drain.NewBehaviorSeedLimitedDrainer(int64(s.userValidator.GetBehaviorSeed()), 16+38, 3266, 64)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to initialize drainer\").Base(err)\n\t}\n\n\tdrainConnection := func(e error) error {\n\t\t// We read a deterministic generated length of data before closing the connection to offset padding read pattern\n\t\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\t\treturn drain.WithError(drainer, reader, e)\n\t}\n\n\tdefer func() {\n\t\tbuffer.Release()\n\t}()\n\n\tif _, err := buffer.ReadFullFrom(reader, protocol.IDBytesLen); err != nil {\n\t\treturn nil, newError(\"failed to read request header\").Base(err)\n\t}\n\n\tvar decryptor io.Reader\n\tvar vmessAccount *vmess.MemoryAccount\n\n\tuser, foundAEAD, errorAEAD := s.userValidator.GetAEAD(buffer.Bytes())\n\n\tvar fixedSizeAuthID [16]byte\n\tcopy(fixedSizeAuthID[:], buffer.Bytes())\n\n\tswitch {\n\tcase foundAEAD:\n\t\tvmessAccount = user.Account.(*vmess.MemoryAccount)\n\t\tvar fixedSizeCmdKey [16]byte\n\t\tcopy(fixedSizeCmdKey[:], vmessAccount.ID.CmdKey())\n\t\taeadData, shouldDrain, bytesRead, errorReason := vmessaead.OpenVMessAEADHeader(fixedSizeCmdKey, fixedSizeAuthID, reader)\n\t\tif errorReason != nil {\n\t\t\tif shouldDrain {\n\t\t\t\tdrainer.AcknowledgeReceive(bytesRead)\n\t\t\t\treturn nil, drainConnection(newError(\"AEAD read failed\").Base(errorReason))\n\t\t\t}\n\t\t\treturn nil, drainConnection(newError(\"AEAD read failed, drain skipped\").Base(errorReason))\n\t\t}\n\t\tdecryptor = bytes.NewReader(aeadData)\n\t\ts.isAEADRequest = true\n\n\tcase errorAEAD == vmessaead.ErrNotFound:\n\t\tuserLegacy, timestamp, valid, userValidationError := s.userValidator.Get(buffer.Bytes())\n\t\tif !valid || userValidationError != nil {\n\t\t\treturn nil, drainConnection(newError(\"invalid user\").Base(userValidationError))\n\t\t}\n\t\tif s.isAEADForced {\n\t\t\treturn nil, drainConnection(newError(\"invalid user: VMessAEAD is enforced and a non VMessAEAD connection is received. You can still disable this security feature with environment variable v2ray.vmess.aead.forced = false . You will not be able to enable legacy header workaround in the future.\"))\n\t\t}\n\t\tif s.userValidator.ShouldShowLegacyWarn() {\n\t\t\tnewError(\"Critical Warning: potentially invalid user: a non VMessAEAD connection is received. From 2022 Jan 1st, this kind of connection will be rejected by default. You should update or replace your client software now. This message will not be shown for further violation on this inbound.\").AtWarning().WriteToLog()\n\t\t}\n\t\tuser = userLegacy\n\t\tiv := hashTimestamp(md5.New(), timestamp)\n\t\tvmessAccount = userLegacy.Account.(*vmess.MemoryAccount)\n\n\t\taesStream := crypto.NewAesDecryptionStream(vmessAccount.ID.CmdKey(), iv)\n\t\tdecryptor = crypto.NewCryptionReader(aesStream, reader)\n\n\tdefault:\n\t\treturn nil, drainConnection(newError(\"invalid user\").Base(errorAEAD))\n\t}\n\n\tdrainer.AcknowledgeReceive(int(buffer.Len()))\n\tbuffer.Clear()\n\tif _, err := buffer.ReadFullFrom(decryptor, 38); err != nil {\n\t\treturn nil, newError(\"failed to read request header\").Base(err)\n\t}\n\n\trequest := &protocol.RequestHeader{\n\t\tUser:    user,\n\t\tVersion: buffer.Byte(0),\n\t}\n\n\tcopy(s.requestBodyIV[:], buffer.BytesRange(1, 17))   // 16 bytes\n\tcopy(s.requestBodyKey[:], buffer.BytesRange(17, 33)) // 16 bytes\n\tvar sid sessionID\n\tcopy(sid.user[:], vmessAccount.ID.Bytes())\n\tsid.key = s.requestBodyKey\n\tsid.nonce = s.requestBodyIV\n\tif !s.sessionHistory.addIfNotExits(sid) {\n\t\tif !s.isAEADRequest {\n\t\t\tdrainErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])\n\t\t\tif drainErr != nil {\n\t\t\t\treturn nil, drainConnection(newError(\"duplicated session id, possibly under replay attack, and failed to taint userHash\").Base(drainErr))\n\t\t\t}\n\t\t\treturn nil, drainConnection(newError(\"duplicated session id, possibly under replay attack, userHash tainted\"))\n\t\t}\n\t\treturn nil, newError(\"duplicated session id, possibly under replay attack, but this is a AEAD request\")\n\t}\n\n\ts.responseHeader = buffer.Byte(33)             // 1 byte\n\trequest.Option = bitmask.Byte(buffer.Byte(34)) // 1 byte\n\tpaddingLen := int(buffer.Byte(35) >> 4)\n\trequest.Security = parseSecurityType(buffer.Byte(35) & 0x0F)\n\t// 1 bytes reserved\n\trequest.Command = protocol.RequestCommand(buffer.Byte(37))\n\n\tswitch request.Command {\n\tcase protocol.RequestCommandMux:\n\t\trequest.Address = net.DomainAddress(\"v1.mux.cool\")\n\t\trequest.Port = 0\n\n\tcase protocol.RequestCommandTCP, protocol.RequestCommandUDP:\n\t\tif addr, port, err := addrParser.ReadAddressPort(buffer, decryptor); err == nil {\n\t\t\trequest.Address = addr\n\t\t\trequest.Port = port\n\t\t}\n\t}\n\n\tif paddingLen > 0 {\n\t\tif _, err := buffer.ReadFullFrom(decryptor, int32(paddingLen)); err != nil {\n\t\t\tif !s.isAEADRequest {\n\t\t\t\tburnErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])\n\t\t\t\tif burnErr != nil {\n\t\t\t\t\treturn nil, newError(\"failed to read padding, failed to taint userHash\").Base(burnErr).Base(err)\n\t\t\t\t}\n\t\t\t\treturn nil, newError(\"failed to read padding, userHash tainted\").Base(err)\n\t\t\t}\n\t\t\treturn nil, newError(\"failed to read padding\").Base(err)\n\t\t}\n\t}\n\n\tif _, err := buffer.ReadFullFrom(decryptor, 4); err != nil {\n\t\tif !s.isAEADRequest {\n\t\t\tburnErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])\n\t\t\tif burnErr != nil {\n\t\t\t\treturn nil, newError(\"failed to read checksum, failed to taint userHash\").Base(burnErr).Base(err)\n\t\t\t}\n\t\t\treturn nil, newError(\"failed to read checksum, userHash tainted\").Base(err)\n\t\t}\n\t\treturn nil, newError(\"failed to read checksum\").Base(err)\n\t}\n\n\tfnv1a := fnv.New32a()\n\tcommon.Must2(fnv1a.Write(buffer.BytesTo(-4)))\n\tactualHash := fnv1a.Sum32()\n\texpectedHash := binary.BigEndian.Uint32(buffer.BytesFrom(-4))\n\n\tif actualHash != expectedHash {\n\t\tif !s.isAEADRequest {\n\t\t\tAutherr := newError(\"invalid auth, legacy userHash tainted\")\n\t\t\tburnErr := s.userValidator.BurnTaintFuse(fixedSizeAuthID[:])\n\t\t\tif burnErr != nil {\n\t\t\t\tAutherr = newError(\"invalid auth, can't taint legacy userHash\").Base(burnErr)\n\t\t\t}\n\t\t\t// It is possible that we are under attack described in https://github.com/v2ray/v2ray-core/issues/2523\n\t\t\treturn nil, drainConnection(Autherr)\n\t\t}\n\t\treturn nil, newError(\"invalid auth, but this is a AEAD request\")\n\t}\n\n\tif request.Address == nil {\n\t\treturn nil, newError(\"invalid remote address\")\n\t}\n\n\tif request.Security == protocol.SecurityType_UNKNOWN || request.Security == protocol.SecurityType_AUTO {\n\t\treturn nil, newError(\"unknown security type: \", request.Security)\n\t}\n\n\treturn request, nil\n}\n\n// DecodeRequestBody returns Reader from which caller can fetch decrypted body.\nfunc (s *ServerSession) DecodeRequestBody(request *protocol.RequestHeader, reader io.Reader) (buf.Reader, error) {\n\tvar sizeParser crypto.ChunkSizeDecoder = crypto.PlainChunkSizeParser{}\n\tif request.Option.Has(protocol.RequestOptionChunkMasking) {\n\t\tsizeParser = NewShakeSizeParser(s.requestBodyIV[:])\n\t}\n\tvar padding crypto.PaddingLengthGenerator\n\tif request.Option.Has(protocol.RequestOptionGlobalPadding) {\n\t\tvar ok bool\n\t\tpadding, ok = sizeParser.(crypto.PaddingLengthGenerator)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"invalid option: RequestOptionGlobalPadding\")\n\t\t}\n\t}\n\n\tswitch request.Security {\n\tcase protocol.SecurityType_NONE:\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tif request.Command.TransferType() == protocol.TransferTypeStream {\n\t\t\t\treturn crypto.NewChunkStreamReader(sizeParser, reader), nil\n\t\t\t}\n\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(NoOpAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, reader, protocol.TransferTypePacket, padding), nil\n\t\t}\n\t\treturn buf.NewReader(reader), nil\n\n\tcase protocol.SecurityType_LEGACY:\n\t\taesStream := crypto.NewAesDecryptionStream(s.requestBodyKey[:], s.requestBodyIV[:])\n\t\tcryptionReader := crypto.NewCryptionReader(aesStream, reader)\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(FnvAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, cryptionReader, request.Command.TransferType(), padding), nil\n\t\t}\n\t\treturn buf.NewReader(cryptionReader), nil\n\n\tcase protocol.SecurityType_AES128_GCM:\n\t\taead := crypto.NewAesGcm(s.requestBodyKey[:])\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(s.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD := crypto.NewAesGcm(AuthenticatedLengthKey)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, reader, request.Command.TransferType(), padding), nil\n\n\tcase protocol.SecurityType_CHACHA20_POLY1305:\n\t\taead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(s.requestBodyKey[:]))\n\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(s.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD, err := chacha20poly1305.New(GenerateChacha20Poly1305Key(AuthenticatedLengthKey))\n\t\t\tcommon.Must(err)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationReader(auth, sizeParser, reader, request.Command.TransferType(), padding), nil\n\n\tdefault:\n\t\treturn nil, newError(\"invalid option: Security\")\n\t}\n}\n\n// EncodeResponseHeader writes encoded response header into the given writer.\nfunc (s *ServerSession) EncodeResponseHeader(header *protocol.ResponseHeader, writer io.Writer) {\n\tvar encryptionWriter io.Writer\n\tif !s.isAEADRequest {\n\t\ts.responseBodyKey = md5.Sum(s.requestBodyKey[:])\n\t\ts.responseBodyIV = md5.Sum(s.requestBodyIV[:])\n\t} else {\n\t\tBodyKey := sha256.Sum256(s.requestBodyKey[:])\n\t\tcopy(s.responseBodyKey[:], BodyKey[:16])\n\t\tBodyIV := sha256.Sum256(s.requestBodyIV[:])\n\t\tcopy(s.responseBodyIV[:], BodyIV[:16])\n\t}\n\n\taesStream := crypto.NewAesEncryptionStream(s.responseBodyKey[:], s.responseBodyIV[:])\n\tencryptionWriter = crypto.NewCryptionWriter(aesStream, writer)\n\ts.responseWriter = encryptionWriter\n\n\taeadEncryptedHeaderBuffer := bytes.NewBuffer(nil)\n\n\tif s.isAEADRequest {\n\t\tencryptionWriter = aeadEncryptedHeaderBuffer\n\t}\n\n\tcommon.Must2(encryptionWriter.Write([]byte{s.responseHeader, byte(header.Option)}))\n\terr := MarshalCommand(header.Command, encryptionWriter)\n\tif err != nil {\n\t\tcommon.Must2(encryptionWriter.Write([]byte{0x00, 0x00}))\n\t}\n\n\tif s.isAEADRequest {\n\t\taeadResponseHeaderLengthEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderLenKey)\n\t\taeadResponseHeaderLengthEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderLenIV)[:12]\n\n\t\taeadResponseHeaderLengthEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)).(cipher.Block)\n\t\taeadResponseHeaderLengthEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)).(cipher.AEAD)\n\n\t\taeadResponseHeaderLengthEncryptionBuffer := bytes.NewBuffer(nil)\n\n\t\tdecryptedResponseHeaderLengthBinaryDeserializeBuffer := uint16(aeadEncryptedHeaderBuffer.Len())\n\n\t\tcommon.Must(binary.Write(aeadResponseHeaderLengthEncryptionBuffer, binary.BigEndian, decryptedResponseHeaderLengthBinaryDeserializeBuffer))\n\n\t\tAEADEncryptedLength := aeadResponseHeaderLengthEncryptionAEAD.Seal(nil, aeadResponseHeaderLengthEncryptionIV, aeadResponseHeaderLengthEncryptionBuffer.Bytes(), nil)\n\t\tcommon.Must2(io.Copy(writer, bytes.NewReader(AEADEncryptedLength)))\n\n\t\taeadResponseHeaderPayloadEncryptionKey := vmessaead.KDF16(s.responseBodyKey[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadKey)\n\t\taeadResponseHeaderPayloadEncryptionIV := vmessaead.KDF(s.responseBodyIV[:], vmessaead.KDFSaltConstAEADRespHeaderPayloadIV)[:12]\n\n\t\taeadResponseHeaderPayloadEncryptionKeyAESBlock := common.Must2(aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)).(cipher.Block)\n\t\taeadResponseHeaderPayloadEncryptionAEAD := common.Must2(cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)).(cipher.AEAD)\n\n\t\taeadEncryptedHeaderPayload := aeadResponseHeaderPayloadEncryptionAEAD.Seal(nil, aeadResponseHeaderPayloadEncryptionIV, aeadEncryptedHeaderBuffer.Bytes(), nil)\n\t\tcommon.Must2(io.Copy(writer, bytes.NewReader(aeadEncryptedHeaderPayload)))\n\t}\n}\n\n// EncodeResponseBody returns a Writer that auto-encrypt content written by caller.\nfunc (s *ServerSession) EncodeResponseBody(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {\n\tvar sizeParser crypto.ChunkSizeEncoder = crypto.PlainChunkSizeParser{}\n\tif request.Option.Has(protocol.RequestOptionChunkMasking) {\n\t\tsizeParser = NewShakeSizeParser(s.responseBodyIV[:])\n\t}\n\tvar padding crypto.PaddingLengthGenerator\n\tif request.Option.Has(protocol.RequestOptionGlobalPadding) {\n\t\tvar ok bool\n\t\tpadding, ok = sizeParser.(crypto.PaddingLengthGenerator)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"invalid option: RequestOptionGlobalPadding\")\n\t\t}\n\t}\n\n\tswitch request.Security {\n\tcase protocol.SecurityType_NONE:\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tif request.Command.TransferType() == protocol.TransferTypeStream {\n\t\t\t\treturn crypto.NewChunkStreamWriter(sizeParser, writer), nil\n\t\t\t}\n\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(NoOpAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, writer, protocol.TransferTypePacket, padding), nil\n\t\t}\n\t\treturn buf.NewWriter(writer), nil\n\n\tcase protocol.SecurityType_LEGACY:\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) {\n\t\t\tauth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    new(FnvAuthenticator),\n\t\t\t\tNonceGenerator:          crypto.GenerateEmptyBytes(),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, s.responseWriter, request.Command.TransferType(), padding), nil\n\t\t}\n\t\treturn &buf.SequentialWriter{Writer: s.responseWriter}, nil\n\n\tcase protocol.SecurityType_AES128_GCM:\n\t\taead := crypto.NewAesGcm(s.responseBodyKey[:])\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(s.responseBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(s.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD := crypto.NewAesGcm(AuthenticatedLengthKey)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, writer, request.Command.TransferType(), padding), nil\n\n\tcase protocol.SecurityType_CHACHA20_POLY1305:\n\t\taead, _ := chacha20poly1305.New(GenerateChacha20Poly1305Key(s.responseBodyKey[:]))\n\n\t\tauth := &crypto.AEADAuthenticator{\n\t\t\tAEAD:                    aead,\n\t\t\tNonceGenerator:          GenerateChunkNonce(s.responseBodyIV[:], uint32(aead.NonceSize())),\n\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t}\n\t\tif request.Option.Has(protocol.RequestOptionAuthenticatedLength) {\n\t\t\tAuthenticatedLengthKey := vmessaead.KDF16(s.requestBodyKey[:], \"auth_len\")\n\t\t\tAuthenticatedLengthKeyAEAD, err := chacha20poly1305.New(GenerateChacha20Poly1305Key(AuthenticatedLengthKey))\n\t\t\tcommon.Must(err)\n\n\t\t\tlengthAuth := &crypto.AEADAuthenticator{\n\t\t\t\tAEAD:                    AuthenticatedLengthKeyAEAD,\n\t\t\t\tNonceGenerator:          GenerateChunkNonce(s.requestBodyIV[:], uint32(aead.NonceSize())),\n\t\t\t\tAdditionalDataGenerator: crypto.GenerateEmptyBytes(),\n\t\t\t}\n\t\t\tsizeParser = NewAEADSizeParser(lengthAuth)\n\t\t}\n\t\treturn crypto.NewAuthenticationWriter(auth, sizeParser, writer, request.Command.TransferType(), padding), nil\n\n\tdefault:\n\t\treturn nil, newError(\"invalid option: Security\")\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/errors.generated.go",
    "content": "package vmess\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vmess/inbound/config.go",
    "content": "package inbound\n\n// GetDefaultValue returns default settings of DefaultConfig.\nfunc (c *Config) GetDefaultValue() *DefaultConfig {\n\tif c.GetDefault() == nil {\n\t\treturn &DefaultConfig{}\n\t}\n\treturn c.Default\n}\n"
  },
  {
    "path": "proxy/vmess/inbound/config.pb.go",
    "content": "package inbound\n\nimport (\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 DetourConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTo            string                 `protobuf:\"bytes,1,opt,name=to,proto3\" json:\"to,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *DetourConfig) Reset() {\n\t*x = DetourConfig{}\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *DetourConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DetourConfig) ProtoMessage() {}\n\nfunc (x *DetourConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[0]\n\tif 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 DetourConfig.ProtoReflect.Descriptor instead.\nfunc (*DetourConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_inbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *DetourConfig) GetTo() string {\n\tif x != nil {\n\t\treturn x.To\n\t}\n\treturn \"\"\n}\n\ntype DefaultConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAlterId       uint32                 `protobuf:\"varint,1,opt,name=alter_id,json=alterId,proto3\" json:\"alter_id,omitempty\"`\n\tLevel         uint32                 `protobuf:\"varint,2,opt,name=level,proto3\" json:\"level,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *DefaultConfig) Reset() {\n\t*x = DefaultConfig{}\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *DefaultConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DefaultConfig) ProtoMessage() {}\n\nfunc (x *DefaultConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[1]\n\tif 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 DefaultConfig.ProtoReflect.Descriptor instead.\nfunc (*DefaultConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_inbound_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *DefaultConfig) GetAlterId() uint32 {\n\tif x != nil {\n\t\treturn x.AlterId\n\t}\n\treturn 0\n}\n\nfunc (x *DefaultConfig) GetLevel() uint32 {\n\tif x != nil {\n\t\treturn x.Level\n\t}\n\treturn 0\n}\n\ntype Config struct {\n\tstate                protoimpl.MessageState `protogen:\"open.v1\"`\n\tUser                 []*protocol.User       `protobuf:\"bytes,1,rep,name=user,proto3\" json:\"user,omitempty\"`\n\tDefault              *DefaultConfig         `protobuf:\"bytes,2,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tDetour               *DetourConfig          `protobuf:\"bytes,3,opt,name=detour,proto3\" json:\"detour,omitempty\"`\n\tSecureEncryptionOnly bool                   `protobuf:\"varint,4,opt,name=secure_encryption_only,json=secureEncryptionOnly,proto3\" json:\"secure_encryption_only,omitempty\"`\n\tunknownFields        protoimpl.UnknownFields\n\tsizeCache            protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[2]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_inbound_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *Config) GetUser() []*protocol.User {\n\tif x != nil {\n\t\treturn x.User\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetDefault() *DefaultConfig {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetDetour() *DetourConfig {\n\tif x != nil {\n\t\treturn x.Detour\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetSecureEncryptionOnly() bool {\n\tif x != nil {\n\t\treturn x.SecureEncryptionOnly\n\t}\n\treturn false\n}\n\ntype SimplifiedConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUsers         []string               `protobuf:\"bytes,1,rep,name=users,proto3\" json:\"users,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_inbound_config_proto_msgTypes[3]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_inbound_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *SimplifiedConfig) GetUsers() []string {\n\tif x != nil {\n\t\treturn x.Users\n\t}\n\treturn nil\n}\n\nvar File_proxy_vmess_inbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_vmess_inbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\" proxy/vmess/inbound/config.proto\\x12\\x1ev2ray.core.proxy.vmess.inbound\\x1a\\x1acommon/protocol/user.proto\\x1a common/protoext/extensions.proto\\\"\\x1e\\n\" +\n\t\"\\fDetourConfig\\x12\\x0e\\n\" +\n\t\"\\x02to\\x18\\x01 \\x01(\\tR\\x02to\\\"@\\n\" +\n\t\"\\rDefaultConfig\\x12\\x19\\n\" +\n\t\"\\balter_id\\x18\\x01 \\x01(\\rR\\aalterId\\x12\\x14\\n\" +\n\t\"\\x05level\\x18\\x02 \\x01(\\rR\\x05level\\\"\\x83\\x02\\n\" +\n\t\"\\x06Config\\x124\\n\" +\n\t\"\\x04user\\x18\\x01 \\x03(\\v2 .v2ray.core.common.protocol.UserR\\x04user\\x12G\\n\" +\n\t\"\\adefault\\x18\\x02 \\x01(\\v2-.v2ray.core.proxy.vmess.inbound.DefaultConfigR\\adefault\\x12D\\n\" +\n\t\"\\x06detour\\x18\\x03 \\x01(\\v2,.v2ray.core.proxy.vmess.inbound.DetourConfigR\\x06detour\\x124\\n\" +\n\t\"\\x16secure_encryption_only\\x18\\x04 \\x01(\\bR\\x14secureEncryptionOnly\\\">\\n\" +\n\t\"\\x10SimplifiedConfig\\x12\\x14\\n\" +\n\t\"\\x05users\\x18\\x01 \\x03(\\tR\\x05users:\\x14\\x82\\xb5\\x18\\x10\\n\" +\n\t\"\\ainbound\\x12\\x05vmessB{\\n\" +\n\t\"\\\"com.v2ray.core.proxy.vmess.inboundP\\x01Z2github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\\xaa\\x02\\x1eV2Ray.Core.Proxy.Vmess.Inboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_vmess_inbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_vmess_inbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_vmess_inbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_vmess_inbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vmess_inbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vmess_inbound_config_proto_rawDesc), len(file_proxy_vmess_inbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_vmess_inbound_config_proto_rawDescData\n}\n\nvar file_proxy_vmess_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_proxy_vmess_inbound_config_proto_goTypes = []any{\n\t(*DetourConfig)(nil),     // 0: v2ray.core.proxy.vmess.inbound.DetourConfig\n\t(*DefaultConfig)(nil),    // 1: v2ray.core.proxy.vmess.inbound.DefaultConfig\n\t(*Config)(nil),           // 2: v2ray.core.proxy.vmess.inbound.Config\n\t(*SimplifiedConfig)(nil), // 3: v2ray.core.proxy.vmess.inbound.SimplifiedConfig\n\t(*protocol.User)(nil),    // 4: v2ray.core.common.protocol.User\n}\nvar file_proxy_vmess_inbound_config_proto_depIdxs = []int32{\n\t4, // 0: v2ray.core.proxy.vmess.inbound.Config.user:type_name -> v2ray.core.common.protocol.User\n\t1, // 1: v2ray.core.proxy.vmess.inbound.Config.default:type_name -> v2ray.core.proxy.vmess.inbound.DefaultConfig\n\t0, // 2: v2ray.core.proxy.vmess.inbound.Config.detour:type_name -> v2ray.core.proxy.vmess.inbound.DetourConfig\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_proxy_vmess_inbound_config_proto_init() }\nfunc file_proxy_vmess_inbound_config_proto_init() {\n\tif File_proxy_vmess_inbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_vmess_inbound_config_proto_rawDesc), len(file_proxy_vmess_inbound_config_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_proxy_vmess_inbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vmess_inbound_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vmess_inbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vmess_inbound_config_proto = out.File\n\tfile_proxy_vmess_inbound_config_proto_goTypes = nil\n\tfile_proxy_vmess_inbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vmess/inbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vmess.inbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vmess.Inbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\";\noption java_package = \"com.v2ray.core.proxy.vmess.inbound\";\noption java_multiple_files = true;\n\nimport \"common/protocol/user.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage DetourConfig {\n  string to = 1;\n}\n\nmessage DefaultConfig {\n  uint32 alter_id = 1;\n  uint32 level = 2;\n}\n\nmessage Config {\n  repeated v2ray.core.common.protocol.User user = 1;\n  DefaultConfig default = 2;\n  DetourConfig detour = 3;\n  bool secure_encryption_only = 4;\n}\n\nmessage SimplifiedConfig{\n  option (v2ray.core.common.protoext.message_opt).type = \"inbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"vmess\";\n\n  repeated string users = 1;\n}\n"
  },
  {
    "path": "proxy/vmess/inbound/errors.generated.go",
    "content": "package inbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vmess/inbound/inbound.go",
    "content": "package inbound\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\tfeature_inbound \"github.com/v2fly/v2ray-core/v5/features/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/encoding\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype userByEmail struct {\n\tsync.Mutex\n\tcache           map[string]*protocol.MemoryUser\n\tdefaultLevel    uint32\n\tdefaultAlterIDs uint16\n}\n\nfunc newUserByEmail(config *DefaultConfig) *userByEmail {\n\treturn &userByEmail{\n\t\tcache:           make(map[string]*protocol.MemoryUser),\n\t\tdefaultLevel:    config.Level,\n\t\tdefaultAlterIDs: uint16(config.AlterId),\n\t}\n}\n\nfunc (v *userByEmail) addNoLock(u *protocol.MemoryUser) bool {\n\temail := strings.ToLower(u.Email)\n\t_, found := v.cache[email]\n\tif found {\n\t\treturn false\n\t}\n\tv.cache[email] = u\n\treturn true\n}\n\nfunc (v *userByEmail) Add(u *protocol.MemoryUser) bool {\n\tv.Lock()\n\tdefer v.Unlock()\n\n\treturn v.addNoLock(u)\n}\n\nfunc (v *userByEmail) Get(email string) (*protocol.MemoryUser, bool) {\n\temail = strings.ToLower(email)\n\n\tv.Lock()\n\tdefer v.Unlock()\n\n\tuser, found := v.cache[email]\n\tif !found {\n\t\tid := uuid.New()\n\t\trawAccount := &vmess.Account{\n\t\t\tId:      id.String(),\n\t\t\tAlterId: uint32(v.defaultAlterIDs),\n\t\t}\n\t\taccount, err := rawAccount.AsAccount()\n\t\tcommon.Must(err)\n\t\tuser = &protocol.MemoryUser{\n\t\t\tLevel:   v.defaultLevel,\n\t\t\tEmail:   email,\n\t\t\tAccount: account,\n\t\t}\n\t\tv.cache[email] = user\n\t}\n\treturn user, found\n}\n\nfunc (v *userByEmail) Remove(email string) bool {\n\temail = strings.ToLower(email)\n\n\tv.Lock()\n\tdefer v.Unlock()\n\n\tif _, found := v.cache[email]; !found {\n\t\treturn false\n\t}\n\tdelete(v.cache, email)\n\treturn true\n}\n\n// Handler is an inbound connection handler that handles messages in VMess protocol.\ntype Handler struct {\n\tpolicyManager         policy.Manager\n\tinboundHandlerManager feature_inbound.Manager\n\tclients               *vmess.TimedUserValidator\n\tusersByEmail          *userByEmail\n\tdetours               *DetourConfig\n\tsessionHistory        *encoding.SessionHistory\n\tsecure                bool\n}\n\n// New creates a new VMess inbound handler.\nfunc New(ctx context.Context, config *Config) (*Handler, error) {\n\tv := core.MustFromContext(ctx)\n\thandler := &Handler{\n\t\tpolicyManager:         v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t\tinboundHandlerManager: v.GetFeature(feature_inbound.ManagerType()).(feature_inbound.Manager),\n\t\tclients:               vmess.NewTimedUserValidator(protocol.DefaultIDHash),\n\t\tdetours:               config.Detour,\n\t\tusersByEmail:          newUserByEmail(config.GetDefaultValue()),\n\t\tsessionHistory:        encoding.NewSessionHistory(),\n\t\tsecure:                config.SecureEncryptionOnly,\n\t}\n\n\tfor _, user := range config.User {\n\t\tmUser, err := user.ToMemoryUser()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get VMess user\").Base(err)\n\t\t}\n\n\t\tif err := handler.AddUser(ctx, mUser); err != nil {\n\t\t\treturn nil, newError(\"failed to initiate user\").Base(err)\n\t\t}\n\t}\n\n\treturn handler, nil\n}\n\n// Close implements common.Closable.\nfunc (h *Handler) Close() error {\n\treturn errors.Combine(\n\t\th.clients.Close(),\n\t\th.sessionHistory.Close(),\n\t\tcommon.Close(h.usersByEmail))\n}\n\n// Network implements proxy.Inbound.Network().\nfunc (*Handler) Network() []net.Network {\n\treturn []net.Network{net.Network_TCP, net.Network_UNIX}\n}\n\nfunc (h *Handler) GetUser(email string) *protocol.MemoryUser {\n\tuser, existing := h.usersByEmail.Get(email)\n\tif !existing {\n\t\th.clients.Add(user)\n\t}\n\treturn user\n}\n\nfunc (h *Handler) AddUser(ctx context.Context, user *protocol.MemoryUser) error {\n\tif len(user.Email) > 0 && !h.usersByEmail.Add(user) {\n\t\treturn newError(\"User \", user.Email, \" already exists.\")\n\t}\n\treturn h.clients.Add(user)\n}\n\nfunc (h *Handler) RemoveUser(ctx context.Context, email string) error {\n\tif email == \"\" {\n\t\treturn newError(\"Email must not be empty.\")\n\t}\n\tif !h.usersByEmail.Remove(email) {\n\t\treturn newError(\"User \", email, \" not found.\")\n\t}\n\th.clients.Remove(email)\n\treturn nil\n}\n\nfunc transferResponse(timer signal.ActivityUpdater, session *encoding.ServerSession, request *protocol.RequestHeader, response *protocol.ResponseHeader, input buf.Reader, output *buf.BufferedWriter) error {\n\tsession.EncodeResponseHeader(response, output)\n\n\tbodyWriter, err := session.EncodeResponseBody(request, output)\n\tif err != nil {\n\t\treturn newError(\"failed to start decoding response\").Base(err)\n\t}\n\t{\n\t\t// Optimize for small response packet\n\t\tdata, err := input.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err := bodyWriter.WriteMultiBuffer(data); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := output.SetBuffered(false); err != nil {\n\t\treturn err\n\t}\n\n\tif err := buf.Copy(input, bodyWriter, buf.UpdateActivity(timer)); err != nil {\n\t\treturn err\n\t}\n\n\taccount := request.User.Account.(*vmess.MemoryAccount)\n\n\tif request.Option.Has(protocol.RequestOptionChunkStream) && !account.NoTerminationSignal {\n\t\tif err := bodyWriter.WriteMultiBuffer(buf.MultiBuffer{}); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc isInsecureEncryption(s protocol.SecurityType) bool {\n\treturn s == protocol.SecurityType_NONE || s == protocol.SecurityType_LEGACY || s == protocol.SecurityType_UNKNOWN\n}\n\n// Process implements proxy.Inbound.Process().\nfunc (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error {\n\tsessionPolicy := h.policyManager.ForLevel(0)\n\tif err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {\n\t\treturn newError(\"unable to set read deadline\").Base(err).AtWarning()\n\t}\n\n\treader := &buf.BufferedReader{Reader: buf.NewReader(connection)}\n\tsvrSession := encoding.NewServerSession(h.clients, h.sessionHistory)\n\tsvrSession.SetAEADForced(aeadForced)\n\trequest, err := svrSession.DecodeRequestHeader(reader)\n\tif err != nil {\n\t\tif errors.Cause(err) != io.EOF {\n\t\t\tlog.Record(&log.AccessMessage{\n\t\t\t\tFrom:   connection.RemoteAddr(),\n\t\t\t\tTo:     \"\",\n\t\t\t\tStatus: log.AccessRejected,\n\t\t\t\tReason: err,\n\t\t\t})\n\t\t\terr = newError(\"invalid request from \", connection.RemoteAddr()).Base(err).AtInfo()\n\t\t}\n\t\treturn err\n\t}\n\n\tif h.secure && isInsecureEncryption(request.Security) {\n\t\tlog.Record(&log.AccessMessage{\n\t\t\tFrom:   connection.RemoteAddr(),\n\t\t\tTo:     \"\",\n\t\t\tStatus: log.AccessRejected,\n\t\t\tReason: \"Insecure encryption\",\n\t\t\tEmail:  request.User.Email,\n\t\t})\n\t\treturn newError(\"client is using insecure encryption: \", request.Security)\n\t}\n\n\tif request.Command != protocol.RequestCommandMux {\n\t\tctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{\n\t\t\tFrom:   connection.RemoteAddr(),\n\t\t\tTo:     request.Destination(),\n\t\t\tStatus: log.AccessAccepted,\n\t\t\tReason: \"\",\n\t\t\tEmail:  request.User.Email,\n\t\t})\n\t}\n\n\tnewError(\"received request for \", request.Destination()).WriteToLog(session.ExportIDToError(ctx))\n\n\tif err := connection.SetReadDeadline(time.Time{}); err != nil {\n\t\tnewError(\"unable to set back read deadline\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tinbound := session.InboundFromContext(ctx)\n\tif inbound == nil {\n\t\tpanic(\"no inbound metadata\")\n\t}\n\tinbound.User = request.User\n\n\tsessionPolicy = h.policyManager.ForLevel(request.User.Level)\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\tctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)\n\tlink, err := dispatcher.Dispatch(ctx, request.Destination())\n\tif err != nil {\n\t\treturn newError(\"failed to dispatch request to \", request.Destination()).Base(err)\n\t}\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\tbodyReader, err := svrSession.DecodeRequestBody(request, reader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to start decoding\").Base(err)\n\t\t}\n\t\tif err := buf.Copy(bodyReader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn newError(\"failed to transfer request\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\twriter := buf.NewBufferedWriter(buf.NewWriter(connection))\n\t\tdefer writer.Flush()\n\n\t\tresponse := &protocol.ResponseHeader{\n\t\t\tCommand: h.generateCommand(ctx, request),\n\t\t}\n\t\treturn transferResponse(timer, svrSession, request, response, link.Reader, writer)\n\t}\n\n\trequestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer))\n\tif err := task.Run(ctx, requestDonePost, responseDone); err != nil {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nfunc (h *Handler) generateCommand(ctx context.Context, request *protocol.RequestHeader) protocol.ResponseCommand {\n\tif h.detours != nil {\n\t\ttag := h.detours.To\n\t\tif h.inboundHandlerManager != nil {\n\t\t\thandler, err := h.inboundHandlerManager.GetHandler(ctx, tag)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get detour handler: \", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tproxyHandler, port, availableMin := handler.GetRandomInboundProxy()\n\t\t\tinboundHandler, ok := proxyHandler.(*Handler)\n\t\t\tif ok && inboundHandler != nil {\n\t\t\t\tif availableMin > 255 {\n\t\t\t\t\tavailableMin = 255\n\t\t\t\t}\n\n\t\t\t\tnewError(\"pick detour handler for port \", port, \" for \", availableMin, \" minutes.\").AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\tuser := inboundHandler.GetUser(request.User.Email)\n\t\t\t\tif user == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\taccount := user.Account.(*vmess.MemoryAccount)\n\t\t\t\treturn &protocol.CommandSwitchAccount{\n\t\t\t\t\tPort:     port,\n\t\t\t\t\tID:       account.ID.UUID(),\n\t\t\t\t\tAlterIds: uint16(len(account.AlterIDs)),\n\t\t\t\t\tLevel:    user.Level,\n\t\t\t\t\tValidMin: byte(availableMin),\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nvar (\n\taeadForced     = false\n\taeadForced2022 = false\n)\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedServer := config.(*SimplifiedConfig)\n\t\tfullConfig := &Config{\n\t\t\tUser: func() (users []*protocol.User) {\n\t\t\t\tfor _, v := range simplifiedServer.Users {\n\t\t\t\t\taccount := &vmess.Account{Id: v}\n\t\t\t\t\tusers = append(users, &protocol.User{\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(account),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}(),\n\t\t}\n\n\t\treturn common.CreateObject(ctx, fullConfig)\n\t}))\n\n\tdefaultFlagValue := \"true_by_default_2022\"\n\n\tisAeadForced := platform.NewEnvFlag(\"v2ray.vmess.aead.forced\").GetValue(func() string { return defaultFlagValue })\n\tif isAeadForced == \"true\" {\n\t\taeadForced = true\n\t}\n\n\tif isAeadForced == \"true_by_default_2022\" {\n\t\taeadForced = true\n\t\taeadForced2022 = true\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/outbound/command.go",
    "content": "package outbound\n\nimport (\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n)\n\nfunc (h *Handler) handleSwitchAccount(cmd *protocol.CommandSwitchAccount) {\n\trawAccount := &vmess.Account{\n\t\tId:      cmd.ID.String(),\n\t\tAlterId: uint32(cmd.AlterIds),\n\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\tType: protocol.SecurityType_LEGACY,\n\t\t},\n\t}\n\n\taccount, err := rawAccount.AsAccount()\n\tcommon.Must(err)\n\tuser := &protocol.MemoryUser{\n\t\tEmail:   \"\",\n\t\tLevel:   cmd.Level,\n\t\tAccount: account,\n\t}\n\tdest := net.TCPDestination(cmd.Host, cmd.Port)\n\tuntil := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute)\n\th.serverList.AddServer(protocol.NewServerSpec(dest, protocol.BeforeTime(until), user))\n}\n\nfunc (h *Handler) handleCommand(dest net.Destination, cmd protocol.ResponseCommand) {\n\tswitch typedCommand := cmd.(type) {\n\tcase *protocol.CommandSwitchAccount:\n\t\tif typedCommand.Host == nil {\n\t\t\ttypedCommand.Host = dest.Address\n\t\t}\n\t\th.handleSwitchAccount(typedCommand)\n\tdefault:\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/outbound/config.go",
    "content": "package outbound\n"
  },
  {
    "path": "proxy/vmess/outbound/config.pb.go",
    "content": "package outbound\n\nimport (\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState     `protogen:\"open.v1\"`\n\tReceiver      []*protocol.ServerEndpoint `protobuf:\"bytes,1,rep,name=Receiver,proto3\" json:\"Receiver,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_vmess_outbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_outbound_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_outbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetReceiver() []*protocol.ServerEndpoint {\n\tif x != nil {\n\t\treturn x.Receiver\n\t}\n\treturn nil\n}\n\ntype SimplifiedConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAddress       *net.IPOrDomain        `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tPort          uint32                 `protobuf:\"varint,2,opt,name=port,proto3\" json:\"port,omitempty\"`\n\tUuid          string                 `protobuf:\"bytes,3,opt,name=uuid,proto3\" json:\"uuid,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *SimplifiedConfig) Reset() {\n\t*x = SimplifiedConfig{}\n\tmi := &file_proxy_vmess_outbound_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SimplifiedConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimplifiedConfig) ProtoMessage() {}\n\nfunc (x *SimplifiedConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_vmess_outbound_config_proto_msgTypes[1]\n\tif 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 SimplifiedConfig.ProtoReflect.Descriptor instead.\nfunc (*SimplifiedConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_vmess_outbound_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SimplifiedConfig) GetAddress() *net.IPOrDomain {\n\tif x != nil {\n\t\treturn x.Address\n\t}\n\treturn nil\n}\n\nfunc (x *SimplifiedConfig) GetPort() uint32 {\n\tif x != nil {\n\t\treturn x.Port\n\t}\n\treturn 0\n}\n\nfunc (x *SimplifiedConfig) GetUuid() string {\n\tif x != nil {\n\t\treturn x.Uuid\n\t}\n\treturn \"\"\n}\n\nvar File_proxy_vmess_outbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_vmess_outbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"!proxy/vmess/outbound/config.proto\\x12\\x1fv2ray.core.proxy.vmess.outbound\\x1a!common/protocol/server_spec.proto\\x1a\\x18common/net/address.proto\\x1a common/protoext/extensions.proto\\\"P\\n\" +\n\t\"\\x06Config\\x12F\\n\" +\n\t\"\\bReceiver\\x18\\x01 \\x03(\\v2*.v2ray.core.common.protocol.ServerEndpointR\\bReceiver\\\"\\x92\\x01\\n\" +\n\t\"\\x10SimplifiedConfig\\x12;\\n\" +\n\t\"\\aaddress\\x18\\x01 \\x01(\\v2!.v2ray.core.common.net.IPOrDomainR\\aaddress\\x12\\x12\\n\" +\n\t\"\\x04port\\x18\\x02 \\x01(\\rR\\x04port\\x12\\x12\\n\" +\n\t\"\\x04uuid\\x18\\x03 \\x01(\\tR\\x04uuid:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\boutbound\\x12\\x05vmess\\x90\\xff)\\x01B~\\n\" +\n\t\"#com.v2ray.core.proxy.vmess.outboundP\\x01Z3github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\\xaa\\x02\\x1fV2Ray.Core.Proxy.Vmess.Outboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_vmess_outbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_vmess_outbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_vmess_outbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_vmess_outbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_vmess_outbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_vmess_outbound_config_proto_rawDesc), len(file_proxy_vmess_outbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_vmess_outbound_config_proto_rawDescData\n}\n\nvar file_proxy_vmess_outbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_vmess_outbound_config_proto_goTypes = []any{\n\t(*Config)(nil),                  // 0: v2ray.core.proxy.vmess.outbound.Config\n\t(*SimplifiedConfig)(nil),        // 1: v2ray.core.proxy.vmess.outbound.SimplifiedConfig\n\t(*protocol.ServerEndpoint)(nil), // 2: v2ray.core.common.protocol.ServerEndpoint\n\t(*net.IPOrDomain)(nil),          // 3: v2ray.core.common.net.IPOrDomain\n}\nvar file_proxy_vmess_outbound_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.vmess.outbound.Config.Receiver:type_name -> v2ray.core.common.protocol.ServerEndpoint\n\t3, // 1: v2ray.core.proxy.vmess.outbound.SimplifiedConfig.address:type_name -> v2ray.core.common.net.IPOrDomain\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_vmess_outbound_config_proto_init() }\nfunc file_proxy_vmess_outbound_config_proto_init() {\n\tif File_proxy_vmess_outbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_vmess_outbound_config_proto_rawDesc), len(file_proxy_vmess_outbound_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_vmess_outbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_vmess_outbound_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_vmess_outbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_vmess_outbound_config_proto = out.File\n\tfile_proxy_vmess_outbound_config_proto_goTypes = nil\n\tfile_proxy_vmess_outbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/vmess/outbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.vmess.outbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Vmess.Outbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\";\noption java_package = \"com.v2ray.core.proxy.vmess.outbound\";\noption java_multiple_files = true;\n\nimport \"common/protocol/server_spec.proto\";\nimport \"common/net/address.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  repeated v2ray.core.common.protocol.ServerEndpoint Receiver = 1;\n}\n\n\nmessage SimplifiedConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"vmess\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  v2ray.core.common.net.IPOrDomain address = 1;\n  uint32 port = 2;\n  string uuid = 3;\n}"
  },
  {
    "path": "proxy/vmess/outbound/errors.generated.go",
    "content": "package outbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/vmess/outbound/outbound.go",
    "content": "package outbound\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"context\"\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"hash/crc64\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/platform\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/encoding\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// Handler is an outbound connection handler for VMess protocol.\ntype Handler struct {\n\tserverList    *protocol.ServerList\n\tserverPicker  protocol.ServerPicker\n\tpolicyManager policy.Manager\n}\n\n// New creates a new VMess outbound handler.\nfunc New(ctx context.Context, config *Config) (*Handler, error) {\n\tserverList := protocol.NewServerList()\n\tfor _, rec := range config.Receiver {\n\t\ts, err := protocol.NewServerSpecFromPB(rec)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to parse server spec\").Base(err)\n\t\t}\n\t\tserverList.AddServer(s)\n\t}\n\n\tv := core.MustFromContext(ctx)\n\thandler := &Handler{\n\t\tserverList:    serverList,\n\t\tserverPicker:  protocol.NewRoundRobinServerPicker(serverList),\n\t\tpolicyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),\n\t}\n\n\treturn handler, nil\n}\n\n// Process implements proxy.Outbound.Process().\nfunc (h *Handler) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\tvar rec *protocol.ServerSpec\n\tvar conn internet.Connection\n\n\terr := retry.ExponentialBackoff(5, 200).On(func() error {\n\t\trec = h.serverPicker.PickServer()\n\t\trawConn, err := dialer.Dial(ctx, rec.Destination())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconn = rawConn\n\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to find an available destination\").Base(err).AtWarning()\n\t}\n\tdefer conn.Close()\n\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\").AtError()\n\t}\n\n\ttarget := outbound.Target\n\tnewError(\"tunneling request to \", target, \" via \", rec.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx))\n\n\tcommand := protocol.RequestCommandTCP\n\tif target.Network == net.Network_UDP {\n\t\tcommand = protocol.RequestCommandUDP\n\t}\n\tif target.Address.Family().IsDomain() && target.Address.Domain() == \"v1.mux.cool\" {\n\t\tcommand = protocol.RequestCommandMux\n\t}\n\n\tuser := rec.PickUser()\n\trequest := &protocol.RequestHeader{\n\t\tVersion: encoding.Version,\n\t\tUser:    user,\n\t\tCommand: command,\n\t\tAddress: target.Address,\n\t\tPort:    target.Port,\n\t\tOption:  protocol.RequestOptionChunkStream,\n\t}\n\n\taccount := request.User.Account.(*vmess.MemoryAccount)\n\trequest.Security = account.Security\n\n\tif request.Security == protocol.SecurityType_AES128_GCM || request.Security == protocol.SecurityType_NONE || request.Security == protocol.SecurityType_CHACHA20_POLY1305 {\n\t\trequest.Option.Set(protocol.RequestOptionChunkMasking)\n\t}\n\n\tif shouldEnablePadding(request.Security) && request.Option.Has(protocol.RequestOptionChunkMasking) {\n\t\trequest.Option.Set(protocol.RequestOptionGlobalPadding)\n\t}\n\n\tif request.Security == protocol.SecurityType_ZERO {\n\t\trequest.Security = protocol.SecurityType_NONE\n\t\trequest.Option.Clear(protocol.RequestOptionChunkStream)\n\t\trequest.Option.Clear(protocol.RequestOptionChunkMasking)\n\t}\n\n\tif account.AuthenticatedLengthExperiment {\n\t\trequest.Option.Set(protocol.RequestOptionAuthenticatedLength)\n\t}\n\n\tinput := link.Reader\n\toutput := link.Writer\n\n\tisAEAD := false\n\tif !aeadDisabled && len(account.AlterIDs) == 0 {\n\t\tisAEAD = true\n\t}\n\n\thashkdf := hmac.New(sha256.New, []byte(\"VMessBF\"))\n\thashkdf.Write(account.ID.Bytes())\n\n\tbehaviorSeed := crc64.Checksum(hashkdf.Sum(nil), crc64.MakeTable(crc64.ISO))\n\n\tsession := encoding.NewClientSession(ctx, isAEAD, protocol.DefaultIDHash, int64(behaviorSeed))\n\tsessionPolicy := h.policyManager.ForLevel(request.User.Level)\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)\n\n\trequestDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)\n\n\t\twriter := buf.NewBufferedWriter(buf.NewWriter(conn))\n\t\tif err := session.EncodeRequestHeader(request, writer); err != nil {\n\t\t\treturn newError(\"failed to encode request\").Base(err).AtWarning()\n\t\t}\n\n\t\tbodyWriter, err := session.EncodeRequestBody(request, writer)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to start encoding\").Base(err)\n\t\t}\n\t\tif err := buf.CopyOnceTimeout(input, bodyWriter, proxy.FirstPayloadTimeout); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {\n\t\t\treturn newError(\"failed to write first payload\").Base(err)\n\t\t}\n\n\t\tif err := writer.SetBuffered(false); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err := buf.Copy(input, bodyWriter, buf.UpdateActivity(timer)); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif request.Option.Has(protocol.RequestOptionChunkStream) && !account.NoTerminationSignal {\n\t\t\tif err := bodyWriter.WriteMultiBuffer(buf.MultiBuffer{}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tresponseDone := func() error {\n\t\tdefer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)\n\n\t\treader := &buf.BufferedReader{Reader: buf.NewReader(conn)}\n\t\theader, err := session.DecodeResponseHeader(reader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to read header\").Base(err)\n\t\t}\n\t\th.handleCommand(rec.Destination(), header.Command)\n\n\t\tbodyReader, err := session.DecodeResponseBody(request, reader)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to start encoding response\").Base(err)\n\t\t}\n\t\treturn buf.Copy(bodyReader, output, buf.UpdateActivity(timer))\n\t}\n\n\tresponseDonePost := task.OnSuccess(responseDone, task.Close(output))\n\tif err := task.Run(ctx, requestDone, responseDonePost); err != nil {\n\t\treturn newError(\"connection ends\").Base(err)\n\t}\n\n\treturn nil\n}\n\nvar (\n\tenablePadding = false\n\taeadDisabled  = false\n)\n\nfunc shouldEnablePadding(s protocol.SecurityType) bool {\n\treturn enablePadding || s == protocol.SecurityType_AES128_GCM || s == protocol.SecurityType_CHACHA20_POLY1305 || s == protocol.SecurityType_AUTO\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn New(ctx, config.(*Config))\n\t}))\n\n\tcommon.Must(common.RegisterConfig((*SimplifiedConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tsimplifiedClient := config.(*SimplifiedConfig)\n\t\tfullClient := &Config{Receiver: []*protocol.ServerEndpoint{\n\t\t\t{\n\t\t\t\tAddress: simplifiedClient.Address,\n\t\t\t\tPort:    simplifiedClient.Port,\n\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t{\n\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{Id: simplifiedClient.Uuid}),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}}\n\n\t\treturn common.CreateObject(ctx, fullClient)\n\t}))\n\n\tconst defaultFlagValue = \"NOT_DEFINED_AT_ALL\"\n\n\tpaddingValue := platform.NewEnvFlag(\"v2ray.vmess.padding\").GetValue(func() string { return defaultFlagValue })\n\tif paddingValue != defaultFlagValue {\n\t\tenablePadding = true\n\t}\n\n\tisAeadDisabled := platform.NewEnvFlag(\"v2ray.vmess.aead.disabled\").GetValue(func() string { return defaultFlagValue })\n\tif isAeadDisabled == \"true\" {\n\t\taeadDisabled = true\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/validator.go",
    "content": "package vmess\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"hash/crc64\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/aead\"\n)\n\nconst (\n\tupdateInterval   = 10 * time.Second\n\tcacheDurationSec = 120\n)\n\ntype user struct {\n\tuser    protocol.MemoryUser\n\tlastSec protocol.Timestamp\n}\n\n// TimedUserValidator is a user Validator based on time.\ntype TimedUserValidator struct {\n\tsync.RWMutex\n\tusers    []*user\n\tuserHash map[[16]byte]indexTimePair\n\thasher   protocol.IDHash\n\tbaseTime protocol.Timestamp\n\ttask     *task.Periodic\n\n\tbehaviorSeed  uint64\n\tbehaviorFused bool\n\n\taeadDecoderHolder *aead.AuthIDDecoderHolder\n\n\tlegacyWarnShown bool\n}\n\ntype indexTimePair struct {\n\tuser    *user\n\ttimeInc uint32\n\n\ttaintedFuse *uint32\n}\n\n// NewTimedUserValidator creates a new TimedUserValidator.\nfunc NewTimedUserValidator(hasher protocol.IDHash) *TimedUserValidator {\n\ttuv := &TimedUserValidator{\n\t\tusers:             make([]*user, 0, 16),\n\t\tuserHash:          make(map[[16]byte]indexTimePair, 1024),\n\t\thasher:            hasher,\n\t\tbaseTime:          protocol.Timestamp(time.Now().Unix() - cacheDurationSec*2),\n\t\taeadDecoderHolder: aead.NewAuthIDDecoderHolder(),\n\t}\n\ttuv.task = &task.Periodic{\n\t\tInterval: updateInterval,\n\t\tExecute: func() error {\n\t\t\ttuv.updateUserHash()\n\t\t\treturn nil\n\t\t},\n\t}\n\tcommon.Must(tuv.task.Start())\n\treturn tuv\n}\n\n// visible for testing\nfunc (v *TimedUserValidator) GetBaseTime() protocol.Timestamp {\n\treturn v.baseTime\n}\n\nfunc (v *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, user *user) {\n\tvar hashValue [16]byte\n\tgenEndSec := nowSec + cacheDurationSec\n\tgenHashForID := func(id *protocol.ID) {\n\t\tidHash := v.hasher(id.Bytes())\n\t\tgenBeginSec := user.lastSec\n\t\tif genBeginSec < nowSec-cacheDurationSec {\n\t\t\tgenBeginSec = nowSec - cacheDurationSec\n\t\t}\n\t\tfor ts := genBeginSec; ts <= genEndSec; ts++ {\n\t\t\tcommon.Must2(serial.WriteUint64(idHash, uint64(ts)))\n\t\t\tidHash.Sum(hashValue[:0])\n\t\t\tidHash.Reset()\n\n\t\t\tv.userHash[hashValue] = indexTimePair{\n\t\t\t\tuser:        user,\n\t\t\t\ttimeInc:     uint32(ts - v.baseTime),\n\t\t\t\ttaintedFuse: new(uint32),\n\t\t\t}\n\t\t}\n\t}\n\n\taccount := user.user.Account.(*MemoryAccount)\n\n\tgenHashForID(account.ID)\n\tfor _, id := range account.AlterIDs {\n\t\tgenHashForID(id)\n\t}\n\tuser.lastSec = genEndSec\n}\n\nfunc (v *TimedUserValidator) removeExpiredHashes(expire uint32) {\n\tfor key, pair := range v.userHash {\n\t\tif pair.timeInc < expire {\n\t\t\tdelete(v.userHash, key)\n\t\t}\n\t}\n}\n\nfunc (v *TimedUserValidator) updateUserHash() {\n\tnow := time.Now()\n\tnowSec := protocol.Timestamp(now.Unix())\n\n\tv.Lock()\n\tdefer v.Unlock()\n\n\tfor _, user := range v.users {\n\t\tv.generateNewHashes(nowSec, user)\n\t}\n\n\texpire := protocol.Timestamp(now.Unix() - cacheDurationSec)\n\tif expire > v.baseTime {\n\t\tv.removeExpiredHashes(uint32(expire - v.baseTime))\n\t}\n}\n\nfunc (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {\n\tv.Lock()\n\tdefer v.Unlock()\n\n\tnowSec := time.Now().Unix()\n\n\tuu := &user{\n\t\tuser:    *u,\n\t\tlastSec: protocol.Timestamp(nowSec - cacheDurationSec),\n\t}\n\tv.users = append(v.users, uu)\n\tv.generateNewHashes(protocol.Timestamp(nowSec), uu)\n\n\taccount := uu.user.Account.(*MemoryAccount)\n\tif !v.behaviorFused {\n\t\thashkdf := hmac.New(sha256.New, []byte(\"VMESSBSKDF\"))\n\t\thashkdf.Write(account.ID.Bytes())\n\t\tv.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil))\n\t}\n\n\tvar cmdkeyfl [16]byte\n\tcopy(cmdkeyfl[:], account.ID.CmdKey())\n\tv.aeadDecoderHolder.AddUser(cmdkeyfl, u)\n\n\treturn nil\n}\n\nfunc (v *TimedUserValidator) Get(userHash []byte) (*protocol.MemoryUser, protocol.Timestamp, bool, error) {\n\tv.RLock()\n\tdefer v.RUnlock()\n\n\tv.behaviorFused = true\n\n\tvar fixedSizeHash [16]byte\n\tcopy(fixedSizeHash[:], userHash)\n\tpair, found := v.userHash[fixedSizeHash]\n\tif found {\n\t\tuser := pair.user.user\n\t\tif atomic.LoadUint32(pair.taintedFuse) == 0 {\n\t\t\treturn &user, protocol.Timestamp(pair.timeInc) + v.baseTime, true, nil\n\t\t}\n\t\treturn nil, 0, false, ErrTainted\n\t}\n\treturn nil, 0, false, ErrNotFound\n}\n\nfunc (v *TimedUserValidator) GetAEAD(userHash []byte) (*protocol.MemoryUser, bool, error) {\n\tv.RLock()\n\tdefer v.RUnlock()\n\n\tvar userHashFL [16]byte\n\tcopy(userHashFL[:], userHash)\n\n\tuserd, err := v.aeadDecoderHolder.Match(userHashFL)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\treturn userd.(*protocol.MemoryUser), true, err\n}\n\nfunc (v *TimedUserValidator) Remove(email string) bool {\n\tv.Lock()\n\tdefer v.Unlock()\n\n\temail = strings.ToLower(email)\n\tidx := -1\n\tfor i, u := range v.users {\n\t\tif strings.EqualFold(u.user.Email, email) {\n\t\t\tidx = i\n\t\t\tvar cmdkeyfl [16]byte\n\t\t\tcopy(cmdkeyfl[:], u.user.Account.(*MemoryAccount).ID.CmdKey())\n\t\t\tv.aeadDecoderHolder.RemoveUser(cmdkeyfl)\n\t\t\tbreak\n\t\t}\n\t}\n\tif idx == -1 {\n\t\treturn false\n\t}\n\tulen := len(v.users)\n\n\tv.users[idx] = v.users[ulen-1]\n\tv.users[ulen-1] = nil\n\tv.users = v.users[:ulen-1]\n\n\treturn true\n}\n\n// Close implements common.Closable.\nfunc (v *TimedUserValidator) Close() error {\n\treturn v.task.Close()\n}\n\nfunc (v *TimedUserValidator) GetBehaviorSeed() uint64 {\n\tv.Lock()\n\tdefer v.Unlock()\n\n\tv.behaviorFused = true\n\tif v.behaviorSeed == 0 {\n\t\tv.behaviorSeed = dice.RollUint64()\n\t}\n\treturn v.behaviorSeed\n}\n\nfunc (v *TimedUserValidator) BurnTaintFuse(userHash []byte) error {\n\tv.RLock()\n\tdefer v.RUnlock()\n\n\tvar userHashFL [16]byte\n\tcopy(userHashFL[:], userHash)\n\n\tpair, found := v.userHash[userHashFL]\n\tif found {\n\t\tif atomic.CompareAndSwapUint32(pair.taintedFuse, 0, 1) {\n\t\t\treturn nil\n\t\t}\n\t\treturn ErrTainted\n\t}\n\treturn ErrNotFound\n}\n\n/*\n\tShouldShowLegacyWarn will return whether a Legacy Warning should be shown\n\nNot guaranteed to only return true once for every inbound, but it is okay.\n*/\nfunc (v *TimedUserValidator) ShouldShowLegacyWarn() bool {\n\tif v.legacyWarnShown {\n\t\treturn false\n\t}\n\tv.legacyWarnShown = true\n\treturn true\n}\n\nvar ErrNotFound = newError(\"Not Found\")\n\nvar ErrTainted = newError(\"ErrTainted\")\n"
  },
  {
    "path": "proxy/vmess/validator_test.go",
    "content": "package vmess_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t. \"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n)\n\nfunc toAccount(a *Account) protocol.Account {\n\taccount, err := a.AsAccount()\n\tcommon.Must(err)\n\treturn account\n}\n\nfunc TestUserValidator(t *testing.T) {\n\thasher := protocol.DefaultIDHash\n\tv := NewTimedUserValidator(hasher)\n\tdefer common.Close(v)\n\n\tid := uuid.New()\n\tuser := &protocol.MemoryUser{\n\t\tEmail: \"test\",\n\t\tAccount: toAccount(&Account{\n\t\t\tId:      id.String(),\n\t\t\tAlterId: 8,\n\t\t}),\n\t}\n\tcommon.Must(v.Add(user))\n\n\t{\n\t\ttestSmallLag := func(lag int64) {\n\t\t\tts := int64(v.GetBaseTime()) + lag + 240\n\t\t\tidHash := hasher(id.Bytes())\n\t\t\tcommon.Must2(serial.WriteUint64(idHash, uint64(ts)))\n\t\t\tuserHash := idHash.Sum(nil)\n\n\t\t\teuser, ets, found, _ := v.Get(userHash)\n\t\t\tif !found {\n\t\t\t\tt.Fatal(\"user not found\")\n\t\t\t}\n\t\t\tif euser.Email != user.Email {\n\t\t\t\tt.Error(\"unexpected user email: \", euser.Email, \" want \", user.Email)\n\t\t\t}\n\t\t\tif int64(ets) != ts {\n\t\t\t\tt.Error(\"unexpected timestamp: \", ets, \" want \", ts)\n\t\t\t}\n\t\t}\n\n\t\ttestSmallLag(0)\n\t\ttestSmallLag(40)\n\t\ttestSmallLag(-40)\n\t\ttestSmallLag(80)\n\t\ttestSmallLag(-80)\n\t\ttestSmallLag(120)\n\t\ttestSmallLag(-120)\n\t}\n\n\t{\n\t\ttestBigLag := func(lag int64) {\n\t\t\tts := int64(v.GetBaseTime()) + lag + 240\n\t\t\tidHash := hasher(id.Bytes())\n\t\t\tcommon.Must2(serial.WriteUint64(idHash, uint64(ts)))\n\t\t\tuserHash := idHash.Sum(nil)\n\n\t\t\teuser, _, found, _ := v.Get(userHash)\n\t\t\tif found || euser != nil {\n\t\t\t\tt.Error(\"unexpected user\")\n\t\t\t}\n\t\t}\n\n\t\ttestBigLag(121)\n\t\ttestBigLag(-121)\n\t\ttestBigLag(310)\n\t\ttestBigLag(-310)\n\t\ttestBigLag(500)\n\t\ttestBigLag(-500)\n\t}\n\n\tif v := v.Remove(user.Email); !v {\n\t\tt.Error(\"unable to remove user\")\n\t}\n\tif v := v.Remove(user.Email); v {\n\t\tt.Error(\"remove user twice\")\n\t}\n}\n\nfunc BenchmarkUserValidator(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\thasher := protocol.DefaultIDHash\n\t\tv := NewTimedUserValidator(hasher)\n\n\t\tfor j := 0; j < 1500; j++ {\n\t\t\tid := uuid.New()\n\t\t\tv.Add(&protocol.MemoryUser{\n\t\t\t\tEmail: \"test\",\n\t\t\t\tAccount: toAccount(&Account{\n\t\t\t\t\tId:      id.String(),\n\t\t\t\t\tAlterId: 16,\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\tcommon.Close(v)\n\t}\n}\n"
  },
  {
    "path": "proxy/vmess/vmess.go",
    "content": "// Package vmess contains the implementation of VMess protocol and transportation.\n//\n// VMess contains both inbound and outbound connections. VMess inbound is usually used on servers\n// together with 'freedom' to talk to final destination, while VMess outbound is usually used on\n// clients with 'socks' for proxying.\npackage vmess\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/vmess/vmessCtxInterface.go",
    "content": "package vmess\n\n// example\nconst AlterID = \"VMessCtxInterface_AlterID\"\n"
  },
  {
    "path": "proxy/wireguard/outbound/config.pb.go",
    "content": "package outbound\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\tgvisorstack \"github.com/v2fly/v2ray-core/v5/common/packetswitch/gvisorstack\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\twgcommon \"github.com/v2fly/v2ray-core/v5/proxy/wireguard/wgcommon\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config_DomainStrategy int32\n\nconst (\n\tConfig_AS_IS   Config_DomainStrategy = 0\n\tConfig_USE_IP  Config_DomainStrategy = 1\n\tConfig_USE_IP4 Config_DomainStrategy = 2\n\tConfig_USE_IP6 Config_DomainStrategy = 3\n)\n\n// Enum value maps for Config_DomainStrategy.\nvar (\n\tConfig_DomainStrategy_name = map[int32]string{\n\t\t0: \"AS_IS\",\n\t\t1: \"USE_IP\",\n\t\t2: \"USE_IP4\",\n\t\t3: \"USE_IP6\",\n\t}\n\tConfig_DomainStrategy_value = map[string]int32{\n\t\t\"AS_IS\":   0,\n\t\t\"USE_IP\":  1,\n\t\t\"USE_IP4\": 2,\n\t\t\"USE_IP6\": 3,\n\t}\n)\n\nfunc (x Config_DomainStrategy) Enum() *Config_DomainStrategy {\n\tp := new(Config_DomainStrategy)\n\t*p = x\n\treturn p\n}\n\nfunc (x Config_DomainStrategy) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Config_DomainStrategy) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_proxy_wireguard_outbound_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Config_DomainStrategy) Type() protoreflect.EnumType {\n\treturn &file_proxy_wireguard_outbound_config_proto_enumTypes[0]\n}\n\nfunc (x Config_DomainStrategy) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Config_DomainStrategy.Descriptor instead.\nfunc (Config_DomainStrategy) EnumDescriptor() ([]byte, []int) {\n\treturn file_proxy_wireguard_outbound_config_proto_rawDescGZIP(), []int{0, 0}\n}\n\ntype Config struct {\n\tstate    protoimpl.MessageState `protogen:\"open.v1\"`\n\tWgDevice *wgcommon.DeviceConfig `protobuf:\"bytes,1,opt,name=wg_device,json=wgDevice,proto3\" json:\"wg_device,omitempty\"`\n\tStack    *gvisorstack.Config    `protobuf:\"bytes,2,opt,name=stack,proto3\" json:\"stack,omitempty\"`\n\t// v2ray.core.net.packetaddr.PacketAddrType outbound_packet_encoding = 3;\n\tListenOnSystemNetwork bool                  `protobuf:\"varint,4,opt,name=listen_on_system_network,json=listenOnSystemNetwork,proto3\" json:\"listen_on_system_network,omitempty\"`\n\tDomainStrategy        Config_DomainStrategy `protobuf:\"varint,5,opt,name=domain_strategy,json=domainStrategy,proto3,enum=v2ray.core.proxy.wireguard.outbound.Config_DomainStrategy\" json:\"domain_strategy,omitempty\"`\n\tunknownFields         protoimpl.UnknownFields\n\tsizeCache             protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_proxy_wireguard_outbound_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_wireguard_outbound_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_proxy_wireguard_outbound_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetWgDevice() *wgcommon.DeviceConfig {\n\tif x != nil {\n\t\treturn x.WgDevice\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetStack() *gvisorstack.Config {\n\tif x != nil {\n\t\treturn x.Stack\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetListenOnSystemNetwork() bool {\n\tif x != nil {\n\t\treturn x.ListenOnSystemNetwork\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetDomainStrategy() Config_DomainStrategy {\n\tif x != nil {\n\t\treturn x.DomainStrategy\n\t}\n\treturn Config_AS_IS\n}\n\nvar File_proxy_wireguard_outbound_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_wireguard_outbound_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"%proxy/wireguard/outbound/config.proto\\x12#v2ray.core.proxy.wireguard.outbound\\x1a%proxy/wireguard/wgcommon/config.proto\\x1a,common/packetswitch/gvisorstack/config.proto\\x1a\\\"common/net/packetaddr/config.proto\\x1a common/protoext/extensions.proto\\\"\\x9e\\x03\\n\" +\n\t\"\\x06Config\\x12N\\n\" +\n\t\"\\twg_device\\x18\\x01 \\x01(\\v21.v2ray.core.proxy.wireguard.wgcommon.DeviceConfigR\\bwgDevice\\x12H\\n\" +\n\t\"\\x05stack\\x18\\x02 \\x01(\\v22.v2ray.core.common.packetswitch.gvisorstack.ConfigR\\x05stack\\x127\\n\" +\n\t\"\\x18listen_on_system_network\\x18\\x04 \\x01(\\bR\\x15listenOnSystemNetwork\\x12c\\n\" +\n\t\"\\x0fdomain_strategy\\x18\\x05 \\x01(\\x0e2:.v2ray.core.proxy.wireguard.outbound.Config.DomainStrategyR\\x0edomainStrategy\\\"A\\n\" +\n\t\"\\x0eDomainStrategy\\x12\\t\\n\" +\n\t\"\\x05AS_IS\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06USE_IP\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aUSE_IP4\\x10\\x02\\x12\\v\\n\" +\n\t\"\\aUSE_IP6\\x10\\x03:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\boutbound\\x12\\twireguardB\\x8a\\x01\\n\" +\n\t\"'com.v2ray.core.proxy.wireguard.outboundP\\x01Z7github.com/v2fly/v2ray-core/v5/proxy/wireguard/outbound\\xaa\\x02#V2Ray.Core.Proxy.Wireguard.Outboundb\\x06proto3\"\n\nvar (\n\tfile_proxy_wireguard_outbound_config_proto_rawDescOnce sync.Once\n\tfile_proxy_wireguard_outbound_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_wireguard_outbound_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_wireguard_outbound_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_wireguard_outbound_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_wireguard_outbound_config_proto_rawDesc), len(file_proxy_wireguard_outbound_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_wireguard_outbound_config_proto_rawDescData\n}\n\nvar file_proxy_wireguard_outbound_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_proxy_wireguard_outbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_proxy_wireguard_outbound_config_proto_goTypes = []any{\n\t(Config_DomainStrategy)(0),    // 0: v2ray.core.proxy.wireguard.outbound.Config.DomainStrategy\n\t(*Config)(nil),                // 1: v2ray.core.proxy.wireguard.outbound.Config\n\t(*wgcommon.DeviceConfig)(nil), // 2: v2ray.core.proxy.wireguard.wgcommon.DeviceConfig\n\t(*gvisorstack.Config)(nil),    // 3: v2ray.core.common.packetswitch.gvisorstack.Config\n}\nvar file_proxy_wireguard_outbound_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.proxy.wireguard.outbound.Config.wg_device:type_name -> v2ray.core.proxy.wireguard.wgcommon.DeviceConfig\n\t3, // 1: v2ray.core.proxy.wireguard.outbound.Config.stack:type_name -> v2ray.core.common.packetswitch.gvisorstack.Config\n\t0, // 2: v2ray.core.proxy.wireguard.outbound.Config.domain_strategy:type_name -> v2ray.core.proxy.wireguard.outbound.Config.DomainStrategy\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_proxy_wireguard_outbound_config_proto_init() }\nfunc file_proxy_wireguard_outbound_config_proto_init() {\n\tif File_proxy_wireguard_outbound_config_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: unsafe.Slice(unsafe.StringData(file_proxy_wireguard_outbound_config_proto_rawDesc), len(file_proxy_wireguard_outbound_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_wireguard_outbound_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_wireguard_outbound_config_proto_depIdxs,\n\t\tEnumInfos:         file_proxy_wireguard_outbound_config_proto_enumTypes,\n\t\tMessageInfos:      file_proxy_wireguard_outbound_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_wireguard_outbound_config_proto = out.File\n\tfile_proxy_wireguard_outbound_config_proto_goTypes = nil\n\tfile_proxy_wireguard_outbound_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/wireguard/outbound/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.wireguard.outbound;\noption csharp_namespace = \"V2Ray.Core.Proxy.Wireguard.Outbound\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/wireguard/outbound\";\noption java_package = \"com.v2ray.core.proxy.wireguard.outbound\";\noption java_multiple_files = true;\n\nimport \"proxy/wireguard/wgcommon/config.proto\";\nimport \"common/packetswitch/gvisorstack/config.proto\";\nimport \"common/net/packetaddr/config.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config{\n  option (v2ray.core.common.protoext.message_opt).type = \"outbound\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"wireguard\";\n\n  v2ray.core.proxy.wireguard.wgcommon.DeviceConfig wg_device = 1;\n  v2ray.core.common.packetswitch.gvisorstack.Config stack = 2;\n\n  //v2ray.core.net.packetaddr.PacketAddrType outbound_packet_encoding = 3;\n  bool listen_on_system_network = 4;\n\n  enum DomainStrategy {\n    AS_IS = 0;\n    USE_IP = 1;\n    USE_IP4 = 2;\n    USE_IP6 = 3;\n  }\n  DomainStrategy domain_strategy = 5;\n}"
  },
  {
    "path": "proxy/wireguard/outbound/errors.generated.go",
    "content": "package outbound\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/wireguard/outbound/outbound.go",
    "content": "package outbound\n\nimport (\n\t\"context\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dualStack/happyEyeball\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tcnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch/gvisorstack\"\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch/interconnect\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/wireguard/wgcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc NewWireguardOutbound(ctx context.Context, config *Config) (*WireguardOutbound, error) {\n\tw := &WireguardOutbound{\n\t\tctx:    ctx,\n\t\tconfig: config,\n\t}\n\t// Acquire dns client feature if available\n\tif err := core.RequireFeatures(ctx, func(d dns.Client) error {\n\t\tw.dnsClient = d\n\t\treturn nil\n\t}); err != nil {\n\t\treturn nil, newError(\"failed to require dns client feature\").Base(err)\n\t}\n\tstorage := envctx.EnvironmentFromContext(ctx).(environment.ProxyEnvironment).TransientStorage()\n\n\tudpState, err := NewClientConnState()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create UDP connection state\").Base(err)\n\t}\n\tif err := storage.Put(ctx, ConnectionState, udpState); err != nil {\n\t\treturn nil, newError(\"failed to put connection state\").Base(err)\n\t}\n\treturn w, nil\n}\n\ntype WireguardOutbound struct {\n\tctx    context.Context\n\tconfig *Config\n\n\tdnsClient dns.Client\n}\n\ntype WireguardOutboundSession struct {\n\tctx    context.Context\n\tconfig *Config\n\n\tstack           *gvisorstack.WrappedStack\n\twireguardDevice *wgcommon.WrappedWireguardDevice\n\tinterconnect    *interconnect.NetworkLayerCable\n\n\t// system packet conn used when ListenOnSystemNetwork is true\n\tsystemPacketConn internet.PacketConn\n\n\tdnsClient dns.Client\n}\n\nfunc (s *WireguardOutboundSession) initFromConfig(ctx context.Context, config *Config) error {\n\tif config == nil {\n\t\treturn newError(\"nil config\")\n\t}\n\t// create interconnect cable\n\tcable, err := interconnect.NewNetworkLayerCable(ctx)\n\tif err != nil {\n\t\treturn newError(\"failed to create interconnect cable\").Base(err)\n\t}\n\ts.interconnect = cable\n\n\t// create wireguard device wrapper\n\twd, err := wgcommon.NewWrappedWireguardDevice(ctx, config.GetWgDevice())\n\tif err != nil {\n\t\treturn newError(\"failed to create wireguard device\").Base(err)\n\t}\n\ts.wireguardDevice = wd\n\t// attach device tunnel to left side of cable\n\ts.wireguardDevice.SetTunnel(cable.GetLSideDevice())\n\n\t// create gvisor stack wrapper if stack config is provided\n\tif config.GetStack() != nil {\n\t\tst, err := gvisorstack.NewStack(ctx, config.GetStack())\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create gvisor stack\").Base(err)\n\t\t}\n\t\ts.stack = st\n\t\tif err := s.stack.CreateStackFromNetworkLayerDevice(cable.GetRSideDevice()); err != nil {\n\t\t\treturn newError(\"failed to create stack from network layer device\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nconst ConnectionState = \"ConnectionState\"\n\ntype ClientConnState struct {\n\tsession  *WireguardOutboundSession\n\tinitOnce *sync.Once\n\tmu       sync.Mutex\n}\n\nfunc (c *ClientConnState) GetOrCreateSession(create func() (*WireguardOutboundSession, error)) (*WireguardOutboundSession, error) {\n\tvar errOuter error\n\tc.initOnce.Do(func() {\n\t\tsess, err := create()\n\t\tif err != nil {\n\t\t\terrOuter = err\n\t\t\treturn\n\t\t}\n\t\tc.mu.Lock()\n\t\tc.session = sess\n\t\tc.mu.Unlock()\n\t})\n\tif errOuter != nil {\n\t\treturn nil, newError(\"failed to initialize UDP State\").Base(errOuter)\n\t}\n\treturn c.session, nil\n}\n\nfunc (c *ClientConnState) IsTransientStorageLifecycleReceiver() {}\n\nfunc (c *ClientConnState) Close() error {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tif c.session == nil {\n\t\treturn nil\n\t}\n\tsess := c.session\n\tc.session = nil\n\n\t// close interconnect devices first to stop any further packet injections\n\tif sess.interconnect != nil {\n\t\t_ = sess.interconnect.GetLSideDevice().Close()\n\t\t_ = sess.interconnect.GetRSideDevice().Close()\n\t\tsess.interconnect = nil\n\t}\n\n\t// close system packet conn\n\tif sess.systemPacketConn != nil {\n\t\t_ = sess.systemPacketConn.Close()\n\t\tsess.systemPacketConn = nil\n\t}\n\n\t// close wireguard device\n\tif sess.wireguardDevice != nil {\n\t\t_ = sess.wireguardDevice.Close()\n\t\tsess.wireguardDevice = nil\n\t}\n\n\t// Close stack last to quiesce any gVisor internal goroutines that may\n\t// hold references to PacketBuffers (prevents dec-ref races).\n\tif sess.stack != nil {\n\t\t_ = sess.stack.Close()\n\t\tsess.stack = nil\n\t}\n\n\treturn nil\n}\n\nfunc (w *WireguardOutbound) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {\n\t// keep dialer for address family preference when resolving domain\n\t_ = dialer\n\tstorage := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment).TransientStorage()\n\tstateIfc, err := storage.Get(ctx, ConnectionState)\n\tif err != nil {\n\t\treturn newError(\"failed to get connection state\").Base(err)\n\t}\n\tclientState, ok := stateIfc.(*ClientConnState)\n\tif !ok {\n\t\treturn newError(\"bad connection state\")\n\t}\n\n\t// create session if needed\n\tsess, err := clientState.GetOrCreateSession(func() (*WireguardOutboundSession, error) {\n\t\ts := &WireguardOutboundSession{ctx: ctx, config: w.config}\n\t\ts.dnsClient = w.dnsClient\n\t\tif err := s.initFromConfig(ctx, w.config); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif !w.config.ListenOnSystemNetwork {\n\t\t\t// SORRRRRY, I tried but it was v2ray's udp support was too difficult to work with\n\t\t\treturn nil, newError(\"unimplemented: listenOnSystemNetwork=false is not implemented yet\")\n\t\t}\n\n\t\tpacketConn, err := internet.ListenSystemPacket(w.ctx, &gonet.UDPAddr{IP: cnet.AnyIP.IP(), Port: 0}, nil)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen on system network\").Base(err)\n\t\t}\n\n\t\ts.systemPacketConn = packetConn\n\t\ts.wireguardDevice.SetConn(packetConn)\n\n\t\t// initialize wireguard device now that conn present\n\t\tif err := s.wireguardDevice.InitDevice(); err != nil {\n\t\t\treturn nil, newError(\"failed to init wireguard device\").Base(err)\n\t\t}\n\t\tif err := s.wireguardDevice.SetupDeviceWithoutPeers(); err != nil {\n\t\t\treturn nil, newError(\"failed to setup wireguard device\").Base(err)\n\t\t}\n\t\tif err := s.wireguardDevice.AddOrReplacePeers(s.config.WgDevice.GetPeers()); err != nil {\n\t\t\treturn nil, newError(\"failed to add peers\").Base(err)\n\t\t}\n\t\tif err := s.wireguardDevice.Up(); err != nil {\n\t\t\treturn nil, newError(\"failed to bring up wireguard device\").Base(err)\n\t\t}\n\t\treturn s, nil\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to create or fetch session\").Base(err)\n\t}\n\n\t{\n\t\tdebugData, err := sess.wireguardDevice.Debug()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to debug wireguard device\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t\tnewError(\"wireguard device debug: \\n\", debugData).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\toutbound := session.OutboundFromContext(ctx)\n\tif outbound == nil || !outbound.Target.IsValid() {\n\t\treturn newError(\"target not specified\")\n\t}\n\tdestination := outbound.Target\n\n\t// require gVisor stack to process network-level connections\n\tif sess.stack == nil {\n\t\treturn newError(\"gvisor stack is not configured for wireguard outbound\")\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\ttimer := signal.CancelAfterInactivity(ctx, cancel, time.Second*300)\n\tdefer cancel()\n\n\tif packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {\n\t\tdefer func() { _ = packetConn.Close() }()\n\t\tpc, err := sess.stack.ListenUDP(ctx, cnet.UDPDestination(nil, 0))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create udp session in stack\").Base(err)\n\t\t}\n\t\tdefer func() { _ = pc.Close() }()\n\n\t\t// Run copy loops and explicitly close resources afterwards to avoid leaks.\n\t\terr = nil\n\t\tfunc() {\n\t\t\trequestDone := func() error {\n\t\t\t\tprotocolWriter := pc\n\t\t\t\treturn udp.CopyPacketConn(protocolWriter, packetConn, udp.UpdateActivity(timer))\n\t\t\t}\n\t\t\tresponseDone := func() error {\n\t\t\t\tprotocolReader := pc\n\t\t\t\treturn udp.CopyPacketConn(packetConn, protocolReader, udp.UpdateActivity(timer))\n\t\t\t}\n\t\t\tresponseDoneAndCloseWriter := task.OnSuccess(responseDone, task.Close(link.Writer))\n\t\t\terr = task.Run(ctx, requestDone, responseDoneAndCloseWriter)\n\t\t}()\n\n\t\tif err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\t}\n\n\tswitch destination.Network {\n\tcase cnet.Network_TCP:\n\t\t// Dial TCP inside the virtual stack\n\t\tips := w.resolveDNSName(ctx, destination, sess)\n\n\t\tvar dialedConn gonet.Conn\n\t\tif len(ips) == 0 {\n\t\t\tconn, err := sess.stack.DialTCP(ctx, destination)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to dial tcp in stack\").Base(err)\n\t\t\t}\n\t\t\tdialedConn = conn\n\t\t\tnewError(\"dialed \", destination, \" with no DNS resolution\").AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\t\t} else {\n\t\t\tconn, err := happyEyeball.RacingDialer(ctx, destination, ips, func(ctx context.Context, domainDestination cnet.Destination, ips cnet.IP) (internet.Connection, error) {\n\t\t\t\tdest := cnet.Destination{Network: domainDestination.Network, Address: cnet.IPAddress(ips), Port: domainDestination.Port}\n\t\t\t\treturn sess.stack.DialTCP(ctx, dest)\n\t\t\t}, true, time.Millisecond*300)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to dial tcp in stack with racing dialer\").Base(err)\n\t\t\t}\n\t\t\tdialedConn = conn\n\t\t}\n\n\t\tdefer func() { _ = dialedConn.Close() }()\n\n\t\trequestDone := func() error {\n\t\t\twriter := buf.NewWriter(dialedConn)\n\t\t\tif err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\treturn newError(\"failed to copy request\").Base(err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tresponseDone := func() error {\n\t\t\treader := buf.NewReader(dialedConn)\n\t\t\tif err := buf.Copy(reader, link.Writer, buf.UpdateActivity(timer)); err != nil {\n\t\t\t\treturn newError(\"failed to copy response\").Base(err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := task.Run(ctx, requestDone, task.OnSuccess(responseDone, task.Close(link.Writer))); err != nil {\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\n\tcase cnet.Network_UDP:\n\t\t// Create a packet conn on the stack and use mono-dest adapter\n\t\tpc, err := sess.stack.ListenUDP(ctx, cnet.UDPDestination(nil, 0))\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create udp session in stack\").Base(err)\n\t\t}\n\t\tmono := udp.NewMonoDestUDPConn(pc, &gonet.UDPAddr{IP: destination.Address.IP(), Port: int(destination.Port)})\n\n\t\trequestDone := func() error {\n\t\t\treturn buf.Copy(link.Reader, mono, buf.UpdateActivity(timer))\n\t\t}\n\t\tresponseDone := func() error {\n\t\t\treturn buf.Copy(mono, link.Writer, buf.UpdateActivity(timer))\n\t\t}\n\n\t\tif err := task.Run(ctx, requestDone, task.OnSuccess(responseDone, task.Close(link.Writer))); err != nil {\n\t\t\t_ = pc.Close()\n\t\t\treturn newError(\"connection ends\").Base(err)\n\t\t}\n\t\treturn nil\n\n\tdefault:\n\t\treturn newError(\"unsupported network: \", destination.Network)\n\t}\n}\n\nfunc (w *WireguardOutbound) resolveDNSName(ctx context.Context, destination cnet.Destination, sess *WireguardOutboundSession) []cnet.IP {\n\t// resolve domain names using dns client if necessary\n\tif destination.Address != nil && destination.Address.Family().IsDomain() && sess.dnsClient != nil {\n\t\tdomain := destination.Address.Domain()\n\t\topt := dns.IPOption{\n\t\t\tIPv4Enable: sess.config.DomainStrategy == Config_USE_IP || sess.config.DomainStrategy == Config_USE_IP4,\n\t\t\tIPv6Enable: sess.config.DomainStrategy == Config_USE_IP || sess.config.DomainStrategy == Config_USE_IP6,\n\t\t\tFakeEnable: false,\n\t\t}\n\t\tips, err := dns.LookupIPWithOption(sess.dnsClient, domain, opt)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to get IP address for domain \", domain).Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t\treturn ips\n\t}\n\treturn nil\n}\n\nfunc (w *WireguardOutbound) Close() error {\n\tstorage := envctx.EnvironmentFromContext(w.ctx).(environment.ProxyEnvironment).TransientStorage()\n\tstateIfc, err := storage.Get(context.Background(), ConnectionState)\n\tif err != nil || stateIfc == nil {\n\t\treturn nil\n\t}\n\tclientState, ok := stateIfc.(*ClientConnState)\n\tif !ok || clientState.session == nil {\n\t\treturn nil\n\t}\n\t_ = clientState.Close()\n\treturn nil\n}\n\nfunc NewClientConnState() (*ClientConnState, error) {\n\treturn &ClientConnState{initOnce: &sync.Once{}}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewWireguardOutbound(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/config.pb.go",
    "content": "package wgcommon\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 PeerConfig struct {\n\tstate                       protoimpl.MessageState `protogen:\"open.v1\"`\n\tPublicKey                   []byte                 `protobuf:\"bytes,1,opt,name=public_key,json=publicKey,proto3\" json:\"public_key,omitempty\"`\n\tPresharedKey                []byte                 `protobuf:\"bytes,2,opt,name=preshared_key,json=presharedKey,proto3\" json:\"preshared_key,omitempty\"`\n\tAllowedIps                  []string               `protobuf:\"bytes,3,rep,name=allowed_ips,json=allowedIps,proto3\" json:\"allowed_ips,omitempty\"`\n\tEndpoint                    string                 `protobuf:\"bytes,4,opt,name=endpoint,proto3\" json:\"endpoint,omitempty\"`\n\tPersistentKeepaliveInterval int64                  `protobuf:\"varint,5,opt,name=persistent_keepalive_interval,json=persistentKeepaliveInterval,proto3\" json:\"persistent_keepalive_interval,omitempty\"`\n\tunknownFields               protoimpl.UnknownFields\n\tsizeCache                   protoimpl.SizeCache\n}\n\nfunc (x *PeerConfig) Reset() {\n\t*x = PeerConfig{}\n\tmi := &file_proxy_wireguard_wgcommon_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PeerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PeerConfig) ProtoMessage() {}\n\nfunc (x *PeerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_wireguard_wgcommon_config_proto_msgTypes[0]\n\tif 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 PeerConfig.ProtoReflect.Descriptor instead.\nfunc (*PeerConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_wireguard_wgcommon_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *PeerConfig) GetPublicKey() []byte {\n\tif x != nil {\n\t\treturn x.PublicKey\n\t}\n\treturn nil\n}\n\nfunc (x *PeerConfig) GetPresharedKey() []byte {\n\tif x != nil {\n\t\treturn x.PresharedKey\n\t}\n\treturn nil\n}\n\nfunc (x *PeerConfig) GetAllowedIps() []string {\n\tif x != nil {\n\t\treturn x.AllowedIps\n\t}\n\treturn nil\n}\n\nfunc (x *PeerConfig) GetEndpoint() string {\n\tif x != nil {\n\t\treturn x.Endpoint\n\t}\n\treturn \"\"\n}\n\nfunc (x *PeerConfig) GetPersistentKeepaliveInterval() int64 {\n\tif x != nil {\n\t\treturn x.PersistentKeepaliveInterval\n\t}\n\treturn 0\n}\n\ntype DeviceConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tPrivateKey    []byte                 `protobuf:\"bytes,1,opt,name=private_key,json=privateKey,proto3\" json:\"private_key,omitempty\"`\n\tListenPort    uint32                 `protobuf:\"varint,3,opt,name=listen_port,json=listenPort,proto3\" json:\"listen_port,omitempty\"`\n\tPeers         []*PeerConfig          `protobuf:\"bytes,4,rep,name=peers,proto3\" json:\"peers,omitempty\"`\n\tMtu           uint32                 `protobuf:\"varint,5,opt,name=mtu,proto3\" json:\"mtu,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *DeviceConfig) Reset() {\n\t*x = DeviceConfig{}\n\tmi := &file_proxy_wireguard_wgcommon_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *DeviceConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DeviceConfig) ProtoMessage() {}\n\nfunc (x *DeviceConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_proxy_wireguard_wgcommon_config_proto_msgTypes[1]\n\tif 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 DeviceConfig.ProtoReflect.Descriptor instead.\nfunc (*DeviceConfig) Descriptor() ([]byte, []int) {\n\treturn file_proxy_wireguard_wgcommon_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *DeviceConfig) GetPrivateKey() []byte {\n\tif x != nil {\n\t\treturn x.PrivateKey\n\t}\n\treturn nil\n}\n\nfunc (x *DeviceConfig) GetListenPort() uint32 {\n\tif x != nil {\n\t\treturn x.ListenPort\n\t}\n\treturn 0\n}\n\nfunc (x *DeviceConfig) GetPeers() []*PeerConfig {\n\tif x != nil {\n\t\treturn x.Peers\n\t}\n\treturn nil\n}\n\nfunc (x *DeviceConfig) GetMtu() uint32 {\n\tif x != nil {\n\t\treturn x.Mtu\n\t}\n\treturn 0\n}\n\nvar File_proxy_wireguard_wgcommon_config_proto protoreflect.FileDescriptor\n\nconst file_proxy_wireguard_wgcommon_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"%proxy/wireguard/wgcommon/config.proto\\x12#v2ray.core.proxy.wireguard.wgcommon\\\"\\xd1\\x01\\n\" +\n\t\"\\n\" +\n\t\"PeerConfig\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"public_key\\x18\\x01 \\x01(\\fR\\tpublicKey\\x12#\\n\" +\n\t\"\\rpreshared_key\\x18\\x02 \\x01(\\fR\\fpresharedKey\\x12\\x1f\\n\" +\n\t\"\\vallowed_ips\\x18\\x03 \\x03(\\tR\\n\" +\n\t\"allowedIps\\x12\\x1a\\n\" +\n\t\"\\bendpoint\\x18\\x04 \\x01(\\tR\\bendpoint\\x12B\\n\" +\n\t\"\\x1dpersistent_keepalive_interval\\x18\\x05 \\x01(\\x03R\\x1bpersistentKeepaliveInterval\\\"\\xa9\\x01\\n\" +\n\t\"\\fDeviceConfig\\x12\\x1f\\n\" +\n\t\"\\vprivate_key\\x18\\x01 \\x01(\\fR\\n\" +\n\t\"privateKey\\x12\\x1f\\n\" +\n\t\"\\vlisten_port\\x18\\x03 \\x01(\\rR\\n\" +\n\t\"listenPort\\x12E\\n\" +\n\t\"\\x05peers\\x18\\x04 \\x03(\\v2/.v2ray.core.proxy.wireguard.wgcommon.PeerConfigR\\x05peers\\x12\\x10\\n\" +\n\t\"\\x03mtu\\x18\\x05 \\x01(\\rR\\x03mtuB\\x8a\\x01\\n\" +\n\t\"'com.v2ray.core.proxy.wireguard.wgcommonP\\x01Z7github.com/v2fly/v2ray-core/v5/proxy/wireguard/wgcommon\\xaa\\x02#V2Ray.Core.Proxy.Wireguard.Wgcommonb\\x06proto3\"\n\nvar (\n\tfile_proxy_wireguard_wgcommon_config_proto_rawDescOnce sync.Once\n\tfile_proxy_wireguard_wgcommon_config_proto_rawDescData []byte\n)\n\nfunc file_proxy_wireguard_wgcommon_config_proto_rawDescGZIP() []byte {\n\tfile_proxy_wireguard_wgcommon_config_proto_rawDescOnce.Do(func() {\n\t\tfile_proxy_wireguard_wgcommon_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proxy_wireguard_wgcommon_config_proto_rawDesc), len(file_proxy_wireguard_wgcommon_config_proto_rawDesc)))\n\t})\n\treturn file_proxy_wireguard_wgcommon_config_proto_rawDescData\n}\n\nvar file_proxy_wireguard_wgcommon_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_proxy_wireguard_wgcommon_config_proto_goTypes = []any{\n\t(*PeerConfig)(nil),   // 0: v2ray.core.proxy.wireguard.wgcommon.PeerConfig\n\t(*DeviceConfig)(nil), // 1: v2ray.core.proxy.wireguard.wgcommon.DeviceConfig\n}\nvar file_proxy_wireguard_wgcommon_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.proxy.wireguard.wgcommon.DeviceConfig.peers:type_name -> v2ray.core.proxy.wireguard.wgcommon.PeerConfig\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_proxy_wireguard_wgcommon_config_proto_init() }\nfunc file_proxy_wireguard_wgcommon_config_proto_init() {\n\tif File_proxy_wireguard_wgcommon_config_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: unsafe.Slice(unsafe.StringData(file_proxy_wireguard_wgcommon_config_proto_rawDesc), len(file_proxy_wireguard_wgcommon_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_proxy_wireguard_wgcommon_config_proto_goTypes,\n\t\tDependencyIndexes: file_proxy_wireguard_wgcommon_config_proto_depIdxs,\n\t\tMessageInfos:      file_proxy_wireguard_wgcommon_config_proto_msgTypes,\n\t}.Build()\n\tFile_proxy_wireguard_wgcommon_config_proto = out.File\n\tfile_proxy_wireguard_wgcommon_config_proto_goTypes = nil\n\tfile_proxy_wireguard_wgcommon_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.proxy.wireguard.wgcommon;\noption csharp_namespace = \"V2Ray.Core.Proxy.Wireguard.Wgcommon\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/proxy/wireguard/wgcommon\";\noption java_package = \"com.v2ray.core.proxy.wireguard.wgcommon\";\noption java_multiple_files = true;\n\n\nmessage PeerConfig {\n  bytes public_key = 1;\n  bytes preshared_key = 2;\n  repeated string allowed_ips = 3;\n  string endpoint = 4;\n  int64 persistent_keepalive_interval = 5;\n}\n\n\nmessage DeviceConfig {\n  bytes private_key = 1;\n  uint32 listen_port = 3;\n  repeated PeerConfig peers = 4;\n  uint32 mtu = 5;\n}"
  },
  {
    "path": "proxy/wireguard/wgcommon/errors.generated.go",
    "content": "package wgcommon\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/filterDebug.go",
    "content": "package wgcommon\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"strings\"\n)\n\nfunc filterDebugData(in string) string {\n\tlines := strings.Split(in, \"\\n\")\n\toutLines := make([]string, 0, len(lines))\n\n\tfor _, line := range lines {\n\t\ttrimmedLeft := strings.TrimLeft(line, \" \\t\")\n\t\tswitch {\n\t\tcase strings.HasPrefix(trimmedLeft, \"private_key=\"):\n\t\t\tcontinue\n\t\tcase strings.HasPrefix(trimmedLeft, \"preshared_key=\"):\n\t\t\tcontinue\n\t\tcase strings.HasPrefix(trimmedLeft, \"public_key=\"):\n\t\t\tleading := line[:len(line)-len(trimmedLeft)]\n\t\t\tvalue := strings.TrimSpace(trimmedLeft[len(\"public_key=\"):])\n\t\t\tdecoded, err := hex.DecodeString(value)\n\t\t\tif err != nil {\n\t\t\t\toutLines = append(outLines, line)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tencoded := base64.StdEncoding.EncodeToString(decoded)\n\t\t\toutLines = append(outLines, leading+\"public_key=\"+encoded)\n\t\t\tcontinue\n\t\tdefault:\n\t\t\toutLines = append(outLines, line)\n\t\t}\n\t}\n\n\treturn strings.Join(outLines, \"\\n\")\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/setup.go",
    "content": "package wgcommon\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"golang.zx2c4.com/wireguard/device\"\n)\n\nfunc (w *WrappedWireguardDevice) InitDevice() error {\n\tif w == nil || w.config == nil {\n\t\treturn errors.New(\"wireguard: missing config\")\n\t}\n\tif w.device != nil {\n\t\treturn errors.New(\"wireguard: device already initialized\")\n\t}\n\n\t// Create a tun device adaptor from the packetswitch network layer device.\n\t// Use a reasonable default MTU and batch sizes. These can be tuned later.\n\ttunDev, err := NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(int(w.config.Mtu), w.tunnel, 1, 1024)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Create wireguard bind adapter from provided PacketConn\n\tbind := NewNetPacketConnToWg(w.conn)\n\n\t// Create the wireguard device with our logger adapter.\n\tdev := device.NewDevice(tunDev, bind, NewDeviceLoggerAdapter())\n\tif dev == nil {\n\t\treturn errors.New(\"wireguard: failed to initialize device\")\n\t}\n\tw.device = dev\n\treturn nil\n}\n\nfunc (w *WrappedWireguardDevice) SetupDeviceWithoutPeers() error {\n\tif w == nil || w.config == nil {\n\t\treturn errors.New(\"wireguard: missing config\")\n\t}\n\tif w.device == nil {\n\t\treturn errors.New(\"wireguard: device not initialized\")\n\t}\n\n\tvar sb strings.Builder\n\tif len(w.config.PrivateKey) > 0 {\n\t\t_, _ = fmt.Fprintf(&sb, \"private_key=%x\\n\", w.config.PrivateKey)\n\t}\n\tif w.config.ListenPort != 0 {\n\t\t_, _ = fmt.Fprintf(&sb, \"listen_port=%d\\n\", w.config.ListenPort)\n\t}\n\n\t// Terminate operation with a blank line.\n\tsb.WriteString(\"\\n\")\n\n\treturn w.device.IpcSet(sb.String())\n}\n\nfunc (w *WrappedWireguardDevice) AddOrReplacePeers(peers []*PeerConfig) error {\n\tif w == nil || w.config == nil {\n\t\treturn errors.New(\"wireguard: missing config\")\n\t}\n\tif w.device == nil {\n\t\treturn errors.New(\"wireguard: device not initialized\")\n\t}\n\n\tvar sb strings.Builder\n\t// Replace existing peers with the provided list\n\tsb.WriteString(\"replace_peers=true\\n\")\n\n\tfor _, p := range peers {\n\t\tif p == nil || len(p.PublicKey) == 0 {\n\t\t\t// skip empty entries\n\t\t\tcontinue\n\t\t}\n\t\t// start peer block\n\t\t_, _ = fmt.Fprintf(&sb, \"public_key=%x\\n\", p.PublicKey)\n\t\tif len(p.PresharedKey) > 0 {\n\t\t\t_, _ = fmt.Fprintf(&sb, \"preshared_key=%x\\n\", p.PresharedKey)\n\t\t}\n\t\tif p.Endpoint != \"\" {\n\t\t\t_, _ = fmt.Fprintf(&sb, \"endpoint=%s\\n\", p.Endpoint)\n\t\t}\n\t\tif p.PersistentKeepaliveInterval != 0 {\n\t\t\t_, _ = fmt.Fprintf(&sb, \"persistent_keepalive_interval=%d\\n\", p.PersistentKeepaliveInterval)\n\t\t}\n\t\t// replace allowed IPs for this peer\n\t\tsb.WriteString(\"replace_allowed_ips=true\\n\")\n\t\tfor _, aip := range p.AllowedIps {\n\t\t\tif aip == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t_, _ = fmt.Fprintf(&sb, \"allowed_ip=%s\\n\", aip)\n\t\t}\n\t}\n\n\t// terminate\n\tsb.WriteString(\"\\n\")\n\n\treturn w.device.IpcSet(sb.String())\n}\n\nfunc (w *WrappedWireguardDevice) RemovePeer(publicKey []byte) error {\n\tif w == nil {\n\t\treturn errors.New(\"wireguard: nil receiver\")\n\t}\n\tif w.device == nil {\n\t\treturn errors.New(\"wireguard: device not initialized\")\n\t}\n\tif len(publicKey) == 0 {\n\t\treturn errors.New(\"wireguard: empty public key\")\n\t}\n\n\tvar sb strings.Builder\n\t_, _ = fmt.Fprintf(&sb, \"public_key=%x\\n\", publicKey)\n\tsb.WriteString(\"remove=true\\n\")\n\tsb.WriteString(\"\\n\")\n\n\treturn w.device.IpcSet(sb.String())\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgConnAdaptor.go",
    "content": "package wgcommon\n\nimport (\n\tgonet \"net\"\n\t\"net/netip\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.zx2c4.com/wireguard/conn\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n// netPacketConnToWg is machine generated\ntype netPacketConnToWg struct {\n\tmu         sync.Mutex\n\tconn       net.PacketConn\n\tactualPort uint16\n\tclosed     bool // tracks whether the bind is logically closed (not the conn)\n}\n\n// NewNetPacketConnToWg constructs a wireguard conn.Bind adapter from a\n// common/net.PacketConn. It returns a Bind implementation that delegates\n// reads/writes to the provided PacketConn.\n//\n// Important: the Bind does NOT own the PacketConn lifecycle. WireGuard calls\n// Close() + Open() internally during BindUpdate(); Close() here only marks\n// the bind as logically closed without closing the underlying conn, so that\n// Open() can re-use it.\nfunc NewNetPacketConnToWg(c net.PacketConn) conn.Bind {\n\tif c == nil {\n\t\treturn &netPacketConnToWg{}\n\t}\n\tn := &netPacketConnToWg{conn: c, closed: true}\n\tif la := c.LocalAddr(); la != nil {\n\t\tif ua, ok := la.(*gonet.UDPAddr); ok {\n\t\t\tn.actualPort = uint16(ua.Port)\n\t\t}\n\t}\n\treturn n\n}\n\n// wgEndpoint is a minimal implementation of conn.Endpoint backed by netip.AddrPort.\ntype wgEndpoint struct {\n\tap     netip.AddrPort\n\thasSrc bool\n\tsrcIP  netip.Addr\n}\n\nfunc (e *wgEndpoint) ClearSrc() {\n\te.hasSrc = false\n}\n\nfunc (e *wgEndpoint) SrcToString() string {\n\tif !e.hasSrc {\n\t\treturn \"\"\n\t}\n\t// return just IP (no port) if src port is unknown\n\treturn e.srcIP.String()\n}\n\nfunc (e *wgEndpoint) DstToString() string {\n\treturn e.ap.String()\n}\n\nfunc (e *wgEndpoint) DstToBytes() []byte {\n\tb, _ := e.ap.MarshalBinary()\n\treturn b\n}\n\nfunc (e *wgEndpoint) DstIP() netip.Addr {\n\treturn e.ap.Addr()\n}\n\nfunc (e *wgEndpoint) SrcIP() netip.Addr {\n\tif e.hasSrc {\n\t\treturn e.srcIP\n\t}\n\treturn netip.Addr{}\n}\n\nfunc (n *netPacketConnToWg) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) {\n\tif n.conn == nil {\n\t\treturn nil, 0, nil\n\t}\n\tn.mu.Lock()\n\tn.closed = false\n\tn.mu.Unlock()\n\n\t// Clear the read deadline that Close() may have set so reads can proceed.\n\t_ = n.conn.SetReadDeadline(time.Time{})\n\n\t// determine actualPort from LocalAddr if possible\n\tif la := n.conn.LocalAddr(); la != nil {\n\t\tif ua, ok := la.(*gonet.UDPAddr); ok {\n\t\t\tn.actualPort = uint16(ua.Port)\n\t\t}\n\t}\n\tactualPort = n.actualPort\n\n\tfn := func(packets [][]byte, sizes []int, eps []conn.Endpoint) (int, error) {\n\t\tvar i int\n\t\tfor i = 0; i < len(packets); i++ {\n\t\t\tnRead, addr, err := n.conn.ReadFrom(packets[i])\n\t\t\tif err != nil {\n\t\t\t\tif i == 0 {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\treturn i, nil\n\t\t\t}\n\t\t\tsizes[i] = nRead\n\t\t\t// build endpoint from addr\n\t\t\tif udpAddr, ok := addr.(*gonet.UDPAddr); ok {\n\t\t\t\tip, _ := netip.AddrFromSlice(udpAddr.IP)\n\t\t\t\tap := netip.AddrPortFrom(ip, uint16(udpAddr.Port))\n\t\t\t\teps[i] = &wgEndpoint{ap: ap}\n\t\t\t} else {\n\t\t\t\t// fallback: parse string\n\t\t\t\ts := addr.String()\n\t\t\t\tif ap, perr := netip.ParseAddrPort(s); perr == nil {\n\t\t\t\t\teps[i] = &wgEndpoint{ap: ap}\n\t\t\t\t} else {\n\t\t\t\t\teps[i] = &wgEndpoint{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn i, nil\n\t}\n\treturn []conn.ReceiveFunc{fn}, actualPort, nil\n}\n\nfunc (n *netPacketConnToWg) Close() error {\n\tn.mu.Lock()\n\tdefer n.mu.Unlock()\n\tn.closed = true\n\t// Do NOT close the underlying conn here. WireGuard calls Close()+Open()\n\t// internally during BindUpdate(). The actual PacketConn lifecycle is\n\t// managed externally by the session that created it.\n\t//\n\t// Set a past read deadline to unblock any pending ReadFrom calls in\n\t// receive goroutines so that WireGuard's stopping.Wait() can complete.\n\tif n.conn != nil {\n\t\t_ = n.conn.SetReadDeadline(time.Unix(1, 0))\n\t}\n\treturn nil\n}\n\nfunc (n *netPacketConnToWg) SetMark(mark uint32) error {\n\t// best-effort: underlying PacketConn may not support setting fwmark; ignore.\n\treturn nil\n}\n\nfunc (n *netPacketConnToWg) Send(bufs [][]byte, ep conn.Endpoint) error {\n\tif n.conn == nil {\n\t\treturn nil\n\t}\n\t// Use DstToString to obtain \"ip:port\" and resolve to UDPAddr\n\taddrStr := ep.DstToString()\n\tudpAddr, err := gonet.ResolveUDPAddr(\"udp\", addrStr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, b := range bufs {\n\t\tif _, werr := n.conn.WriteTo(b, udpAddr); werr != nil {\n\t\t\treturn werr\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (n *netPacketConnToWg) ParseEndpoint(s string) (conn.Endpoint, error) {\n\tap, err := netip.ParseAddrPort(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &wgEndpoint{ap: ap}, nil\n}\n\nfunc (n *netPacketConnToWg) BatchSize() int {\n\t// underlying common/net.PacketConn may not support batch; report 1.\n\treturn 1\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgConnAdaptor_test.go",
    "content": "package wgcommon\n\nimport (\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.zx2c4.com/wireguard/conn\"\n)\n\nfunc TestNetPacketConnToWg_OpenReceive_Send(t *testing.T) {\n\t// setup a UDP listener (server)\n\tsvAddr, err := net.ResolveUDPAddr(\"udp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tsvConn, err := net.ListenUDP(\"udp\", svAddr)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = svConn.Close() }()\n\n\t// client\n\tclConn, err := net.DialUDP(\"udp\", nil, svConn.LocalAddr().(*net.UDPAddr))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = clConn.Close() }()\n\n\t// Wrap server conn as Bind\n\tbind := NewNetPacketConnToWg(svConn)\n\tfns, port, err := bind.Open(0)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif port == 0 {\n\t\t// LocalAddr should have set actualPort, otherwise use svConn\n\t\tif la := svConn.LocalAddr(); la != nil {\n\t\t\tif ua, ok := la.(*net.UDPAddr); ok && ua.Port != 0 {\n\t\t\t\tport = uint16(ua.Port)\n\t\t\t\t_ = port\n\t\t\t}\n\t\t}\n\t}\n\tif len(fns) == 0 {\n\t\tt.Fatal(\"no receive functions returned\")\n\t}\n\n\trecvFn := fns[0]\n\n\t// run receiver in a goroutine\n\trecvBuf := make([]byte, 1500)\n\tsizes := make([]int, 1)\n\teps := make([]conn.Endpoint, 1)\n\tch := make(chan error, 1)\n\tgo func() {\n\t\t_, err := recvFn([][]byte{recvBuf}, sizes, eps)\n\t\tch <- err\n\t}()\n\n\t// send a message from client to server\n\tmsg := []byte(\"hello-wg\")\n\tif _, err := clConn.Write(msg); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// wait for receive\n\tselect {\n\tcase err := <-ch:\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\tcase <-time.After(time.Second):\n\t\tt.Fatal(\"timeout waiting for receive\")\n\t}\n\n\t// verify sizes and endpoint\n\tif sizes[0] != len(msg) {\n\t\tt.Fatalf(\"unexpected size: got %d want %d\", sizes[0], len(msg))\n\t}\n\tif eps[0] == nil {\n\t\tt.Fatal(\"nil endpoint returned\")\n\t}\n\t// endpoint DstToString should be the client's address\n\tif eps[0].DstToString() != clConn.LocalAddr().String() {\n\t\tt.Fatalf(\"unexpected endpoint dst: %s\", eps[0].DstToString())\n\t}\n\n\t// Test Send: use a separate client conn to receive\n\trcv2, err := net.ListenUDP(\"udp\", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = rcv2.Close() }()\n\n\t// create a bind adapter from a separate unconnected \"sender\" socket\n\tsenderConn, err := net.ListenUDP(\"udp\", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = senderConn.Close() }()\n\tsenderBind := NewNetPacketConnToWg(senderConn)\n\t// parse endpoint for rcv2\n\tep, err := senderBind.ParseEndpoint(rcv2.LocalAddr().String())\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// send from senderBind to rcv2 via Send\n\tp := [][]byte{[]byte(\"ping\")}\n\tif err := senderBind.Send(p, ep); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// read on rcv2\n\tbuf := make([]byte, 1500)\n\tif err := rcv2.SetReadDeadline(time.Now().Add(time.Second)); err != nil {\n\t\tt.Fatal(err)\n\t}\n\tn, _, err := rcv2.ReadFromUDP(buf)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif n != len(p[0]) {\n\t\tt.Fatalf(\"unexpected recv len: %d\", n)\n\t}\n\t_ = buf\n}\n\nfunc TestParseEndpointAndBatchSizeAndNilConstructor(t *testing.T) {\n\t// Parse valid IPv4 endpoint\n\tep, err := NewNetPacketConnToWg(nil).ParseEndpoint(\"127.0.0.1:12345\")\n\tif err != nil {\n\t\tt.Fatalf(\"ParseEndpoint failed: %v\", err)\n\t}\n\tif ep == nil {\n\t\tt.Fatal(\"expected endpoint, got nil\")\n\t}\n\tif ep.DstToString() != \"127.0.0.1:12345\" {\n\t\tt.Fatalf(\"unexpected DstToString: %s\", ep.DstToString())\n\t}\n\n\t// Parse IPv6 endpoint\n\tipv6ep, err := NewNetPacketConnToWg(nil).ParseEndpoint(\"[::1]:54321\")\n\tif err != nil {\n\t\tt.Fatalf(\"ParseEndpoint v6 failed: %v\", err)\n\t}\n\tif ipv6ep == nil {\n\t\tt.Fatal(\"expected ipv6 endpoint, got nil\")\n\t}\n\n\t// BatchSize and Close/SetMark for nil-constructed adapter\n\tbind := NewNetPacketConnToWg(nil)\n\tif bind.BatchSize() != 1 {\n\t\tt.Fatalf(\"unexpected batch size: %d\", bind.BatchSize())\n\t}\n\t// Close and SetMark should be no-ops and not panic\n\tif err := bind.Close(); err != nil {\n\t\tt.Fatalf(\"Close on nil adapter returned error: %v\", err)\n\t}\n\tif err := bind.SetMark(123); err != nil {\n\t\tt.Fatalf(\"SetMark on nil adapter returned error: %v\", err)\n\t}\n}\n\nfunc TestSendWithConnectedSocketProducesError(t *testing.T) {\n\t// create a server to target\n\ttarget, err := net.ListenUDP(\"udp\", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = target.Close() }()\n\n\t// create a connected client socket (DialUDP)\n\tcl, err := net.DialUDP(\"udp\", nil, target.LocalAddr().(*net.UDPAddr))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = cl.Close() }()\n\n\tbind := NewNetPacketConnToWg(cl)\n\tep, err := bind.ParseEndpoint(\"127.0.0.1:1\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// Attempting to Send with a connected socket uses WriteTo and is expected\n\t// to return an error about using WriteTo on a pre-connected connection.\n\tp := [][]byte{[]byte(\"x\")}\n\terr = bind.Send(p, ep)\n\tif err == nil {\n\t\tt.Fatalf(\"expected error when calling Send on adapter wrapping connected socket, got nil\")\n\t}\n}\n\nfunc TestReceiveMultiplePackets(t *testing.T) {\n\t// server\n\tsv, err := net.ListenUDP(\"udp\", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = sv.Close() }()\n\n\t// client\n\tc, err := net.DialUDP(\"udp\", nil, sv.LocalAddr().(*net.UDPAddr))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() { _ = c.Close() }()\n\n\tbind := NewNetPacketConnToWg(sv)\n\tfns, _, err := bind.Open(0)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(fns) == 0 {\n\t\tt.Fatal(\"no receive functions\")\n\t}\n\trecv := fns[0]\n\n\t// prepare two buffers\n\tb1 := make([]byte, 64)\n\tb2 := make([]byte, 64)\n\tsizes := make([]int, 2)\n\teps := make([]conn.Endpoint, 2)\n\tch := make(chan error, 1)\n\tgo func() {\n\t\t_, err := recv([][]byte{b1, b2}, sizes, eps)\n\t\tch <- err\n\t}()\n\n\t// send two packets quickly\n\tif _, err := c.Write([]byte(\"one\")); err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif _, err := c.Write([]byte(\"two\")); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tselect {\n\tcase err := <-ch:\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\tcase <-time.After(time.Second):\n\t\tt.Fatal(\"timeout waiting for batched receive\")\n\t}\n\n\tif sizes[0] == 0 && sizes[1] == 0 {\n\t\tt.Fatalf(\"expected at least one packet size to be non-zero\")\n\t}\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgDeviceAdaptor.go",
    "content": "package wgcommon\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"sync\"\n\n\t\"golang.zx2c4.com/wireguard/tun\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\nfunc NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(mtu int, networkLayerSwitch packetswitch.NetworkLayerDevice, batchSize int, inboundChannelSize int) (*NetworkLayerDeviceToWireguardTunDeviceAdaptor, error) {\n\tif batchSize <= 0 {\n\t\tbatchSize = 1\n\t}\n\tif inboundChannelSize <= 0 {\n\t\tinboundChannelSize = 1024\n\t}\n\tn := &NetworkLayerDeviceToWireguardTunDeviceAdaptor{\n\t\tmtu:                mtu,\n\t\tnetworkLayerSwitch: networkLayerSwitch,\n\t\tin:                 make(chan []byte, inboundChannelSize),\n\t\tevents:             make(chan tun.Event, 4),\n\t\tbatchSize:          batchSize,\n\t}\n\t// Attach writer to the network layer switch so incoming packets are delivered to this adaptor.\n\tif networkLayerSwitch != nil {\n\t\tif err := networkLayerSwitch.OnAttach(&networkLayerWriter{parent: n}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// If the underlying device exposes real link events, forward them.\n\t\tif src, ok := networkLayerSwitch.(interface{ Events() <-chan tun.Event }); ok {\n\t\t\tgo func() {\n\t\t\t\tfor ev := range src.Events() {\n\t\t\t\t\t// Acquire lock to synchronize with Close (which closes the events channel).\n\t\t\t\t\tn.mu.Lock()\n\t\t\t\t\tclosed := n.closed\n\t\t\t\t\tif !closed {\n\t\t\t\t\t\t// best-effort: do not block if events channel is full\n\t\t\t\t\t\tselect {\n\t\t\t\t\t\tcase n.events <- ev:\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tn.mu.Unlock()\n\t\t\t\t\tif closed {\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\treturn n, nil\n}\n\n// NetworkLayerDeviceToWireguardTunDeviceAdaptor is primarily machine generated.\ntype NetworkLayerDeviceToWireguardTunDeviceAdaptor struct {\n\tmtu                int\n\tnetworkLayerSwitch packetswitch.NetworkLayerDevice\n\n\tmu        sync.RWMutex\n\tclosed    bool\n\tin        chan []byte\n\tevents    chan tun.Event\n\tbatchSize int\n}\n\n// networkLayerWriter adapts packetswitch writes into the adaptor's incoming channel.\ntype networkLayerWriter struct {\n\tparent *NetworkLayerDeviceToWireguardTunDeviceAdaptor\n}\n\nfunc (w *networkLayerWriter) Write(packet []byte) (int, error) {\n\tp := make([]byte, len(packet))\n\tcopy(p, packet)\n\tw.parent.mu.RLock()\n\tclosed := w.parent.closed\n\tw.parent.mu.RUnlock()\n\tif closed {\n\t\treturn 0, errors.New(\"device closed\")\n\t}\n\tselect {\n\tcase w.parent.in <- p:\n\t\treturn len(packet), nil\n\tdefault:\n\t\t// Channel full, drop packet.\n\t\treturn 0, errors.New(\"no buffer space\")\n\t}\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) File() *os.File {\n\t// No underlying OS file for this adaptor.\n\treturn nil\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) Read(bufs [][]byte, sizes []int, offset int) (ret int, err error) {\n\t// Read up to BatchSize packets or until bufs exhausted.\n\t// NOTE: 'offset' is a byte offset within each buffer (to leave room for transport headers),\n\t// NOT an index into the bufs slice. WireGuard expects packet data to be written starting at\n\t// bufs[i][offset:].\n\tmaxCount := n.BatchSize()\n\tif maxCount <= 0 {\n\t\tmaxCount = 1\n\t}\n\tfor i := 0; i < maxCount && i < len(bufs); i++ {\n\t\tvar b []byte\n\t\tvar ok bool\n\t\tif ret == 0 {\n\t\t\t// first read: block until a packet arrives or channel closes\n\t\t\tb, ok = <-n.in\n\t\t} else {\n\t\t\t// subsequent reads: do not block — if no packet available, return what we've got\n\t\t\tselect {\n\t\t\tcase b, ok = <-n.in:\n\t\t\t\t// got one\n\t\t\tdefault:\n\t\t\t\treturn ret, nil\n\t\t\t}\n\t\t}\n\t\tif !ok {\n\t\t\t// channel closed\n\t\t\tif ret == 0 {\n\t\t\t\treturn 0, os.ErrClosed\n\t\t\t}\n\t\t\treturn ret, nil\n\t\t}\n\t\tto := bufs[i]\n\t\tif to == nil {\n\t\t\t// packet consumed but no destination buffer provided, skip copying\n\t\t\tret++\n\t\t\tcontinue\n\t\t}\n\t\tcopied := copy(to[offset:], b)\n\t\tif sizes != nil && i < len(sizes) {\n\t\t\tsizes[i] = copied\n\t\t}\n\t\tret++\n\t}\n\treturn ret, nil\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) Write(bufs [][]byte, offset int) (int, error) {\n\twritten := 0\n\tif n.networkLayerSwitch == nil {\n\t\treturn 0, errors.New(\"no network layer writer attached\")\n\t}\n\tfor i := 0; i < len(bufs); i++ {\n\t\tb := bufs[i]\n\t\tif b == nil || len(b) <= offset {\n\t\t\tcontinue\n\t\t}\n\t\t// The offset is a byte offset within each buffer where the actual\n\t\t// packet payload starts (after transport headers). Extract only the\n\t\t// payload portion. Copy because caller may reuse buffer.\n\t\tpayload := b[offset:]\n\t\tcp := make([]byte, len(payload))\n\t\tcopy(cp, payload)\n\t\t_, err := n.networkLayerSwitch.Write(cp)\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\twritten++\n\t}\n\treturn written, nil\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) MTU() (int, error) {\n\treturn n.mtu, nil\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) Name() (string, error) {\n\t// No specific name available for this virtual adaptor.\n\treturn \"\", nil\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) Events() <-chan tun.Event {\n\treturn n.events\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) Close() error {\n\tn.mu.Lock()\n\tif n.closed {\n\t\tn.mu.Unlock()\n\t\treturn nil\n\t}\n\tn.closed = true\n\tclose(n.in)\n\t// Close events channel to signal no more events.\n\tclose(n.events)\n\tdev := n.networkLayerSwitch\n\tn.networkLayerSwitch = nil\n\tn.mu.Unlock()\n\tif dev != nil {\n\t\t_ = dev.Close()\n\t}\n\treturn nil\n}\n\nfunc (n *NetworkLayerDeviceToWireguardTunDeviceAdaptor) BatchSize() int {\n\treturn n.batchSize\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgDeviceAdaptor_test.go",
    "content": "package wgcommon\n\nimport (\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.zx2c4.com/wireguard/tun\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\n// fakeNetDevice implements packetswitch.NetworkLayerDevice and optionally exposes Events().\ntype fakeNetDevice struct {\n\tmu     sync.Mutex\n\twriter packetswitch.NetworkLayerPacketWriter\n\twrites [][]byte\n\tclosed bool\n\tevents chan tun.Event\n}\n\nfunc (f *fakeNetDevice) OnAttach(w packetswitch.NetworkLayerPacketWriter) error {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tf.writer = w\n\treturn nil\n}\n\nfunc (f *fakeNetDevice) Write(packet []byte) (int, error) {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tif f.closed {\n\t\treturn 0, errClosed\n\t}\n\tcp := make([]byte, len(packet))\n\tcopy(cp, packet)\n\tf.writes = append(f.writes, cp)\n\treturn len(packet), nil\n}\n\nfunc (f *fakeNetDevice) Close() error {\n\tf.mu.Lock()\n\tf.closed = true\n\tf.mu.Unlock()\n\treturn nil\n}\n\nfunc (f *fakeNetDevice) getWriter() packetswitch.NetworkLayerPacketWriter {\n\tf.mu.Lock()\n\tw := f.writer\n\tf.mu.Unlock()\n\treturn w\n}\n\nfunc (f *fakeNetDevice) lastWrite() []byte {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tif len(f.writes) == 0 {\n\t\treturn nil\n\t}\n\treturn f.writes[len(f.writes)-1]\n}\n\n// Provide Events() so adaptor can forward events when present.\nfunc (f *fakeNetDevice) Events() <-chan tun.Event {\n\treturn f.events\n}\n\nvar errClosed = &fakeError{\"closed\"}\n\ntype fakeError struct{ s string }\n\nfunc (e *fakeError) Error() string { return e.s }\n\nfunc TestNewAdaptor_ReadWrite_Basic(t *testing.T) {\n\tfd := &fakeNetDevice{events: make(chan tun.Event, 4)}\n\t// batchSize 2, inboundChannelSize 4\n\ta, err := NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(1500, fd, 2, 4)\n\tif err != nil {\n\t\tt.Fatalf(\"constructor failed: %v\", err)\n\t}\n\n\tw := fd.getWriter()\n\tif w == nil {\n\t\tt.Fatal(\"expected writer to be attached to fake device\")\n\t}\n\n\tp1 := []byte{0x01, 0x02, 0x03}\n\tif _, err := w.Write(p1); err != nil {\n\t\tt.Fatalf(\"writer.Write failed: %v\", err)\n\t}\n\n\tbufs := make([][]byte, 2)\n\tbufs[0] = make([]byte, 64)\n\tbufs[1] = make([]byte, 64)\n\tsizes := make([]int, 2)\n\n\tret, err := a.Read(bufs, sizes, 0)\n\tif err != nil {\n\t\tt.Fatalf(\"Read returned error: %v\", err)\n\t}\n\tif ret != 1 {\n\t\tt.Fatalf(\"expected 1 packet read, got %d\", ret)\n\t}\n\tif sizes[0] != len(p1) {\n\t\tt.Fatalf(\"expected sizes[0]=%d, got %d\", len(p1), sizes[0])\n\t}\n\tif !reflect.DeepEqual(bufs[0][:sizes[0]], p1) {\n\t\tt.Fatalf(\"payload mismatch: got %v want %v\", bufs[0][:sizes[0]], p1)\n\t}\n\n\t// Now write two packets and read both\n\tp2 := []byte{0x0a, 0x0b}\n\tp3 := []byte{0x0c}\n\tif _, err := w.Write(p2); err != nil {\n\t\tt.Fatalf(\"writer.Write p2 failed: %v\", err)\n\t}\n\tif _, err := w.Write(p3); err != nil {\n\t\tt.Fatalf(\"writer.Write p3 failed: %v\", err)\n\t}\n\n\tbufs2 := make([][]byte, 2)\n\tbufs2[0] = make([]byte, 16)\n\tbufs2[1] = make([]byte, 16)\n\tsizes2 := make([]int, 2)\n\n\tret2, err := a.Read(bufs2, sizes2, 0)\n\tif err != nil {\n\t\tt.Fatalf(\"Read returned error: %v\", err)\n\t}\n\tif ret2 != 2 {\n\t\tt.Fatalf(\"expected 2 packets read, got %d\", ret2)\n\t}\n\tif sizes2[0] != len(p2) || sizes2[1] != len(p3) {\n\t\tt.Fatalf(\"unexpected sizes: %v\", sizes2)\n\t}\n}\n\nfunc TestNewAdaptor_WriteToNetwork(t *testing.T) {\n\tfd := &fakeNetDevice{events: make(chan tun.Event, 4)}\n\ta, err := NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(1500, fd, 1, 4)\n\tif err != nil {\n\t\tt.Fatalf(\"constructor failed: %v\", err)\n\t}\n\n\tpayload := []byte{0xaa, 0xbb, 0xcc}\n\tbufs := make([][]byte, 1)\n\tbufs[0] = payload\n\n\twritten, err := a.Write(bufs, 0)\n\tif err != nil {\n\t\tt.Fatalf(\"Write returned error: %v\", err)\n\t}\n\tif written != 1 {\n\t\tt.Fatalf(\"expected 1 written, got %d\", written)\n\t}\n\tlw := fd.lastWrite()\n\tif !reflect.DeepEqual(lw, payload) {\n\t\tt.Fatalf(\"device write mismatch: got %v want %v\", lw, payload)\n\t}\n}\n\nfunc TestNewAdaptor_InboundBufferFullDrops(t *testing.T) {\n\tfd := &fakeNetDevice{events: make(chan tun.Event, 4)}\n\t// inboundChannelSize 1 so second write should fail\n\ta, err := NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(1500, fd, 2, 1)\n\tif err != nil {\n\t\tt.Fatalf(\"constructor failed: %v\", err)\n\t}\n\tw := fd.getWriter()\n\tif w == nil {\n\t\tt.Fatal(\"expected writer to be attached to fake device\")\n\t}\n\n\tp1 := []byte{0x01}\n\tp2 := []byte{0x02}\n\tif _, err := w.Write(p1); err != nil {\n\t\tt.Fatalf(\"first write failed: %v\", err)\n\t}\n\t// second write should return error due to buffer full\n\tif _, err := w.Write(p2); err == nil {\n\t\tt.Fatalf(\"expected second write to fail due to full buffer\")\n\t}\n\n\tbufs := make([][]byte, 1)\n\tbufs[0] = make([]byte, 8)\n\tsizes := make([]int, 1)\n\tret, err := a.Read(bufs, sizes, 0)\n\tif err != nil {\n\t\tt.Fatalf(\"Read returned error: %v\", err)\n\t}\n\tif ret != 1 {\n\t\tt.Fatalf(\"expected 1 packet read, got %d\", ret)\n\t}\n}\n\nfunc TestNewAdaptor_ReadWithNonZeroOffset(t *testing.T) {\n\t// This test reproduces the 100% CPU bug where offset was misinterpreted\n\t// as a buffer index rather than a byte offset within each buffer.\n\tfd := &fakeNetDevice{events: make(chan tun.Event, 4)}\n\ta, err := NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(1500, fd, 1, 4)\n\tif err != nil {\n\t\tt.Fatalf(\"constructor failed: %v\", err)\n\t}\n\tw := fd.getWriter()\n\tif w == nil {\n\t\tt.Fatal(\"expected writer to be attached\")\n\t}\n\n\tp1 := []byte{0xDE, 0xAD, 0xBE, 0xEF}\n\tif _, err := w.Write(p1); err != nil {\n\t\tt.Fatalf(\"writer.Write failed: %v\", err)\n\t}\n\n\t// Use offset=16 to mimic WireGuard's MessageTransportHeaderSize\n\tconst offset = 16\n\tbufs := make([][]byte, 1)\n\tbufs[0] = make([]byte, 64)\n\tsizes := make([]int, 1)\n\n\tret, err := a.Read(bufs, sizes, offset)\n\tif err != nil {\n\t\tt.Fatalf(\"Read returned error: %v\", err)\n\t}\n\tif ret != 1 {\n\t\tt.Fatalf(\"expected 1 packet read, got %d\", ret)\n\t}\n\tif sizes[0] != len(p1) {\n\t\tt.Fatalf(\"expected sizes[0]=%d, got %d\", len(p1), sizes[0])\n\t}\n\t// Data should be at bufs[0][offset:offset+sizes[0]], not bufs[0][0:sizes[0]]\n\tgot := bufs[0][offset : offset+sizes[0]]\n\tif !reflect.DeepEqual(got, p1) {\n\t\tt.Fatalf(\"payload mismatch: got %v want %v\", got, p1)\n\t}\n\t// The header area before offset should be untouched (all zeros)\n\tfor i := 0; i < offset; i++ {\n\t\tif bufs[0][i] != 0 {\n\t\t\tt.Fatalf(\"byte at position %d was modified: %x\", i, bufs[0][i])\n\t\t}\n\t}\n}\n\nfunc TestNewAdaptor_EventForwardingAndClose(t *testing.T) {\n\tfd := &fakeNetDevice{events: make(chan tun.Event, 4)}\n\ta, err := NewNetworkLayerDeviceToWireguardTunDeviceAdaptor(1500, fd, 1, 4)\n\tif err != nil {\n\t\tt.Fatalf(\"constructor failed: %v\", err)\n\t}\n\n\t// send event from underlying device\n\tfd.events <- tun.EventUp\n\n\tselect {\n\tcase ev := <-a.Events():\n\t\tif ev != tun.EventUp {\n\t\t\tt.Fatalf(\"expected EventUp, got %v\", ev)\n\t\t}\n\tcase <-time.After(time.Second):\n\t\tt.Fatal(\"timeout waiting for forwarded event\")\n\t}\n\n\t// Close adaptor and ensure events channel is closed\n\tif err := a.Close(); err != nil {\n\t\tt.Fatalf(\"Close returned error: %v\", err)\n\t}\n\t// reading from closed events channel should return immediately with ok==false\n\tselect {\n\tcase _, ok := <-a.Events():\n\t\tif ok {\n\t\t\tt.Fatal(\"expected events channel to be closed\")\n\t\t}\n\tcase <-time.After(time.Second):\n\t\tt.Fatal(\"timeout waiting for events channel close\")\n\t}\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgLogAdaptor.go",
    "content": "package wgcommon\n\nimport (\n\t\"fmt\"\n\n\t\"golang.zx2c4.com/wireguard/device\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n)\n\n// NewDeviceLoggerAdapter returns a wireguard device.Logger that forwards\n// verbose and error logs into the project's error logger using errors.New(...).\n// Verbosef logs are recorded as Debug, Errorf logs are recorded as Error.\n// machine generated\nfunc NewDeviceLoggerAdapter() *device.Logger {\n\tl := &device.Logger{}\n\tl.Verbosef = func(format string, args ...any) {\n\t\tmsg := fmt.Sprintf(format, args...)\n\t\terr := errors.New(msg)\n\t\terr.AtDebug().WriteToLog()\n\t}\n\tl.Errorf = func(format string, args ...any) {\n\t\tmsg := fmt.Sprintf(format, args...)\n\t\terr := errors.New(msg)\n\t\terr.AtError().WriteToLog()\n\t}\n\treturn l\n}\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgcommon.go",
    "content": "package wgcommon\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "proxy/wireguard/wgcommon/wgdevice.go",
    "content": "package wgcommon\n\nimport (\n\t\"context\"\n\n\t\"golang.zx2c4.com/wireguard/device\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/packetswitch\"\n)\n\nfunc NewWrappedWireguardDevice(ctx context.Context, config *DeviceConfig) (*WrappedWireguardDevice, error) {\n\treturn &WrappedWireguardDevice{\n\t\tconfig: config,\n\t\tctx:    ctx,\n\t}, nil\n}\n\ntype WrappedWireguardDevice struct {\n\tconfig *DeviceConfig\n\tctx    context.Context\n\tdevice *device.Device\n\n\ttunnel packetswitch.NetworkLayerDevice\n\tconn   net.PacketConn\n}\n\nfunc (w *WrappedWireguardDevice) Up() error {\n\tif w.device != nil {\n\t\treturn w.device.Up()\n\t}\n\treturn newError(\"wireguard device do not exist\").AtError()\n}\n\n// SetTunnel sets the network layer tunnel device for the wrapped WireGuard device.\nfunc (w *WrappedWireguardDevice) SetTunnel(t packetswitch.NetworkLayerDevice) {\n\tw.tunnel = t\n}\n\n// SetConn sets the underlying packet connection used by the wrapped WireGuard device.\nfunc (w *WrappedWireguardDevice) SetConn(c net.PacketConn) {\n\tw.conn = c\n}\n\nfunc (w *WrappedWireguardDevice) Close() error {\n\tif w == nil {\n\t\treturn nil\n\t}\n\t// Bring device down if initialized\n\tif w.device != nil {\n\t\t_ = w.device.Down()\n\t\tw.device = nil\n\t}\n\t// Close tunnel if present\n\tif w.tunnel != nil {\n\t\t_ = w.tunnel.Close()\n\t\tw.tunnel = nil\n\t}\n\t// Close underlying packet conn if present\n\tif w.conn != nil {\n\t\t_ = w.conn.Close()\n\t\tw.conn = nil\n\t}\n\treturn nil\n}\n\nfunc (w *WrappedWireguardDevice) Debug() (string, error) {\n\tif w.device != nil {\n\t\tresult, err := w.device.IpcGet()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn filterDebugData(result), nil\n\t}\n\treturn \"\", nil\n}\n"
  },
  {
    "path": "release/config/config.json",
    "content": "// Config file of V2Ray. This file follows standard JSON format, with comments support.\n// Uncomment entries below to satisfy your needs. Also read our manual for more detail at\n// https://www.v2fly.org/\n{\n  \"log\": {\n    // By default, V2Ray writes access log to stdout.\n    // \"access\": \"/path/to/access/log/file\",\n\n    // By default, V2Ray write error log to stdout.\n    // \"error\": \"/path/to/error/log/file\",\n\n    // Log level, one of \"debug\", \"info\", \"warning\", \"error\", \"none\"\n    \"loglevel\": \"warning\"\n  },\n  // List of inbound proxy configurations.\n  \"inbounds\": [{\n    // Port to listen on. You may need root access if the value is less than 1024.\n    \"port\": 1080,\n\n    // IP address to listen on. Change to \"0.0.0.0\" to listen on all network interfaces.\n    \"listen\": \"127.0.0.1\",\n\n    // Tag of the inbound proxy. May be used for routing.\n    \"tag\": \"socks-inbound\",\n\n    // Protocol name of inbound proxy.\n    \"protocol\": \"socks\",\n\n    // Settings of the protocol. Varies based on protocol.\n    \"settings\": {\n      \"auth\": \"noauth\",\n      \"udp\": false,\n      \"ip\": \"127.0.0.1\"\n    },\n\n    // Enable sniffing on TCP connection.\n    \"sniffing\": {\n      \"enabled\": true,\n      // Target domain will be overriden to the one carried by the connection, if the connection is HTTP or HTTPS.\n      \"destOverride\": [\"http\", \"tls\"]\n    }\n  }],\n  // List of outbound proxy configurations.\n  \"outbounds\": [{\n    // Protocol name of the outbound proxy.\n    \"protocol\": \"freedom\",\n\n    // Settings of the protocol. Varies based on protocol.\n    \"settings\": {},\n\n    // Tag of the outbound. May be used for routing.\n    \"tag\": \"direct\"\n  },{\n    \"protocol\": \"blackhole\",\n    \"settings\": {},\n    \"tag\": \"blocked\"\n  }],\n\n  // Transport is for global transport settings. If you have multiple transports with same settings\n  // (say mKCP), you may put it here, instead of in each individual inbound/outbounds.\n  //\"transport\": {},\n\n  // Routing controls how traffic from inbounds are sent to outbounds.\n  \"routing\": {\n    \"domainStrategy\": \"IPOnDemand\",\n    \"rules\":[\n      {\n        // Blocks access to private IPs. Remove this if you want to access your router.\n        \"type\": \"field\",\n        \"ip\": [\"geoip:private\"],\n        \"outboundTag\": \"blocked\"\n      },\n      {\n        // Blocks major ads.\n        \"type\": \"field\",\n        \"domain\": [\"geosite:category-ads\"],\n        \"outboundTag\": \"blocked\"\n      }\n    ]\n  },\n\n  // Dns settings for domain resolution.\n  \"dns\": {\n    // Static hosts, similar to hosts file.\n    \"hosts\": {\n      // Match v2fly.org to another domain on CloudFlare. This domain will be used when querying IPs for v2fly.org.\n      \"domain:v2fly.org\": \"www.vicemc.net\",\n\n      // The following settings help to eliminate DNS poisoning in mainland China.\n      // It is safe to comment these out if this is not the case for you.\n      \"domain:github.io\": \"pages.github.com\",\n      \"domain:wikipedia.org\": \"www.wikimedia.org\",\n      \"domain:shadowsocks.org\": \"electronicsrealm.com\"\n    },\n    \"servers\": [\n      \"1.1.1.1\",\n      {\n        \"address\": \"114.114.114.114\",\n        \"port\": 53,\n        // List of domains that use this DNS first.\n        \"domains\": [\n          \"geosite:cn\"\n        ]\n      },\n      \"8.8.8.8\",\n      \"localhost\"\n    ]\n  },\n\n  // Policy controls some internal behavior of how V2Ray handles connections.\n  // It may be on connection level by user levels in 'levels', or global settings in 'system.'\n  \"policy\": {\n    // Connection policys by user levels\n    \"levels\": {\n      \"0\": {\n        \"uplinkOnly\": 0,\n        \"downlinkOnly\": 0\n      }\n    },\n    \"system\": {\n      \"statsInboundUplink\": false,\n      \"statsInboundDownlink\": false,\n      \"statsOutboundUplink\": false,\n      \"statsOutboundDownlink\": false\n    }\n  },\n\n  // Stats enables internal stats counter.\n  // This setting can be used together with Policy and Api.\n  //\"stats\":{},\n\n  // Api enables gRPC APIs for external programs to communicate with V2Ray instance.\n  //\"api\": {\n    //\"tag\": \"api\",\n    //\"services\": [\n    //  \"HandlerService\",\n    //  \"LoggerService\",\n    //  \"StatsService\"\n    //]\n  //},\n\n  // You may add other entries to the configuration, but they will not be recognized by V2Ray.\n  \"other\": {}\n}\n"
  },
  {
    "path": "release/config/systemd/system/v2ray.service",
    "content": "[Unit]\nDescription=V2Ray Service\nDocumentation=https://www.v2fly.org/\nAfter=network.target nss-lookup.target\n\n[Service]\nUser=nobody\nCapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nNoNewPrivileges=true\nExecStart=/usr/local/bin/v2ray run -config /usr/local/etc/v2ray/config.json\nRestart=on-failure\nRestartPreventExitStatus=23\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "release/config/systemd/system/v2ray@.service",
    "content": "[Unit]\nDescription=V2Ray Service\nDocumentation=https://www.v2fly.org/\nAfter=network.target nss-lookup.target\n\n[Service]\nUser=nobody\nCapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nNoNewPrivileges=true\nExecStart=/usr/local/bin/v2ray run -config /usr/local/etc/v2ray/%i.json\nRestart=on-failure\nRestartPreventExitStatus=23\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "release/config/vpoint_socks_vmess.json",
    "content": "{\n  \"log\": {\n    \"loglevel\": \"warning\"\n  },\n  \"inbounds\": [{\n    \"port\": 1080,\n    \"listen\": \"127.0.0.1\",\n    \"protocol\": \"socks\",\n    \"settings\": {\n      \"auth\": \"noauth\",\n      \"udp\": false,\n      \"ip\": \"127.0.0.1\"\n    }\n  }],\n  \"outbounds\": [{\n    \"protocol\": \"freedom\",\n    \"settings\": {},\n    \"tag\": \"direct\"\n  }],\n  \"policy\": {\n    \"levels\": {\n      \"0\": {\"uplinkOnly\": 0}\n    }\n  }\n}\n"
  },
  {
    "path": "release/config/vpoint_vmess_freedom.json",
    "content": "{\n  \"inbounds\": [{\n    \"port\": 10086,\n    \"protocol\": \"vmess\",\n    \"settings\": {\n      \"clients\": [\n        {\n          \"id\": \"23ad6b10-8d1a-40f7-8ad0-e3e35cd38297\",\n          \"level\": 1,\n          \"alterId\": 64\n        }\n      ]\n    }\n  }],\n  \"outbounds\": [{\n    \"protocol\": \"freedom\",\n    \"settings\": {}\n  },{\n    \"protocol\": \"blackhole\",\n    \"settings\": {},\n    \"tag\": \"blocked\"\n  }],\n  \"routing\": {\n    \"rules\": [\n      {\n        \"type\": \"field\",\n        \"ip\": [\"geoip:private\"],\n        \"outboundTag\": \"blocked\"\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "release/container/Containerfile",
    "content": "# golang:1.21.4 linux/amd64\nFROM docker.io/library/golang@sha256:337543447173c2238c78d4851456760dcc57c1dfa8c3bcd94cbee8b0f7b32ad0 AS builder\nFROM scratch\n\nCOPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo\nCOPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/\nCOPY --from=builder /etc/passwd /etc/passwd\nCOPY --from=builder /etc/group /etc/group\nCOPY --from=builder /tmp /tmp\nCOPY --from=builder /dev /dev\n\nENV v2ray.location.asset=/opt/v2ray/share\n\nCOPY ./ /opt/v2ray/\n\nENTRYPOINT [ \"/opt/v2ray/bin/v2ray\" ]\nCMD [ \"run\", \"-config\", \"/etc/v2ray/config.json\" ]\n"
  },
  {
    "path": "release/container/downloadAssets.sh",
    "content": "#!/bin/bash\n\nset -x -e\n\ndownload() {\n  curl -L \"https://github.com/${RELEASE_REPO}/releases/download/$1/$2\" >\"$2\"\n}\n\ndownloadAndUnzip() {\n  download \"$1\" \"$2\"\n  unzip -n -d \"${2%\\.zip}\" \"$2\"\n}\nmkdir -p assets\n\npushd assets\ndownloadAndUnzip \"$1\" \"v2ray-linux-$2.zip\"\ndownloadAndUnzip \"$1\" \"v2ray-extra.zip\"\npopd\n\nplaceFile() {\n  mkdir -p \"context/$2\"\n  cp -R \"assets/$1/$3\" \"context/$2/$3\"\n}\n\nfunction generateStandardVersion() {\n  placeFile \"$1\" \"$2/bin\" \"v2ray\"\n}\n\nfunction generateExtraVersion() {\n  generateStandardVersion \"$1\" \"$2\"\n  placeFile \"$1\" \"$2/share\" \"geosite.dat\"\n  placeFile \"$1\" \"$2/share\" \"geoip.dat\"\n  placeFile \"$1\" \"$2/etc\" \"config.json\"\n  placeFile \"v2ray-extra\" \"$2/share\" \"browserforwarder\"\n}\n\nif [ \"$4\" = \"std\" ]; then\n    generateStandardVersion \"v2ray-linux-$2\" \"linux/$3/std\"\nfi\n\nif [ \"$4\" = \"extra\" ]; then\n    generateExtraVersion \"v2ray-linux-$2\" \"linux/$3/extra\"\nfi\n\n\n"
  },
  {
    "path": "release/debian/changelog",
    "content": "v2ray-core (4.42.2-2) unstable; urgency=medium\n\n  * Support Windows ARM64\n  * TLS: support client certificate authentication\n  * GeoIP asset: add trimmed GeoIP file `geoip-only-cn-private.dat` to zip package for ROM/RAM insufficient devices\n  * Socks: support 4/4a version of the socks protocol\n  * DNS: add option `disableFallbackIfMatch` for DNS\n  * More details in https://github.com/v2fly/v2ray-core/releases/tag/v4.42.2\n\n -- V2Fly <dev@v2fly.org>  Mon, 20 Sep 2021 11:00:00 +0800\n\nv2ray-core (4.41.1-1) unstable; urgency=medium\n\n  * VMess: added two VMess experiments: AuthenticatedLength & NoTerminationSignal\n  * Draining connection at client side when receiving invalid data\n  * Observatory: support custom probe interval and probe URL\n  * Fix: connection stability issue in HTTP/2 & gRPC transport\n  * More details in https://github.com/v2fly/v2ray-core/releases/tag/v4.41.1\n\n -- V2Fly <dev@v2fly.org>  Wed, 18 Aug 2021 10:00:00 +0800\n\nv2ray-core (4.40.1-1) unstable; urgency=medium\n\n  * DNS: support DNS over TCP\n  * Fix: new certification issuing incorrectly delayed\n  * More details in https://github.com/v2fly/v2ray-core/releases/tag/v4.40.1\n\n -- V2Fly <dev@v2fly.org>  Tue, 22 Jun 2021 22:00:00 +0800\n\nv2ray-core (4.39.2-1) unstable; urgency=medium\n\n  * Websocket: support header based Websocket early data & its partial browser forwarder support\n  * GeoData: add a memory efficient geodata decoder called `memconservative` for memory-limited devices\n  * HTTP/2 Transport: support to set method and headers for outgoing connections\n  * TCP Socket Option: support to set keepalive interval on Linux operating system\n  * Fixed BrowserForwarder panics with empty config\n  * Fixed FakeDNS prints error with empty config\n  * Fixed dual stack FakeDNS Close method\n  * Fixed Observatory starts with empty config & fails to close\n  * Fixed null check on alternative system dialer\n  * Fixed the chain proxy support for gRPC and HTTP/2 transport\n  * Fixed leastping logic\n  * Fixed v2ctl unable to create geodata loaders\n  * More details in https://github.com/v2fly/v2ray-core/releases/tag/v4.39.2\n\n -- V2Fly <dev@v2fly.org>  Wed, 26 May 2021 08:00:00 +0800\n\nv2ray-core (4.38.3-1) unstable; urgency=medium\n\n  * FakeDNS: add fakedns+others sniffer\n  * FakeDNS: support dual stack IP pool by default\n  * Observatory: A component that measures the connectivity of selected outbounds\n  * Multi-JSON support for Observatory & BrowserForwarder\n  * Routing: add leastPing balancing strategy\n  * Fix: FakeDNS crash\n  * Fix: FakeDNS return ErrEmptyResponse when no FakeIP found\n  * Fix: UDP DNS connection crash\n  * More details in https://github.com/v2fly/v2ray-core/releases/tag/v4.38.3\n\n -- V2Fly <dev@v2fly.org>  Wed, 5 May 2021 10:00:00 +0800\n\nv2ray-core (4.37.3-1) unstable; urgency=medium\n\n  * DNS: hosts support multiple addresses (#884 #886 #888)\n  * Fix: cannot load geoip & geosite (#889)\n  * Chore: use Go v1.16 to build Debian package (#890)\n\n -- V2Fly <dev@v2fly.org>  Mon, 12 Apr 2021 23:05:51 +0800\n\nv2ray-core (4.37.2-1) unstable; urgency=medium\n\n  * Websocket: support browser forwarder (#818)\n  * Websocket: support Websocket 0-RTT early data (#818)\n  * Shadowsocks: add replay protection for Shadowsocks proxy (#777)\n  * DNS: add queryStrategy option for DNS (#794)\n  * DNS: add disableFallback & skipFallback option for DNS client (#864)\n  * GeoIP: add inversed GeoIP matching (#860)\n\n -- V2Fly <dev@v2fly.org>  Sun, 11 Apr 2021 22:00:51 +0800\n\nv2ray-core (4.34.0-1) unstable; urgency=medium\n\n  * TLS Session Resumption is now disabled by default (#569).\n    See #557 for more information.\n  * Support for the legacy Shadowsocks protocol with stream ciphers has been removed (#566).\n    If you are still using the unsecure stream ciphers, migrate to Shadowsocks AEAD (ChaCha20Poly1305 and AES-GCM) immediately.\n  * We have added preliminary support for DNS over QUIC (#534).\n    Currently only non-proxied lookup is supported.\n  * No longer Release s390x, ppc64, ppc64le, and MIPS SoftFloat\n\n -- ymshenyu <ymshenyu@gmail.com>  Mon, 04 Jan 2021 22:00:51 +0800\n\nv2ray-core (4.33.0-1) unstable; urgency=medium\n\n  * Remove XTLS\n  * Add support for Debian package\n  * API: Reflection Service Support\n  * Update to IETF QUIC draft-32 (draft-29 is still supported)\n  * Use Go 1.15.5\n\n -- kslr <kslrwang@gmail.com>  Mon, 04 Jan 2021 22:00:07 +0800\n\nv2ray-core (4.32.1-1) unstable; urgency=medium\n\n  * Initial release\n\n -- ymshenyu <ymshenyu@gmail.com>  Sun, 08 Nov 2020 08:59:07 +0800\n"
  },
  {
    "path": "release/debian/control",
    "content": "Source: v2ray-core\nSection: net\nPriority: optional\nMaintainer: ymshenyu <ymshenyu@gmail.com>\nBuild-Depends:  debhelper-compat (= 12),\n                dh-golang,\nStandards-Version: 4.5.0\nHomepage: https://github.com/v2fly/v2ray-core\n#Vcs-Browser: https://salsa.debian.org/debian/v2ray-core\n#Vcs-Git: https://salsa.debian.org/debian/v2ray-core.git\nRules-Requires-Root: no\nXS-Go-Import-Path: github.com/v2fly/v2ray-core/v5\n\nPackage: v2ray\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nRecommends: v2ray-domain-list-community,\n            v2ray-geoip,\n            v2ray-geoip-only-cn-private\nDescription: Library platform for building proxies in golang\n Project V2Ray is a set of network tools that help you to build your\n own computer network. It secures your network connections and thus\n protects your privacy.\n\nPackage: v2ray-domain-list-community\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nDescription: Library platform for building proxies in golang (routing file)\n Project V2Ray is a set of network tools that help you to build your\n own computer network. It secures your network connections and thus\n protects your privacy.\n\nPackage: v2ray-geoip\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nDescription: Library platform for building proxies in golang (routing file)\n Project V2Ray is a set of network tools that help you to build your\n own computer network. It secures your network connections and thus\n protects your privacy.\n\nPackage: v2ray-geoip-only-cn-private\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nDescription: Library platform for building proxies in golang (routing file)\n Project V2Ray is a set of network tools that help you to build your\n own computer network. It secures your network connections and thus\n protects your privacy.\n"
  },
  {
    "path": "release/debian/copyright",
    "content": "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\nUpstream-Name: v2ray-core\nUpstream-Contact: https://github.com/v2fly/v2ray-core\nSource: https://github.com/v2fly/v2ray-core\n\nFiles: *\nCopyright: 2015-2020 V2Fly Community\nLicense: Expat\n\nFiles: release/config/geoip.dat\nCopyright: 2015-2020 V2Fly Community\nLicense: CC-BY-SA-4.0\n\nFiles: release/config/geoip-only-cn-private.dat\nCopyright: 2015-2020 V2Fly Community\nLicense: CC-BY-SA-4.0\n\nFiles: release/debian/*\nCopyright: 2020 ymshenyu <ymshenyu@gmail.com>\nLicense: Expat\n\nLicense: Expat\n Permission is hereby granted, free of charge, to any person obtaining a\n copy of this software and associated documentation files (the \"Software\"),\n to deal in the Software without restriction, including without limitation\n the rights to use, copy, modify, merge, publish, distribute, sublicense,\n and/or sell copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following conditions:\n .\n The above copyright notice and this permission notice shall be included\n in all copies or substantial portions of the Software.\n .\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nLicense: CC-BY-SA-4.0\n Attribution-ShareAlike 4.0 International\n .\n =======================================================================\n .\n Creative Commons Corporation (\"Creative Commons\") is not a law firm and\n does not provide legal services or legal advice. Distribution of\n Creative Commons public licenses does not create a lawyer-client or\n other relationship. Creative Commons makes its licenses and related\n information available on an \"as-is\" basis. Creative Commons gives no\n warranties regarding its licenses, any material licensed under their\n terms and conditions, or any related information. Creative Commons\n disclaims all liability for damages resulting from their use to the\n fullest extent possible.\n .\n Using Creative Commons Public Licenses\n .\n Creative Commons public licenses provide a standard set of terms and\n conditions that creators and other rights holders may use to share\n original works of authorship and other material subject to copyright\n and certain other rights specified in the public license below. The\n following considerations are for informational purposes only, are not\n exhaustive, 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     wiki.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     wiki.creativecommons.org/Considerations_for_licensees\n .\n =======================================================================\n .\n Creative Commons Attribution-ShareAlike 4.0 International Public\n License\n .\n By exercising the Licensed Rights (defined below), You accept and agree\n to be bound by the terms and conditions of this Creative Commons\n Attribution-ShareAlike 4.0 International Public License (\"Public\n License\"). To the extent this Public License may be interpreted as a\n contract, You are granted the Licensed Rights in consideration of Your\n acceptance of these terms and conditions, and the Licensor grants You\n such rights in consideration of benefits the Licensor receives from\n making the Licensed Material available under these terms and\n conditions.\n .\n .\n Section 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 .\n Section 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 .\n Section 3 -- License Conditions.\n .\n Your exercise of the Licensed Rights is expressly made subject to the\n following 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 .\n Section 4 -- Sui Generis Database Rights.\n .\n Where the Licensed Rights include Sui Generis Database Rights that\n apply 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 .\n For the avoidance of doubt, this Section 4 supplements and does not\n replace Your obligations under this Public License where the Licensed\n Rights include other Copyright and Similar Rights.\n .\n .\n Section 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 .\n Section 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 .\n Section 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 .\n Section 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 .\n Creative Commons is not a party to its public licenses.\n Notwithstanding, Creative Commons may elect to apply one of its public\n licenses to material it publishes and in those instances will be\n considered the \"Licensor.\" Except for the limited purpose of indicating\n that material is shared under a Creative Commons public license or as\n otherwise permitted by the Creative Commons policies published at\n creativecommons.org/policies, Creative Commons does not authorize the\n use of the trademark \"Creative Commons\" or any other trademark or logo\n of Creative Commons without its prior written consent including,\n without limitation, in connection with any unauthorized modifications\n to any of its public licenses or any other arrangements,\n understandings, or agreements concerning use of licensed material. For\n the avoidance of doubt, this paragraph does not form part of the public\n licenses.\n .\n Creative Commons may be contacted at creativecommons.org.\n\n\n# Please also look if there are files or directories which have a\n# different copyright/license attached and list them here.\n# Please avoid picking licenses with terms that are more restrictive than the\n# packaged work, as it may make Debian's contributions unacceptable upstream.\n#\n# If you need, there are some extra license texts available in two places:\n#   /usr/share/debhelper/dh_make/licenses/\n#   /usr/share/common-licenses/\n"
  },
  {
    "path": "release/debian/rules",
    "content": "#!/usr/bin/make -f\n\ninclude /usr/share/dpkg/default.mk\n\nBUILDDIR=_build\n\n%:\n\tdh $@ --builddirectory=$(BUILDDIR) --buildsystem=golang\n\nexecute_after_dh_auto_configure:\n\tgo mod vendor\n\tcp -r vendor/* _build/src\n\noverride_dh_auto_build:\n\tDH_GOPKG=\"github.com/v2fly/v2ray-core/v5/main\" dh_auto_build -- -ldflags \"-s -w\"\n\tcd $(BUILDDIR); mv bin/main bin/v2ray\n\noverride_dh_auto_install:\n\tdh_auto_install -- --no-source\n\noverride_dh_auto_test:\n"
  },
  {
    "path": "release/debian/source/format",
    "content": "3.0 (quilt)\n"
  },
  {
    "path": "release/debian/v2ray-docs.docs",
    "content": "README.md\n"
  },
  {
    "path": "release/debian/v2ray-domain-list-community.install",
    "content": "release/config/geosite.dat usr/share/v2ray\n"
  },
  {
    "path": "release/debian/v2ray-geoip-only-cn-private.install",
    "content": "release/config/geoip-only-cn-private.dat usr/share/v2ray\n"
  },
  {
    "path": "release/debian/v2ray-geoip.install",
    "content": "release/config/geoip.dat usr/share/v2ray\n"
  },
  {
    "path": "release/debian/v2ray.install",
    "content": "usr/bin\nrelease/config/config.json etc/v2ray\n"
  },
  {
    "path": "release/debian/v2ray.service",
    "content": "[Unit]\nDescription=V2Ray Service\nDocumentation=https://www.v2fly.org/\nAfter=network.target nss-lookup.target\n\n[Service]\nUser=nobody\nCapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nNoNewPrivileges=true\nExecStart=/usr/bin/v2ray -config /etc/v2ray/config.json\nRestart=on-failure\nRestartPreventExitStatus=23\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "release/debian/v2ray@.service",
    "content": "[Unit]\nDescription=V2Ray Service\nDocumentation=https://www.v2fly.org/\nAfter=network.target nss-lookup.target\n\n[Service]\nUser=nobody\nCapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nAmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE\nNoNewPrivileges=true\nExecStart=/usr/bin/v2ray -config /etc/v2ray/%i.json\nRestart=on-failure\nRestartPreventExitStatus=23\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "release/extra/browserforwarder/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Bridge</title>\n</head>\n<body>\nSee debug console for detail\n<script src=\"index.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "release/extra/browserforwarder/index.js",
    "content": "\"use strict\";\n(function() {\n\nvar $global,$module;if(Error.stackTraceLimit=1/0,\"undefined\"!=typeof window?$global=window:\"undefined\"!=typeof self?$global=self:\"undefined\"!=typeof global?($global=global).require=require:$global=this,void 0===$global||void 0===$global.Array)throw new Error(\"no global object found\");\"undefined\"!=typeof module&&($module=module);var $throwRuntimeError,$packages={},$idCounter=0,$keys=function(e){return e?Object.keys(e):[]},$flushConsole=function(){},$throwNilPointerError=function(){$throwRuntimeError(\"invalid memory address or nil pointer dereference\")},$call=function(e,n,r){return e.apply(n,r)},$makeFunc=function(e){return function(){return $externalize(e(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface)}},$unused=function(e){},$mapArray=function(e,n){for(var r=new e.constructor(e.length),t=0;t<e.length;t++)r[t]=n(e[t]);return r},$methodVal=function(e,n){var r=e.$methodVals||{};e.$methodVals=r;var t=r[n];if(void 0!==t)return t;var i=e[n];return t=function(){$stackDepthOffset--;try{return i.apply(e,arguments)}finally{$stackDepthOffset++}},r[n]=t,t},$methodExpr=function(e,n){var r=e.prototype[n];return void 0===r.$expr&&(r.$expr=function(){$stackDepthOffset--;try{return e.wrapped&&(arguments[0]=new e(arguments[0])),Function.call.apply(r,arguments)}finally{$stackDepthOffset++}}),r.$expr},$ifaceMethodExprs={},$ifaceMethodExpr=function(e){var n=$ifaceMethodExprs[\"$\"+e];return void 0===n&&(n=$ifaceMethodExprs[\"$\"+e]=function(){$stackDepthOffset--;try{return Function.call.apply(arguments[0][e],arguments)}finally{$stackDepthOffset++}}),n},$subslice=function(e,n,r,t){if(void 0===r&&(r=e.$length),void 0===t&&(t=e.$capacity),(n<0||r<n||t<r||r>e.$capacity||t>e.$capacity)&&$throwRuntimeError(\"slice bounds out of range\"),e===e.constructor.nil)return e;var i=new e.constructor(e.$array);return i.$offset=e.$offset+n,i.$length=r-n,i.$capacity=t-n,i},$substring=function(e,n,r){return(n<0||r<n||r>e.length)&&$throwRuntimeError(\"slice bounds out of range\"),e.substring(n,r)},$sliceToArray=function(e){return e.$array.constructor!==Array?e.$array.subarray(e.$offset,e.$offset+e.$length):e.$array.slice(e.$offset,e.$offset+e.$length)},$decodeRune=function(e,n){var r=e.charCodeAt(n);if(r<128)return[r,1];if(r!=r||r<192)return[65533,1];var t=e.charCodeAt(n+1);if(t!=t||t<128||192<=t)return[65533,1];if(r<224)return(a=(31&r)<<6|63&t)<=127?[65533,1]:[a,2];var i=e.charCodeAt(n+2);if(i!=i||i<128||192<=i)return[65533,1];if(r<240)return(a=(15&r)<<12|(63&t)<<6|63&i)<=2047?[65533,1]:55296<=a&&a<=57343?[65533,1]:[a,3];var a,o=e.charCodeAt(n+3);return o!=o||o<128||192<=o?[65533,1]:r<248?(a=(7&r)<<18|(63&t)<<12|(63&i)<<6|63&o)<=65535||1114111<a?[65533,1]:[a,4]:[65533,1]},$encodeRune=function(e){return(e<0||e>1114111||55296<=e&&e<=57343)&&(e=65533),e<=127?String.fromCharCode(e):e<=2047?String.fromCharCode(192|e>>6,128|63&e):e<=65535?String.fromCharCode(224|e>>12,128|e>>6&63,128|63&e):String.fromCharCode(240|e>>18,128|e>>12&63,128|e>>6&63,128|63&e)},$stringToBytes=function(e){for(var n=new Uint8Array(e.length),r=0;r<e.length;r++)n[r]=e.charCodeAt(r);return n},$bytesToString=function(e){if(0===e.$length)return\"\";for(var n=\"\",r=0;r<e.$length;r+=1e4)n+=String.fromCharCode.apply(void 0,e.$array.subarray(e.$offset+r,e.$offset+Math.min(e.$length,r+1e4)));return n},$stringToRunes=function(e){for(var n,r=new Int32Array(e.length),t=0,i=0;i<e.length;i+=n[1],t++)n=$decodeRune(e,i),r[t]=n[0];return r.subarray(0,t)},$runesToString=function(e){if(0===e.$length)return\"\";for(var n=\"\",r=0;r<e.$length;r++)n+=$encodeRune(e.$array[e.$offset+r]);return n},$copyString=function(e,n){for(var r=Math.min(n.length,e.$length),t=0;t<r;t++)e.$array[e.$offset+t]=n.charCodeAt(t);return r},$copySlice=function(e,n){var r=Math.min(n.$length,e.$length);return $copyArray(e.$array,n.$array,e.$offset,n.$offset,r,e.constructor.elem),r},$copyArray=function(e,n,r,t,i,a){if(0!==i&&(e!==n||r!==t))if(n.subarray)e.set(n.subarray(t,t+i),r);else{switch(a.kind){case $kindArray:case $kindStruct:if(e===n&&r>t){for(var o=i-1;o>=0;o--)a.copy(e[r+o],n[t+o]);return}for(o=0;o<i;o++)a.copy(e[r+o],n[t+o]);return}if(e===n&&r>t)for(o=i-1;o>=0;o--)e[r+o]=n[t+o];else for(o=0;o<i;o++)e[r+o]=n[t+o]}},$clone=function(e,n){var r=n.zero();return n.copy(r,e),r},$pointerOfStructConversion=function(e,n){void 0===e.$proxies&&(e.$proxies={},e.$proxies[e.constructor.string]=e);var r=e.$proxies[n.string];if(void 0===r){for(var t={},i=0;i<n.elem.fields.length;i++)!function(n){t[n]={get:function(){return e[n]},set:function(r){e[n]=r}}}(n.elem.fields[i].prop);(r=Object.create(n.prototype,t)).$val=r,e.$proxies[n.string]=r,r.$proxies=e.$proxies}return r},$append=function(e){return $internalAppend(e,arguments,1,arguments.length-1)},$appendSlice=function(e,n){if(n.constructor===String){var r=$stringToBytes(n);return $internalAppend(e,r,0,r.length)}return $internalAppend(e,n.$array,n.$offset,n.$length)},$internalAppend=function(e,n,r,t){if(0===t)return e;var i=e.$array,a=e.$offset,o=e.$length+t,$=e.$capacity;if(o>$)if(a=0,$=Math.max(o,e.$capacity<1024?2*e.$capacity:Math.floor(5*e.$capacity/4)),e.$array.constructor===Array){(i=e.$array.slice(e.$offset,e.$offset+e.$length)).length=$;for(var c=e.constructor.elem.zero,u=e.$length;u<$;u++)i[u]=c()}else(i=new e.$array.constructor($)).set(e.$array.subarray(e.$offset,e.$offset+e.$length));$copyArray(i,n,a+e.$length,r,t,e.constructor.elem);var l=new e.constructor(i);return l.$offset=a,l.$length=o,l.$capacity=$,l},$equal=function(e,n,r){if(r===$jsObjectPtr)return e===n;switch(r.kind){case $kindComplex64:case $kindComplex128:return e.$real===n.$real&&e.$imag===n.$imag;case $kindInt64:case $kindUint64:return e.$high===n.$high&&e.$low===n.$low;case $kindArray:if(e.length!==n.length)return!1;for(var t=0;t<e.length;t++)if(!$equal(e[t],n[t],r.elem))return!1;return!0;case $kindStruct:for(t=0;t<r.fields.length;t++){var i=r.fields[t];if(!$equal(e[i.prop],n[i.prop],i.typ))return!1}return!0;case $kindInterface:return $interfaceIsEqual(e,n);default:return e===n}},$interfaceIsEqual=function(e,n){return e===$ifaceNil||n===$ifaceNil?e===n:e.constructor===n.constructor&&(e.constructor===$jsObjectPtr?e.object===n.object:(e.constructor.comparable||$throwRuntimeError(\"comparing uncomparable type \"+e.constructor.string),$equal(e.$val,n.$val,e.constructor)))},$min=Math.min,$mod=function(e,n){return e%n},$parseInt=parseInt,$parseFloat=function(e){return void 0!==e&&null!==e&&e.constructor===Number?e:parseFloat(e)},$froundBuf=new Float32Array(1),$fround=Math.fround||function(e){return $froundBuf[0]=e,$froundBuf[0]},$imul=Math.imul||function(e,n){var r=65535&e,t=65535&n;return r*t+((e>>>16&65535)*t+r*(n>>>16&65535)<<16>>>0)>>0},$floatKey=function(e){return e!=e?\"NaN$\"+ ++$idCounter:String(e)},$flatten64=function(e){return 4294967296*e.$high+e.$low},$shiftLeft64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high<<n|e.$low>>>32-n,e.$low<<n>>>0):n<64?new e.constructor(e.$low<<n-32,0):new e.constructor(0,0)},$shiftRightInt64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high>>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(e.$high>>31,e.$high>>n-32>>>0):e.$high<0?new e.constructor(-1,4294967295):new e.constructor(0,0)},$shiftRightUint64=function(e,n){return 0===n?e:n<32?new e.constructor(e.$high>>>n,(e.$low>>>n|e.$high<<32-n)>>>0):n<64?new e.constructor(0,e.$high>>>n-32):new e.constructor(0,0)},$mul64=function(e,n){var r=0,t=0;0!=(1&n.$low)&&(r=e.$high,t=e.$low);for(var i=1;i<32;i++)0!=(n.$low&1<<i)&&(r+=e.$high<<i|e.$low>>>32-i,t+=e.$low<<i>>>0);for(i=0;i<32;i++)0!=(n.$high&1<<i)&&(r+=e.$low<<i);return new e.constructor(r,t)},$div64=function(e,n,r){0===n.$high&&0===n.$low&&$throwRuntimeError(\"integer divide by zero\");var t=1,i=1,a=e.$high,o=e.$low;a<0&&(t=-1,i=-1,a=-a,0!==o&&(a--,o=4294967296-o));var $=n.$high,c=n.$low;n.$high<0&&(t*=-1,$=-$,0!==c&&($--,c=4294967296-c));for(var u=0,l=0,s=0;$<2147483648&&(a>$||a===$&&o>c);)$=($<<1|c>>>31)>>>0,c=c<<1>>>0,s++;for(var f=0;f<=s;f++)u=u<<1|l>>>31,l=l<<1>>>0,(a>$||a===$&&o>=c)&&(a-=$,(o-=c)<0&&(a--,o+=4294967296),4294967296===++l&&(u++,l=0)),c=(c>>>1|$<<31)>>>0,$>>>=1;return r?new e.constructor(a*i,o*i):new e.constructor(u*t,l*t)},$divComplex=function(e,n){var r=e.$real===1/0||e.$real===-1/0||e.$imag===1/0||e.$imag===-1/0,t=n.$real===1/0||n.$real===-1/0||n.$imag===1/0||n.$imag===-1/0,i=!r&&(e.$real!=e.$real||e.$imag!=e.$imag),a=!t&&(n.$real!=n.$real||n.$imag!=n.$imag);if(i||a)return new e.constructor(NaN,NaN);if(r&&!t)return new e.constructor(1/0,1/0);if(!r&&t)return new e.constructor(0,0);if(0===n.$real&&0===n.$imag)return 0===e.$real&&0===e.$imag?new e.constructor(NaN,NaN):new e.constructor(1/0,1/0);if(Math.abs(n.$real)<=Math.abs(n.$imag)){var o=n.$real/n.$imag,$=n.$real*o+n.$imag;return new e.constructor((e.$real*o+e.$imag)/$,(e.$imag*o-e.$real)/$)}o=n.$imag/n.$real,$=n.$imag*o+n.$real;return new e.constructor((e.$imag*o+e.$real)/$,(e.$imag-e.$real*o)/$)},$kindBool=1,$kindInt=2,$kindInt8=3,$kindInt16=4,$kindInt32=5,$kindInt64=6,$kindUint=7,$kindUint8=8,$kindUint16=9,$kindUint32=10,$kindUint64=11,$kindUintptr=12,$kindFloat32=13,$kindFloat64=14,$kindComplex64=15,$kindComplex128=16,$kindArray=17,$kindChan=18,$kindFunc=19,$kindInterface=20,$kindMap=21,$kindPtr=22,$kindSlice=23,$kindString=24,$kindStruct=25,$kindUnsafePointer=26,$methodSynthesizers=[],$addMethodSynthesizer=function(e){null!==$methodSynthesizers?$methodSynthesizers.push(e):e()},$synthesizeMethods=function(){$methodSynthesizers.forEach(function(e){e()}),$methodSynthesizers=null},$ifaceKeyFor=function(e){if(e===$ifaceNil)return\"nil\";var n=e.constructor;return n.string+\"$\"+n.keyFor(e.$val)},$identity=function(e){return e},$typeIDCounter=0,$idKey=function(e){return void 0===e.$id&&($idCounter++,e.$id=$idCounter),String(e.$id)},$newType=function(e,n,r,t,i,a,o){var $;switch(n){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindUnsafePointer:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$identity;break;case $kindString:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return\"$\"+e};break;case $kindFloat32:case $kindFloat64:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=function(e){return $floatKey(e)};break;case $kindInt64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindUint64:($=function(e,n){this.$high=e+Math.floor(Math.ceil(n)/4294967296)>>>0,this.$low=n>>>0,this.$val=this}).keyFor=function(e){return e.$high+\"$\"+e.$low};break;case $kindComplex64:($=function(e,n){this.$real=$fround(e),this.$imag=$fround(n),this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindComplex128:($=function(e,n){this.$real=e,this.$imag=n,this.$val=this}).keyFor=function(e){return e.$real+\"$\"+e.$imag};break;case $kindArray:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,\"\",!1,function(e){this.$get=function(){return e},this.$set=function(e){$.copy(this,e)},this.$val=e}),$.init=function(e,n){$.elem=e,$.len=n,$.comparable=e.comparable,$.keyFor=function(n){return Array.prototype.join.call($mapArray(n,function(n){return String(e.keyFor(n)).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}),\"$\")},$.copy=function(n,r){$copyArray(n,r,0,0,r.length,e)},$.ptr.init($),Object.defineProperty($.ptr.nil,\"nilCheck\",{get:$throwNilPointerError})};break;case $kindChan:($=function(e){this.$val=e}).wrapped=!0,$.keyFor=$idKey,$.init=function(e,n,r){$.elem=e,$.sendOnly=n,$.recvOnly=r};break;case $kindFunc:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n,r){$.params=e,$.results=n,$.variadic=r,$.comparable=!1};break;case $kindInterface:($={implementedBy:{},missingMethodFor:{}}).keyFor=$ifaceKeyFor,$.init=function(e){$.methods=e,e.forEach(function(e){$ifaceNil[e.prop]=$throwNilPointerError})};break;case $kindMap:($=function(e){this.$val=e}).wrapped=!0,$.init=function(e,n){$.key=e,$.elem=n,$.comparable=!1};break;case $kindPtr:($=o||function(e,n,r){this.$get=e,this.$set=n,this.$target=r,this.$val=this}).keyFor=$idKey,$.init=function(e){$.elem=e,$.wrapped=e.kind===$kindArray,$.nil=new $($throwNilPointerError,$throwNilPointerError)};break;case $kindSlice:($=function(e){e.constructor!==$.nativeArray&&(e=new $.nativeArray(e)),this.$array=e,this.$offset=0,this.$length=e.length,this.$capacity=e.length,this.$val=this}).init=function(e){$.elem=e,$.comparable=!1,$.nativeArray=$nativeArray(e.kind),$.nil=new $([])};break;case $kindStruct:($=function(e){this.$val=e}).wrapped=!0,$.ptr=$newType(4,$kindPtr,\"*\"+r,!1,i,a,o),$.ptr.elem=$,$.ptr.prototype.$get=function(){return this},$.ptr.prototype.$set=function(e){$.copy(this,e)},$.init=function(e,n){$.pkgPath=e,$.fields=n,n.forEach(function(e){e.typ.comparable||($.comparable=!1)}),$.keyFor=function(e){var r=e.$val;return $mapArray(n,function(e){return String(e.typ.keyFor(r[e.prop])).replace(/\\\\/g,\"\\\\\\\\\").replace(/\\$/g,\"\\\\$\")}).join(\"$\")},$.copy=function(e,r){for(var t=0;t<n.length;t++){var i=n[t];switch(i.typ.kind){case $kindArray:case $kindStruct:i.typ.copy(e[i.prop],r[i.prop]);continue;default:e[i.prop]=r[i.prop];continue}}};var r={};n.forEach(function(e){r[e.prop]={get:$throwNilPointerError,set:$throwNilPointerError}}),$.ptr.nil=Object.create(o.prototype,r),$.ptr.nil.$val=$.ptr.nil,$addMethodSynthesizer(function(){var e=function(e,n,r){void 0===e.prototype[n.prop]&&(e.prototype[n.prop]=function(){var e=this.$val[r.prop];return r.typ===$jsObjectPtr&&(e=new $jsObjectPtr(e)),void 0===e.$val&&(e=new r.typ(e)),e[n.prop].apply(e,arguments)})};n.forEach(function(n){n.embedded&&($methodSet(n.typ).forEach(function(r){e($,r,n),e($.ptr,r,n)}),$methodSet($ptrType(n.typ)).forEach(function(r){e($.ptr,r,n)}))})})};break;default:$panic(new $String(\"invalid kind: \"+n))}switch(n){case $kindBool:case $kindMap:$.zero=function(){return!1};break;case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindUnsafePointer:case $kindFloat32:case $kindFloat64:$.zero=function(){return 0};break;case $kindString:$.zero=function(){return\"\"};break;case $kindInt64:case $kindUint64:case $kindComplex64:case $kindComplex128:var c=new $(0,0);$.zero=function(){return c};break;case $kindPtr:case $kindSlice:$.zero=function(){return $.nil};break;case $kindChan:$.zero=function(){return $chanNil};break;case $kindFunc:$.zero=function(){return $throwNilPointerError};break;case $kindInterface:$.zero=function(){return $ifaceNil};break;case $kindArray:$.zero=function(){var e=$nativeArray($.elem.kind);if(e!==Array)return new e($.len);for(var n=new Array($.len),r=0;r<$.len;r++)n[r]=$.elem.zero();return n};break;case $kindStruct:$.zero=function(){return new $.ptr};break;default:$panic(new $String(\"invalid kind: \"+n))}return $.id=$typeIDCounter,$typeIDCounter++,$.size=e,$.kind=n,$.string=r,$.named=t,$.pkg=i,$.exported=a,$.methods=[],$.methodSetCache=null,$.comparable=!0,$},$methodSet=function(e){if(null!==e.methodSetCache)return e.methodSetCache;var n={},r=e.kind===$kindPtr;if(r&&e.elem.kind===$kindInterface)return e.methodSetCache=[],[];for(var t=[{typ:r?e.elem:e,indirect:r}],i={};t.length>0;){var a=[],o=[];t.forEach(function(e){if(!i[e.typ.string])switch(i[e.typ.string]=!0,e.typ.named&&(o=o.concat(e.typ.methods),e.indirect&&(o=o.concat($ptrType(e.typ).methods))),e.typ.kind){case $kindStruct:e.typ.fields.forEach(function(n){if(n.embedded){var r=n.typ,t=r.kind===$kindPtr;a.push({typ:t?r.elem:r,indirect:e.indirect||t})}});break;case $kindInterface:o=o.concat(e.typ.methods)}}),o.forEach(function(e){void 0===n[e.name]&&(n[e.name]=e)}),t=a}return e.methodSetCache=[],Object.keys(n).sort().forEach(function(r){e.methodSetCache.push(n[r])}),e.methodSetCache},$Bool=$newType(1,$kindBool,\"bool\",!0,\"\",!1,null),$Int=$newType(4,$kindInt,\"int\",!0,\"\",!1,null),$Int8=$newType(1,$kindInt8,\"int8\",!0,\"\",!1,null),$Int16=$newType(2,$kindInt16,\"int16\",!0,\"\",!1,null),$Int32=$newType(4,$kindInt32,\"int32\",!0,\"\",!1,null),$Int64=$newType(8,$kindInt64,\"int64\",!0,\"\",!1,null),$Uint=$newType(4,$kindUint,\"uint\",!0,\"\",!1,null),$Uint8=$newType(1,$kindUint8,\"uint8\",!0,\"\",!1,null),$Uint16=$newType(2,$kindUint16,\"uint16\",!0,\"\",!1,null),$Uint32=$newType(4,$kindUint32,\"uint32\",!0,\"\",!1,null),$Uint64=$newType(8,$kindUint64,\"uint64\",!0,\"\",!1,null),$Uintptr=$newType(4,$kindUintptr,\"uintptr\",!0,\"\",!1,null),$Float32=$newType(4,$kindFloat32,\"float32\",!0,\"\",!1,null),$Float64=$newType(8,$kindFloat64,\"float64\",!0,\"\",!1,null),$Complex64=$newType(8,$kindComplex64,\"complex64\",!0,\"\",!1,null),$Complex128=$newType(16,$kindComplex128,\"complex128\",!0,\"\",!1,null),$String=$newType(8,$kindString,\"string\",!0,\"\",!1,null),$UnsafePointer=$newType(4,$kindUnsafePointer,\"unsafe.Pointer\",!0,\"\",!1,null),$nativeArray=function(e){switch(e){case $kindInt:return Int32Array;case $kindInt8:return Int8Array;case $kindInt16:return Int16Array;case $kindInt32:return Int32Array;case $kindUint:return Uint32Array;case $kindUint8:return Uint8Array;case $kindUint16:return Uint16Array;case $kindUint32:case $kindUintptr:return Uint32Array;case $kindFloat32:return Float32Array;case $kindFloat64:return Float64Array;default:return Array}},$toNativeArray=function(e,n){var r=$nativeArray(e);return r===Array?n:new r(n)},$arrayTypes={},$arrayType=function(e,n){var r=e.id+\"$\"+n,t=$arrayTypes[r];return void 0===t&&(t=$newType(12,$kindArray,\"[\"+n+\"]\"+e.string,!1,\"\",!1,null),$arrayTypes[r]=t,t.init(e,n)),t},$chanType=function(e,n,r){var t=(r?\"<-\":\"\")+\"chan\"+(n?\"<- \":\" \")+e.string,i=n?\"SendChan\":r?\"RecvChan\":\"Chan\",a=e[i];return void 0===a&&(a=$newType(4,$kindChan,t,!1,\"\",!1,null),e[i]=a,a.init(e,n,r)),a},$Chan=function(e,n){(n<0||n>2147483647)&&$throwRuntimeError(\"makechan: size out of range\"),this.$elem=e,this.$capacity=n,this.$buffer=[],this.$sendQueue=[],this.$recvQueue=[],this.$closed=!1},$chanNil=new $Chan(null,0);$chanNil.$sendQueue=$chanNil.$recvQueue={length:0,push:function(){},shift:function(){},indexOf:function(){return-1}};var $funcTypes={},$funcType=function(e,n,r){var t=$mapArray(e,function(e){return e.id}).join(\",\")+\"$\"+$mapArray(n,function(e){return e.id}).join(\",\")+\"$\"+r,i=$funcTypes[t];if(void 0===i){var a=$mapArray(e,function(e){return e.string});r&&(a[a.length-1]=\"...\"+a[a.length-1].substr(2));var o=\"func(\"+a.join(\", \")+\")\";1===n.length?o+=\" \"+n[0].string:n.length>1&&(o+=\" (\"+$mapArray(n,function(e){return e.string}).join(\", \")+\")\"),i=$newType(4,$kindFunc,o,!1,\"\",!1,null),$funcTypes[t]=i,i.init(e,n,r)}return i},$interfaceTypes={},$interfaceType=function(e){var n=$mapArray(e,function(e){return e.pkg+\",\"+e.name+\",\"+e.typ.id}).join(\"$\"),r=$interfaceTypes[n];if(void 0===r){var t=\"interface {}\";0!==e.length&&(t=\"interface { \"+$mapArray(e,function(e){return(\"\"!==e.pkg?e.pkg+\".\":\"\")+e.name+e.typ.string.substr(4)}).join(\"; \")+\" }\"),r=$newType(8,$kindInterface,t,!1,\"\",!1,null),$interfaceTypes[n]=r,r.init(e)}return r},$emptyInterface=$interfaceType([]),$ifaceNil={},$error=$newType(8,$kindInterface,\"error\",!0,\"\",!1,null);$error.init([{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],!1)}]);var $panicValue,$jsObjectPtr,$jsErrorPtr,$mapTypes={},$mapType=function(e,n){var r=e.id+\"$\"+n.id,t=$mapTypes[r];return void 0===t&&(t=$newType(4,$kindMap,\"map[\"+e.string+\"]\"+n.string,!1,\"\",!1,null),$mapTypes[r]=t,t.init(e,n)),t},$makeMap=function(e,n){for(var r={},t=0;t<n.length;t++){var i=n[t];r[e(i.k)]=i}return r},$ptrType=function(e){var n=e.ptr;return void 0===n&&(n=$newType(4,$kindPtr,\"*\"+e.string,!1,\"\",e.exported,null),e.ptr=n,n.init(e)),n},$newDataPointer=function(e,n){return n.elem.kind===$kindStruct?e:new n(function(){return e},function(n){e=n})},$indexPtr=function(e,n,r){return e.$ptr=e.$ptr||{},e.$ptr[n]||(e.$ptr[n]=new r(function(){return e[n]},function(r){e[n]=r}))},$sliceType=function(e){var n=e.slice;return void 0===n&&(n=$newType(12,$kindSlice,\"[]\"+e.string,!1,\"\",!1,null),e.slice=n,n.init(e)),n},$makeSlice=function(e,n,r){r=r||n,(n<0||n>2147483647)&&$throwRuntimeError(\"makeslice: len out of range\"),(r<0||r<n||r>2147483647)&&$throwRuntimeError(\"makeslice: cap out of range\");var t=new e.nativeArray(r);if(e.nativeArray===Array)for(var i=0;i<r;i++)t[i]=e.elem.zero();var a=new e(t);return a.$length=n,a},$structTypes={},$structType=function(e,n){var r=$mapArray(n,function(e){return e.name+\",\"+e.typ.id+\",\"+e.tag}).join(\"$\"),t=$structTypes[r];if(void 0===t){var i=\"struct { \"+$mapArray(n,function(e){return e.name+\" \"+e.typ.string+(\"\"!==e.tag?' \"'+e.tag.replace(/\\\\/g,\"\\\\\\\\\").replace(/\"/g,'\\\\\"')+'\"':\"\")}).join(\"; \")+\" }\";0===n.length&&(i=\"struct {}\"),t=$newType(0,$kindStruct,i,!1,\"\",!1,function(){this.$val=this;for(var e=0;e<n.length;e++){var r=n[e],t=arguments[e];this[r.prop]=void 0!==t?t:r.typ.zero()}}),$structTypes[r]=t,t.init(e,n)}return t},$assertType=function(e,n,r){var t,i=n.kind===$kindInterface,a=\"\";if(e===$ifaceNil)t=!1;else if(i){var o=e.constructor.string;if(void 0===(t=n.implementedBy[o])){t=!0;for(var $=$methodSet(e.constructor),c=n.methods,u=0;u<c.length;u++){for(var l=c[u],s=!1,f=0;f<$.length;f++){var d=$[f];if(d.name===l.name&&d.pkg===l.pkg&&d.typ===l.typ){s=!0;break}}if(!s){t=!1,n.missingMethodFor[o]=l.name;break}}n.implementedBy[o]=t}t||(a=n.missingMethodFor[o])}else t=e.constructor===n;if(!t){if(r)return[n.zero(),!1];$panic(new $packages.runtime.TypeAssertionError.ptr($packages.runtime._type.ptr.nil,e===$ifaceNil?$packages.runtime._type.ptr.nil:new $packages.runtime._type.ptr(e.constructor.string),new $packages.runtime._type.ptr(n.string),a))}return i||(e=e.$val),n===$jsObjectPtr&&(e=e.object),r?[e,!0]:e},$stackDepthOffset=0,$getStackDepth=function(){var e=new Error;if(void 0!==e.stack)return $stackDepthOffset+e.stack.split(\"\\n\").length},$panicStackDepth=null,$callDeferred=function(e,n,r){if(!r&&null!==e&&e.index>=$curGoroutine.deferStack.length)throw n;if(null!==n){var t=null;try{$curGoroutine.deferStack.push(e),$panic(new $jsErrorPtr(n))}catch(e){t=e}return $curGoroutine.deferStack.pop(),void $callDeferred(e,t)}if(!$curGoroutine.asleep){$stackDepthOffset--;var i=$panicStackDepth,a=$panicValue,o=$curGoroutine.panicStack.pop();void 0!==o&&($panicStackDepth=$getStackDepth(),$panicValue=o);try{for(;;){if(null===e&&void 0===(e=$curGoroutine.deferStack[$curGoroutine.deferStack.length-1])){if($panicStackDepth=null,o.Object instanceof Error)throw o.Object;var $;throw $=o.constructor===$String?o.$val:void 0!==o.Error?o.Error():void 0!==o.String?o.String():o,new Error($)}var c=e.pop();if(void 0===c){if($curGoroutine.deferStack.pop(),void 0!==o){e=null;continue}return}var u=c[0].apply(c[2],c[1]);if(u&&void 0!==u.$blk){if(e.push([u.$blk,[],u]),r)throw null;return}if(void 0!==o&&null===$panicStackDepth)throw null}}finally{void 0!==o&&(null!==$panicStackDepth&&$curGoroutine.panicStack.push(o),$panicStackDepth=i,$panicValue=a),$stackDepthOffset++}}},$panic=function(e){$curGoroutine.panicStack.push(e),$callDeferred(null,null,!0)},$recover=function(){return null===$panicStackDepth||void 0!==$panicStackDepth&&$panicStackDepth!==$getStackDepth()-2?$ifaceNil:($panicStackDepth=null,$panicValue)},$throw=function(e){throw e},$noGoroutine={asleep:!1,exit:!1,deferStack:[],panicStack:[]},$curGoroutine=$noGoroutine,$totalGoroutines=0,$awakeGoroutines=0,$checkForDeadlock=!0,$mainFinished=!1,$go=function(e,n){$totalGoroutines++,$awakeGoroutines++;var r=function(){try{$curGoroutine=r;var t=e.apply(void 0,n);if(t&&void 0!==t.$blk)return e=function(){return t.$blk()},void(n=[]);r.exit=!0}catch(e){if(!r.exit)throw e}finally{$curGoroutine=$noGoroutine,r.exit&&($totalGoroutines--,r.asleep=!0),r.asleep&&($awakeGoroutines--,!$mainFinished&&0===$awakeGoroutines&&$checkForDeadlock&&(console.error(\"fatal error: all goroutines are asleep - deadlock!\"),void 0!==$global.process&&$global.process.exit(2)))}};r.asleep=!1,r.exit=!1,r.deferStack=[],r.panicStack=[],$schedule(r)},$scheduled=[],$runScheduled=function(){try{for(var e;void 0!==(e=$scheduled.shift());)e()}finally{$scheduled.length>0&&setTimeout($runScheduled,0)}},$schedule=function(e){e.asleep&&(e.asleep=!1,$awakeGoroutines++),$scheduled.push(e),$curGoroutine===$noGoroutine&&$runScheduled()},$setTimeout=function(e,n){return $awakeGoroutines++,setTimeout(function(){$awakeGoroutines--,e()},n)},$block=function(){$curGoroutine===$noGoroutine&&$throwRuntimeError(\"cannot block in JavaScript callback, fix by wrapping code in goroutine\"),$curGoroutine.asleep=!0},$send=function(e,n){e.$closed&&$throwRuntimeError(\"send on closed channel\");var r=e.$recvQueue.shift();if(void 0===r){if(!(e.$buffer.length<e.$capacity)){var t,i=$curGoroutine;return e.$sendQueue.push(function(e){return t=e,$schedule(i),n}),$block(),{$blk:function(){t&&$throwRuntimeError(\"send on closed channel\")}}}e.$buffer.push(n)}else r([n,!0])},$recv=function(e){var n=e.$sendQueue.shift();void 0!==n&&e.$buffer.push(n(!1));var r=e.$buffer.shift();if(void 0!==r)return[r,!0];if(e.$closed)return[e.$elem.zero(),!1];var t=$curGoroutine,i={$blk:function(){return this.value}};return e.$recvQueue.push(function(e){i.value=e,$schedule(t)}),$block(),i},$close=function(e){for(e.$closed&&$throwRuntimeError(\"close of closed channel\"),e.$closed=!0;;){var n=e.$sendQueue.shift();if(void 0===n)break;n(!0)}for(;;){var r=e.$recvQueue.shift();if(void 0===r)break;r([e.$elem.zero(),!1])}},$select=function(e){for(var n=[],r=-1,t=0;t<e.length;t++){var i,a=(i=e[t])[0];switch(i.length){case 0:r=t;break;case 1:(0!==a.$sendQueue.length||0!==a.$buffer.length||a.$closed)&&n.push(t);break;case 2:a.$closed&&$throwRuntimeError(\"send on closed channel\"),(0!==a.$recvQueue.length||a.$buffer.length<a.$capacity)&&n.push(t)}}if(0!==n.length&&(r=n[Math.floor(Math.random()*n.length)]),-1!==r)switch((i=e[r]).length){case 0:return[r];case 1:return[r,$recv(i[0])];case 2:return $send(i[0],i[1]),[r]}var o=[],$=$curGoroutine,c={$blk:function(){return this.selection}},u=function(){for(var e=0;e<o.length;e++){var n=o[e],r=n[0],t=r.indexOf(n[1]);-1!==t&&r.splice(t,1)}};for(t=0;t<e.length;t++)!function(n){var r=e[n];switch(r.length){case 1:var t=function(e){c.selection=[n,e],u(),$schedule($)};o.push([r[0].$recvQueue,t]),r[0].$recvQueue.push(t);break;case 2:t=function(){return r[0].$closed&&$throwRuntimeError(\"send on closed channel\"),c.selection=[n],u(),$schedule($),r[1]};o.push([r[0].$sendQueue,t]),r[0].$sendQueue.push(t)}}(t);return $block(),c},$needsExternalization=function(e){switch(e.kind){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindFloat32:case $kindFloat64:return!1;default:return e!==$jsObjectPtr}},$externalize=function(e,n){if(n===$jsObjectPtr)return e;switch(n.kind){case $kindBool:case $kindInt:case $kindInt8:case $kindInt16:case $kindInt32:case $kindUint:case $kindUint8:case $kindUint16:case $kindUint32:case $kindUintptr:case $kindFloat32:case $kindFloat64:return e;case $kindInt64:case $kindUint64:return $flatten64(e);case $kindArray:return $needsExternalization(n.elem)?$mapArray(e,function(e){return $externalize(e,n.elem)}):e;case $kindFunc:return $externalizeFunction(e,n,!1);case $kindInterface:return e===$ifaceNil?null:e.constructor===$jsObjectPtr?e.$val.object:$externalize(e.$val,e.constructor);case $kindMap:for(var r={},t=$keys(e),i=0;i<t.length;i++){var a=e[t[i]];r[$externalize(a.k,n.key)]=$externalize(a.v,n.elem)}return r;case $kindPtr:return e===n.nil?null:$externalize(e.$get(),n.elem);case $kindSlice:return $needsExternalization(n.elem)?$mapArray($sliceToArray(e),function(e){return $externalize(e,n.elem)}):$sliceToArray(e);case $kindString:if($isASCII(e))return e;var o,$=\"\";for(i=0;i<e.length;i+=o[1]){var c=(o=$decodeRune(e,i))[0];if(c>65535){var u=Math.floor((c-65536)/1024)+55296,l=(c-65536)%1024+56320;$+=String.fromCharCode(u,l)}else $+=String.fromCharCode(c)}return $;case $kindStruct:var s=$packages.time;if(void 0!==s&&e.constructor===s.Time.ptr){var f=$div64(e.UnixNano(),new $Int64(0,1e6));return new Date($flatten64(f))}var d={},p=function(e,n){if(n===$jsObjectPtr)return e;switch(n.kind){case $kindPtr:return e===n.nil?d:p(e.$get(),n.elem);case $kindStruct:var r=n.fields[0];return p(e[r.prop],r.typ);case $kindInterface:return p(e.$val,e.constructor);default:return d}},h=p(e,n);if(h!==d)return h;h={};for(i=0;i<n.fields.length;i++){var k=n.fields[i];k.exported&&(h[k.name]=$externalize(e[k.prop],k.typ))}return h}$throwRuntimeError(\"cannot externalize \"+n.string)},$externalizeFunction=function(e,n,r){return e===$throwNilPointerError?null:(void 0===e.$externalizeWrapper&&($checkForDeadlock=!1,e.$externalizeWrapper=function(){for(var t=[],i=0;i<n.params.length;i++){if(n.variadic&&i===n.params.length-1){for(var a=n.params[i].elem,o=[],$=i;$<arguments.length;$++)o.push($internalize(arguments[$],a));t.push(new n.params[i](o));break}t.push($internalize(arguments[i],n.params[i]))}var c=e.apply(r?this:void 0,t);switch(n.results.length){case 0:return;case 1:return $externalize(c,n.results[0]);default:for(i=0;i<n.results.length;i++)c[i]=$externalize(c[i],n.results[i]);return c}}),e.$externalizeWrapper)},$internalize=function(e,n,r){if(n===$jsObjectPtr)return e;if(n===$jsObjectPtr.elem&&$throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\"),e&&void 0!==e.__internal_object__)return $assertType(e.__internal_object__,n,!1);var t=$packages.time;if(void 0!==t&&n===t.Time)return null!==e&&void 0!==e&&e.constructor===Date||$throwRuntimeError(\"cannot internalize time.Time from \"+typeof e+\", must be Date\"),t.Unix(new $Int64(0,0),new $Int64(0,1e6*e.getTime()));switch(n.kind){case $kindBool:return!!e;case $kindInt:return parseInt(e);case $kindInt8:return parseInt(e)<<24>>24;case $kindInt16:return parseInt(e)<<16>>16;case $kindInt32:return parseInt(e)>>0;case $kindUint:return parseInt(e);case $kindUint8:return parseInt(e)<<24>>>24;case $kindUint16:return parseInt(e)<<16>>>16;case $kindUint32:case $kindUintptr:return parseInt(e)>>>0;case $kindInt64:case $kindUint64:return new n(0,e);case $kindFloat32:case $kindFloat64:return parseFloat(e);case $kindArray:return e.length!==n.len&&$throwRuntimeError(\"got array with wrong size from JavaScript native\"),$mapArray(e,function(e){return $internalize(e,n.elem)});case $kindFunc:return function(){for(var t=[],i=0;i<n.params.length;i++){if(n.variadic&&i===n.params.length-1){for(var a=n.params[i].elem,o=arguments[i],$=0;$<o.$length;$++)t.push($externalize(o.$array[o.$offset+$],a));break}t.push($externalize(arguments[i],n.params[i]))}var c=e.apply(r,t);switch(n.results.length){case 0:return;case 1:return $internalize(c,n.results[0]);default:for(i=0;i<n.results.length;i++)c[i]=$internalize(c[i],n.results[i]);return c}};case $kindInterface:if(0!==n.methods.length&&$throwRuntimeError(\"cannot internalize \"+n.string),null===e)return $ifaceNil;if(void 0===e)return new $jsObjectPtr(void 0);switch(e.constructor){case Int8Array:return new($sliceType($Int8))(e);case Int16Array:return new($sliceType($Int16))(e);case Int32Array:return new($sliceType($Int))(e);case Uint8Array:return new($sliceType($Uint8))(e);case Uint16Array:return new($sliceType($Uint16))(e);case Uint32Array:return new($sliceType($Uint))(e);case Float32Array:return new($sliceType($Float32))(e);case Float64Array:return new($sliceType($Float64))(e);case Array:return $internalize(e,$sliceType($emptyInterface));case Boolean:return new $Bool(!!e);case Date:return void 0===t?new $jsObjectPtr(e):new t.Time($internalize(e,t.Time));case Function:var i=$funcType([$sliceType($emptyInterface)],[$jsObjectPtr],!0);return new i($internalize(e,i));case Number:return new $Float64(parseFloat(e));case String:return new $String($internalize(e,$String));default:if($global.Node&&e instanceof $global.Node)return new $jsObjectPtr(e);var a=$mapType($String,$emptyInterface);return new a($internalize(e,a))}case $kindMap:for(var o={},$=$keys(e),c=0;c<$.length;c++){var u=$internalize($[c],n.key);o[n.key.keyFor(u)]={k:u,v:$internalize(e[$[c]],n.elem)}}return o;case $kindPtr:if(n.elem.kind===$kindStruct)return $internalize(e,n.elem);case $kindSlice:return new n($mapArray(e,function(e){return $internalize(e,n.elem)}));case $kindString:if(e=String(e),$isASCII(e))return e;var l=\"\";for(c=0;c<e.length;){var s=e.charCodeAt(c);if(55296<=s&&s<=56319){var f=e.charCodeAt(c+1);l+=$encodeRune(1024*(s-55296)+f-56320+65536),c+=2}else l+=$encodeRune(s),c++}return l;case $kindStruct:var d={},p=function(n){if(n===$jsObjectPtr)return e;switch(n===$jsObjectPtr.elem&&$throwRuntimeError(\"cannot internalize js.Object, use *js.Object instead\"),n.kind){case $kindPtr:return p(n.elem);case $kindStruct:var r=n.fields[0],t=p(r.typ);if(t!==d){var i=new n.ptr;return i[r.prop]=t,i}return d;default:return d}},h=p(n);if(h!==d)return h}$throwRuntimeError(\"cannot internalize \"+n.string)},$isASCII=function(e){for(var n=0;n<e.length;n++)if(e.charCodeAt(n)>=128)return!1;return!0};\n\n$packages[\"github.com/gopherjs/gopherjs/js\"]=(function(){var $pkg={},$init,A,B,L,N,Q,E,K;A=$pkg.Object=$newType(0,$kindStruct,\"js.Object\",true,\"github.com/gopherjs/gopherjs/js\",true,function(object_){this.$val=this;if(arguments.length===0){this.object=null;return;}this.object=object_;});B=$pkg.Error=$newType(0,$kindStruct,\"js.Error\",true,\"github.com/gopherjs/gopherjs/js\",true,function(Object_){this.$val=this;if(arguments.length===0){this.Object=null;return;}this.Object=Object_;});L=$sliceType($emptyInterface);N=$ptrType(A);Q=$ptrType(B);A.ptr.prototype.Get=function(a){var a,b;b=this;return b.object[$externalize(a,$String)];};A.prototype.Get=function(a){return this.$val.Get(a);};A.ptr.prototype.Set=function(a,b){var a,b,c;c=this;c.object[$externalize(a,$String)]=$externalize(b,$emptyInterface);};A.prototype.Set=function(a,b){return this.$val.Set(a,b);};A.ptr.prototype.Delete=function(a){var a,b;b=this;delete b.object[$externalize(a,$String)];};A.prototype.Delete=function(a){return this.$val.Delete(a);};A.ptr.prototype.Length=function(){var a;a=this;return $parseInt(a.object.length);};A.prototype.Length=function(){return this.$val.Length();};A.ptr.prototype.Index=function(a){var a,b;b=this;return b.object[a];};A.prototype.Index=function(a){return this.$val.Index(a);};A.ptr.prototype.SetIndex=function(a,b){var a,b,c;c=this;c.object[a]=$externalize(b,$emptyInterface);};A.prototype.SetIndex=function(a,b){return this.$val.SetIndex(a,b);};A.ptr.prototype.Call=function(a,b){var a,b,c,d;c=this;return(d=c.object,d[$externalize(a,$String)].apply(d,$externalize(b,L)));};A.prototype.Call=function(a,b){return this.$val.Call(a,b);};A.ptr.prototype.Invoke=function(a){var a,b;b=this;return b.object.apply(undefined,$externalize(a,L));};A.prototype.Invoke=function(a){return this.$val.Invoke(a);};A.ptr.prototype.New=function(a){var a,b;b=this;return new($global.Function.prototype.bind.apply(b.object,[undefined].concat($externalize(a,L))));};A.prototype.New=function(a){return this.$val.New(a);};A.ptr.prototype.Bool=function(){var a;a=this;return!!(a.object);};A.prototype.Bool=function(){return this.$val.Bool();};A.ptr.prototype.String=function(){var a;a=this;return $internalize(a.object,$String);};A.prototype.String=function(){return this.$val.String();};A.ptr.prototype.Int=function(){var a;a=this;return $parseInt(a.object)>>0;};A.prototype.Int=function(){return this.$val.Int();};A.ptr.prototype.Int64=function(){var a;a=this;return $internalize(a.object,$Int64);};A.prototype.Int64=function(){return this.$val.Int64();};A.ptr.prototype.Uint64=function(){var a;a=this;return $internalize(a.object,$Uint64);};A.prototype.Uint64=function(){return this.$val.Uint64();};A.ptr.prototype.Float=function(){var a;a=this;return $parseFloat(a.object);};A.prototype.Float=function(){return this.$val.Float();};A.ptr.prototype.Interface=function(){var a;a=this;return $internalize(a.object,$emptyInterface);};A.prototype.Interface=function(){return this.$val.Interface();};A.ptr.prototype.Unsafe=function(){var a;a=this;return a.object;};A.prototype.Unsafe=function(){return this.$val.Unsafe();};B.ptr.prototype.Error=function(){var a;a=this;return\"JavaScript error: \"+$internalize(a.Object.message,$String);};B.prototype.Error=function(){return this.$val.Error();};B.ptr.prototype.Stack=function(){var a;a=this;return $internalize(a.Object.stack,$String);};B.prototype.Stack=function(){return this.$val.Stack();};E=function(a){var a;return $makeFunc(a);};$pkg.MakeFunc=E;K=function(){var a;a=new B.ptr(null);$unused(a);};N.methods=[{prop:\"Get\",name:\"Get\",pkg:\"\",typ:$funcType([$String],[N],false)},{prop:\"Set\",name:\"Set\",pkg:\"\",typ:$funcType([$String,$emptyInterface],[],false)},{prop:\"Delete\",name:\"Delete\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"Length\",name:\"Length\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Index\",name:\"Index\",pkg:\"\",typ:$funcType([$Int],[N],false)},{prop:\"SetIndex\",name:\"SetIndex\",pkg:\"\",typ:$funcType([$Int,$emptyInterface],[],false)},{prop:\"Call\",name:\"Call\",pkg:\"\",typ:$funcType([$String,L],[N],true)},{prop:\"Invoke\",name:\"Invoke\",pkg:\"\",typ:$funcType([L],[N],true)},{prop:\"New\",name:\"New\",pkg:\"\",typ:$funcType([L],[N],true)},{prop:\"Bool\",name:\"Bool\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Int\",name:\"Int\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Int64\",name:\"Int64\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([],[$Uint64],false)},{prop:\"Float\",name:\"Float\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Interface\",name:\"Interface\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)},{prop:\"Unsafe\",name:\"Unsafe\",pkg:\"\",typ:$funcType([],[$Uintptr],false)}];Q.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Stack\",name:\"Stack\",pkg:\"\",typ:$funcType([],[$String],false)}];A.init(\"github.com/gopherjs/gopherjs/js\",[{prop:\"object\",name:\"object\",embedded:false,exported:false,typ:N,tag:\"\"}]);B.init(\"\",[{prop:\"Object\",name:\"Object\",embedded:true,exported:true,typ:N,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:K();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/cpu\"]=(function(){var $pkg={},$init;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/bytealg\"]=(function(){var $pkg={},$init,A,B,I,K,M;A=$packages[\"internal/cpu\"];B=function(b,c){var b,c,d,e,f,g;if(!((b.$length===c.$length))){return false;}d=b;e=0;while(true){if(!(e<d.$length)){break;}f=e;g=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);if(!((g===((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f])))){return false;}e++;}return true;};$pkg.Equal=B;I=function(b,c){var b,c;$panic(new $String(\"unimplemented\"));};$pkg.Index=I;K=function(b){var b;$panic(new $String(\"unimplemented\"));};$pkg.Cutover=K;M=function(b,c){var b,c,d;d=0;while(true){if(!(d<b.length)){break;}if(b.charCodeAt(d)===c){return d;}d=d+(1)>>0;}return-1;};$pkg.IndexByteString=M;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.MaxLen=0;}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"runtime/internal/sys\"]=(function(){var $pkg={},$init;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"runtime\"]=(function(){var $pkg={},$init,B,C,A,E,AQ,AR,AX,BF,F,G,I,O,V,AJ,AK;B=$packages[\"github.com/gopherjs/gopherjs/js\"];C=$packages[\"internal/bytealg\"];A=$packages[\"runtime/internal/sys\"];E=$pkg._type=$newType(0,$kindStruct,\"runtime._type\",true,\"runtime\",false,function(str_){this.$val=this;if(arguments.length===0){this.str=\"\";return;}this.str=str_;});AQ=$pkg.TypeAssertionError=$newType(0,$kindStruct,\"runtime.TypeAssertionError\",true,\"runtime\",true,function(_interface_,concrete_,asserted_,missingMethod_){this.$val=this;if(arguments.length===0){this._interface=AX.nil;this.concrete=AX.nil;this.asserted=AX.nil;this.missingMethod=\"\";return;}this._interface=_interface_;this.concrete=concrete_;this.asserted=asserted_;this.missingMethod=missingMethod_;});AR=$pkg.errorString=$newType(8,$kindString,\"runtime.errorString\",true,\"runtime\",false,null);AX=$ptrType(E);BF=$ptrType(AQ);E.ptr.prototype.string=function(){var a;a=this;return a.str;};E.prototype.string=function(){return this.$val.string();};E.ptr.prototype.pkgpath=function(){var a;a=this;return\"\";};E.prototype.pkgpath=function(){return this.$val.pkgpath();};F=function(){var a,b;a=$packages[$externalize(\"github.com/gopherjs/gopherjs/js\",$String)];$jsObjectPtr=a.Object.ptr;$jsErrorPtr=a.Error.ptr;$throwRuntimeError=AK;b=$ifaceNil;b=new AQ.ptr(AX.nil,AX.nil,AX.nil,\"\");$unused(b);};G=function(){var a,b,c;a=$global.process;if(a===undefined){return\"/\";}b=a.env.GOPHERJS_GOROOT;if(!(b===undefined)){return $internalize(b,$String);}else{c=a.env.GOROOT;if(!(c===undefined)){return $internalize(c,$String);}}return\"/usr/local/go\";};$pkg.GOROOT=G;I=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=0;c=\"\";d=0;e=false;f=new($global.Error)().stack.split($externalize(\"\\n\",$String))[(a+2>>0)];if(f===undefined){g=0;h=\"\";i=0;j=false;b=g;c=h;d=i;e=j;return[b,c,d,e];}k=f.substring(($parseInt(f.indexOf($externalize(\"(\",$String)))>>0)+1>>0,$parseInt(f.indexOf($externalize(\")\",$String)))>>0).split($externalize(\":\",$String));l=0;m=$internalize(k[0],$String);n=$parseInt(k[1])>>0;o=true;b=l;c=m;d=n;e=o;return[b,c,d,e];};$pkg.Caller=I;O=function(){$curGoroutine.exit=$externalize(true,$Bool);$throw(null);};$pkg.Goexit=O;V=function(a,b){var a,b;};$pkg.SetFinalizer=V;AJ=function(a){var a;};$pkg.KeepAlive=AJ;AK=function(a){var a;$panic(new AR((a)));};AQ.ptr.prototype.RuntimeError=function(){};AQ.prototype.RuntimeError=function(){return this.$val.RuntimeError();};AQ.ptr.prototype.Error=function(){var a,b,c,d,e;a=this;b=\"interface\";if(!(a._interface===AX.nil)){b=a._interface.string();}c=a.asserted.string();if(a.concrete===AX.nil){return\"interface conversion: \"+b+\" is nil, not \"+c;}d=a.concrete.string();if(a.missingMethod===\"\"){e=\"interface conversion: \"+b+\" is \"+d+\", not \"+c;if(d===c){if(!(a.concrete.pkgpath()===a.asserted.pkgpath())){e=e+(\" (types from different packages)\");}else{e=e+(\" (types from different scopes)\");}}return e;}return\"interface conversion: \"+d+\" is not \"+c+\": missing method \"+a.missingMethod;};AQ.prototype.Error=function(){return this.$val.Error();};AR.prototype.RuntimeError=function(){var a;a=this.$val;};$ptrType(AR).prototype.RuntimeError=function(){return new AR(this.$get()).RuntimeError();};AR.prototype.Error=function(){var a;a=this.$val;return\"runtime error: \"+(a);};$ptrType(AR).prototype.Error=function(){return new AR(this.$get()).Error();};AX.methods=[{prop:\"string\",name:\"string\",pkg:\"runtime\",typ:$funcType([],[$String],false)},{prop:\"pkgpath\",name:\"pkgpath\",pkg:\"runtime\",typ:$funcType([],[$String],false)}];BF.methods=[{prop:\"RuntimeError\",name:\"RuntimeError\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];AR.methods=[{prop:\"RuntimeError\",name:\"RuntimeError\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];E.init(\"runtime\",[{prop:\"str\",name:\"str\",embedded:false,exported:false,typ:$String,tag:\"\"}]);AQ.init(\"runtime\",[{prop:\"_interface\",name:\"_interface\",embedded:false,exported:false,typ:AX,tag:\"\"},{prop:\"concrete\",name:\"concrete\",embedded:false,exported:false,typ:AX,tag:\"\"},{prop:\"asserted\",name:\"asserted\",embedded:false,exported:false,typ:AX,tag:\"\"},{prop:\"missingMethod\",name:\"missingMethod\",embedded:false,exported:false,typ:$String,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}F();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"errors\"]=(function(){var $pkg={},$init,B,C,A;B=$pkg.errorString=$newType(0,$kindStruct,\"errors.errorString\",true,\"errors\",false,function(s_){this.$val=this;if(arguments.length===0){this.s=\"\";return;}this.s=s_;});C=$ptrType(B);A=function(a){var a;return new B.ptr(a);};$pkg.New=A;B.ptr.prototype.Error=function(){var a;a=this;return a.s;};B.prototype.Error=function(){return this.$val.Error();};C.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];B.init(\"errors\",[{prop:\"s\",name:\"s\",embedded:false,exported:false,typ:$String,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"math/bits\"]=(function(){var $pkg={},$init,I,J,BC,H,K,N,O,AM;H=function(a){var a;return 64-AM(a)>>0;};$pkg.LeadingZeros64=H;K=function(a){var a;if(true){return N(((a>>>0)));}return O((new $Uint64(0,a)));};$pkg.TrailingZeros=K;N=function(a){var a,b;if(a===0){return 32;}return(((b=($imul((((a&(-a>>>0))>>>0)),125613361)>>>0)>>>27>>>0,((b<0||b>=I.length)?($throwRuntimeError(\"index out of range\"),undefined):I[b]))>>0));};$pkg.TrailingZeros32=N;O=function(a){var a,b,c;if((a.$high===0&&a.$low===0)){return 64;}return(((b=$shiftRightUint64($mul64(((c=new $Uint64(-a.$high,-a.$low),new $Uint64(a.$high&c.$high,(a.$low&c.$low)>>>0))),new $Uint64(66559345,3033172745)),58),(($flatten64(b)<0||$flatten64(b)>=J.length)?($throwRuntimeError(\"index out of range\"),undefined):J[$flatten64(b)]))>>0));};$pkg.TrailingZeros64=O;AM=function(a){var a,b;b=0;if((a.$high>1||(a.$high===1&&a.$low>=0))){a=$shiftRightUint64(a,(32));b=32;}if((a.$high>0||(a.$high===0&&a.$low>=65536))){a=$shiftRightUint64(a,(16));b=b+(16)>>0;}if((a.$high>0||(a.$high===0&&a.$low>=256))){a=$shiftRightUint64(a,(8));b=b+(8)>>0;}b=b+(((($flatten64(a)<0||$flatten64(a)>=BC.length)?($throwRuntimeError(\"index out of range\"),undefined):BC[$flatten64(a)])>>0))>>0;return b;};$pkg.Len64=AM;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:I=$toNativeArray($kindUint8,[0,1,28,2,29,14,24,3,30,22,20,15,25,17,4,8,31,27,13,23,21,19,16,7,26,12,18,6,11,5,10,9]);J=$toNativeArray($kindUint8,[0,1,56,2,57,49,28,3,61,58,42,50,38,29,17,4,62,47,59,36,45,43,51,22,53,39,33,30,24,18,12,5,63,55,48,27,60,41,37,16,46,35,44,21,52,32,23,11,54,26,40,15,34,20,31,10,25,14,19,9,13,8,7,6]);BC=$toNativeArray($kindUint8,[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"math\"]=(function(){var $pkg={},$init,A,B,FV,FW,FX,FY,C,D,G,AY,V,AF,AZ,BA,BB,BC,BD;A=$packages[\"github.com/gopherjs/gopherjs/js\"];B=$packages[\"math/bits\"];FV=$arrayType($Uint32,2);FW=$arrayType($Float32,2);FX=$arrayType($Float64,1);FY=$structType(\"math\",[{prop:\"uint32array\",name:\"uint32array\",embedded:false,exported:false,typ:FV,tag:\"\"},{prop:\"float32array\",name:\"float32array\",embedded:false,exported:false,typ:FW,tag:\"\"},{prop:\"float64array\",name:\"float64array\",embedded:false,exported:false,typ:FX,tag:\"\"}]);V=function(av){var av;return $parseFloat(C.exp(av));};$pkg.Exp=V;AF=function(av){var av;if(!((av===av))){return G;}return $parseFloat(C.log(av));};$pkg.Log=AF;AZ=function(){var av;av=new($global.ArrayBuffer)(8);AY.uint32array=new($global.Uint32Array)(av);AY.float32array=new($global.Float32Array)(av);AY.float64array=new($global.Float64Array)(av);};BA=function(av){var av;AY.float32array[0]=av;return AY.uint32array[0];};$pkg.Float32bits=BA;BB=function(av){var av;AY.uint32array[0]=av;return AY.float32array[0];};$pkg.Float32frombits=BB;BC=function(av){var av,aw,ax;AY.float64array[0]=av;return(aw=$shiftLeft64((new $Uint64(0,AY.uint32array[1])),32),ax=(new $Uint64(0,AY.uint32array[0])),new $Uint64(aw.$high+ax.$high,aw.$low+ax.$low));};$pkg.Float64bits=BC;BD=function(av){var av;AY.uint32array[0]=((av.$low>>>0));AY.uint32array[1]=(($shiftRightUint64(av,32).$low>>>0));return AY.float64array[0];};$pkg.Float64frombits=BD;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}AY=new FY.ptr(FV.zero(),FW.zero(),FX.zero());C=$global.Math;D=0;G=0/D;AZ();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"unicode/utf8\"]=(function(){var $pkg={},$init,B,A,C,F,G,H,I,J,K,L,M,N,P,Q;B=$pkg.acceptRange=$newType(0,$kindStruct,\"utf8.acceptRange\",true,\"unicode/utf8\",false,function(lo_,hi_){this.$val=this;if(arguments.length===0){this.lo=0;this.hi=0;return;}this.lo=lo_;this.hi=hi_;});F=function(a){var a,aa,ab,ac,ad,ae,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=0;c=0;d=a.$length;if(d<1){e=65533;f=0;b=e;c=f;return[b,c];}g=(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]);h=((g<0||g>=A.length)?($throwRuntimeError(\"index out of range\"),undefined):A[g]);if(h>=240){i=(((h>>0))<<31>>0)>>31>>0;j=(((((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])>>0))&~i)>>0)|(65533&i);k=1;b=j;c=k;return[b,c];}l=(h&7)>>>0;n=$clone((m=h>>>4<<24>>>24,((m<0||m>=C.length)?($throwRuntimeError(\"index out of range\"),undefined):C[m])),B);if(d<((l>>0))){o=65533;p=1;b=o;c=p;return[b,c];}q=(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]);if(q<n.lo||n.hi<q){r=65533;s=1;b=r;c=s;return[b,c];}if(l===2){t=(((((g&31)>>>0)>>0))<<6>>0)|((((q&63)>>>0)>>0));u=2;b=t;c=u;return[b,c];}v=(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]);if(v<128||191<v){w=65533;x=1;b=w;c=x;return[b,c];}if(l===3){y=((((((g&15)>>>0)>>0))<<12>>0)|(((((q&63)>>>0)>>0))<<6>>0))|((((v&63)>>>0)>>0));z=3;b=y;c=z;return[b,c];}aa=(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]);if(aa<128||191<aa){ab=65533;ac=1;b=ab;c=ac;return[b,c];}ad=(((((((g&7)>>>0)>>0))<<18>>0)|(((((q&63)>>>0)>>0))<<12>>0))|(((((v&63)>>>0)>>0))<<6>>0))|((((aa&63)>>>0)>>0));ae=4;b=ad;c=ae;return[b,c];};$pkg.DecodeRune=F;G=function(a){var a,aa,ab,ac,ad,ae,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=0;c=0;d=a.length;if(d<1){e=65533;f=0;b=e;c=f;return[b,c];}g=a.charCodeAt(0);h=((g<0||g>=A.length)?($throwRuntimeError(\"index out of range\"),undefined):A[g]);if(h>=240){i=(((h>>0))<<31>>0)>>31>>0;j=((((a.charCodeAt(0)>>0))&~i)>>0)|(65533&i);k=1;b=j;c=k;return[b,c];}l=(h&7)>>>0;n=$clone((m=h>>>4<<24>>>24,((m<0||m>=C.length)?($throwRuntimeError(\"index out of range\"),undefined):C[m])),B);if(d<((l>>0))){o=65533;p=1;b=o;c=p;return[b,c];}q=a.charCodeAt(1);if(q<n.lo||n.hi<q){r=65533;s=1;b=r;c=s;return[b,c];}if(l===2){t=(((((g&31)>>>0)>>0))<<6>>0)|((((q&63)>>>0)>>0));u=2;b=t;c=u;return[b,c];}v=a.charCodeAt(2);if(v<128||191<v){w=65533;x=1;b=w;c=x;return[b,c];}if(l===3){y=((((((g&15)>>>0)>>0))<<12>>0)|(((((q&63)>>>0)>>0))<<6>>0))|((((v&63)>>>0)>>0));z=3;b=y;c=z;return[b,c];}aa=a.charCodeAt(3);if(aa<128||191<aa){ab=65533;ac=1;b=ab;c=ac;return[b,c];}ad=(((((((g&7)>>>0)>>0))<<18>>0)|(((((q&63)>>>0)>>0))<<12>>0))|(((((v&63)>>>0)>>0))<<6>>0))|((((aa&63)>>>0)>>0));ae=4;b=ad;c=ae;return[b,c];};$pkg.DecodeRuneInString=G;H=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=0;c=0;d=a.$length;if(d===0){e=65533;f=0;b=e;c=f;return[b,c];}g=d-1>>0;b=((((g<0||g>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+g])>>0));if(b<128){h=b;i=1;b=h;c=i;return[b,c];}j=d-4>>0;if(j<0){j=0;}g=g-(1)>>0;while(true){if(!(g>=j)){break;}if(N(((g<0||g>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+g]))){break;}g=g-(1)>>0;}if(g<0){g=0;}k=F($subslice(a,g,d));b=k[0];c=k[1];if(!(((g+c>>0)===d))){l=65533;m=1;b=l;c=m;return[b,c];}n=b;o=c;b=n;c=o;return[b,c];};$pkg.DecodeLastRune=H;I=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=0;c=0;d=a.length;if(d===0){e=65533;f=0;b=e;c=f;return[b,c];}g=d-1>>0;b=((a.charCodeAt(g)>>0));if(b<128){h=b;i=1;b=h;c=i;return[b,c];}j=d-4>>0;if(j<0){j=0;}g=g-(1)>>0;while(true){if(!(g>=j)){break;}if(N(a.charCodeAt(g))){break;}g=g-(1)>>0;}if(g<0){g=0;}k=G($substring(a,g,d));b=k[0];c=k[1];if(!(((g+c>>0)===d))){l=65533;m=1;b=l;c=m;return[b,c];}n=b;o=c;b=n;c=o;return[b,c];};$pkg.DecodeLastRuneInString=I;J=function(a){var a;if(a<0){return-1;}else if(a<=127){return 1;}else if(a<=2047){return 2;}else if(55296<=a&&a<=57343){return-1;}else if(a<=65535){return 3;}else if(a<=1114111){return 4;}return-1;};$pkg.RuneLen=J;K=function(a,b){var a,b,c;c=((b>>>0));if(c<=127){(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((b<<24>>>24)));return 1;}else if(c<=2047){$unused((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((192|(((b>>6>>0)<<24>>>24)))>>>0));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=((128|((((b<<24>>>24))&63)>>>0))>>>0));return 2;}else if((c>1114111)||(55296<=c&&c<=57343)){b=65533;$unused((2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((224|(((b>>12>>0)<<24>>>24)))>>>0));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=((128|(((((b>>6>>0)<<24>>>24))&63)>>>0))>>>0));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=((128|((((b<<24>>>24))&63)>>>0))>>>0));return 3;}else if(c<=65535){$unused((2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((224|(((b>>12>>0)<<24>>>24)))>>>0));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=((128|(((((b>>6>>0)<<24>>>24))&63)>>>0))>>>0));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=((128|((((b<<24>>>24))&63)>>>0))>>>0));return 3;}else{$unused((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((240|(((b>>18>>0)<<24>>>24)))>>>0));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=((128|(((((b>>12>>0)<<24>>>24))&63)>>>0))>>>0));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=((128|(((((b>>6>>0)<<24>>>24))&63)>>>0))>>>0));(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]=((128|((((b<<24>>>24))&63)>>>0))>>>0));return 4;}};$pkg.EncodeRune=K;L=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=a.$length;c=0;d=0;while(true){if(!(d<b)){break;}c=c+(1)>>0;e=((d<0||d>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+d]);if(e<128){d=d+(1)>>0;continue;}f=((e<0||e>=A.length)?($throwRuntimeError(\"index out of range\"),undefined):A[e]);if(f===241){d=d+(1)>>0;continue;}g=((((f&7)>>>0)>>0));if((d+g>>0)>b){d=d+(1)>>0;continue;}i=$clone((h=f>>>4<<24>>>24,((h<0||h>=C.length)?($throwRuntimeError(\"index out of range\"),undefined):C[h])),B);k=(j=d+1>>0,((j<0||j>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+j]));if(k<i.lo||i.hi<k){g=1;}else if(g===2){}else{m=(l=d+2>>0,((l<0||l>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+l]));if(m<128||191<m){g=1;}else if(g===3){}else{o=(n=d+3>>0,((n<0||n>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+n]));if(o<128||191<o){g=1;}}}d=d+(g)>>0;}return c;};$pkg.RuneCount=L;M=function(a){var a,b,c,d,e,f,g,h,i,j,k,l;b=0;c=a.length;d=0;while(true){if(!(d<c)){break;}e=a.charCodeAt(d);if(e<128){d=d+(1)>>0;b=b+(1)>>0;continue;}f=((e<0||e>=A.length)?($throwRuntimeError(\"index out of range\"),undefined):A[e]);if(f===241){d=d+(1)>>0;b=b+(1)>>0;continue;}g=((((f&7)>>>0)>>0));if((d+g>>0)>c){d=d+(1)>>0;b=b+(1)>>0;continue;}i=$clone((h=f>>>4<<24>>>24,((h<0||h>=C.length)?($throwRuntimeError(\"index out of range\"),undefined):C[h])),B);j=a.charCodeAt((d+1>>0));if(j<i.lo||i.hi<j){g=1;}else if(g===2){}else{k=a.charCodeAt((d+2>>0));if(k<128||191<k){g=1;}else if(g===3){}else{l=a.charCodeAt((d+3>>0));if(l<128||191<l){g=1;}}}d=d+(g)>>0;b=b+(1)>>0;}b=b;return b;};$pkg.RuneCountInString=M;N=function(a){var a;return!((((a&192)>>>0)===128));};$pkg.RuneStart=N;P=function(a){var a,b,c,d,e,f,g,h,i,j,k;b=a.length;c=0;while(true){if(!(c<b)){break;}d=a.charCodeAt(c);if(d<128){c=c+(1)>>0;continue;}e=((d<0||d>=A.length)?($throwRuntimeError(\"index out of range\"),undefined):A[d]);if(e===241){return false;}f=((((e&7)>>>0)>>0));if((c+f>>0)>b){return false;}h=$clone((g=e>>>4<<24>>>24,((g<0||g>=C.length)?($throwRuntimeError(\"index out of range\"),undefined):C[g])),B);i=a.charCodeAt((c+1>>0));if(i<h.lo||h.hi<i){return false;}else if(f===2){}else{j=a.charCodeAt((c+2>>0));if(j<128||191<j){return false;}else if(f===3){}else{k=a.charCodeAt((c+3>>0));if(k<128||191<k){return false;}}}c=c+(f)>>0;}return true;};$pkg.ValidString=P;Q=function(a){var a;if(0<=a&&a<55296){return true;}else if(57343<a&&a<=1114111){return true;}return false;};$pkg.ValidRune=Q;B.init(\"unicode/utf8\",[{prop:\"lo\",name:\"lo\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"hi\",name:\"hi\",embedded:false,exported:false,typ:$Uint8,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:A=$toNativeArray($kindUint8,[240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,19,3,3,3,3,3,3,3,3,3,3,3,3,35,3,3,52,4,4,4,68,241,241,241,241,241,241,241,241,241,241,241]);C=$toNativeArray($kindStruct,[new B.ptr(128,191),new B.ptr(160,191),new B.ptr(128,159),new B.ptr(144,191),new B.ptr(128,143)]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"strconv\"]=(function(){var $pkg={},$init,B,D,A,C,E,U,AC,AG,AL,AS,BB,DA,DB,DC,DD,DE,DF,DG,DH,DI,DJ,DK,DL,DM,DN,I,AH,AM,AN,AO,AT,CV,AU,CW,BH,BI,BJ,BK,BL,V,W,X,Y,Z,AA,AB,AD,AE,AF,AI,AJ,AK,AP,AQ,AR,AW,AX,AY,AZ,BA,BC,BD,BE,BF,BG,BM,BN,BO,BR,BS,BT,BU,BW,BX,BY,BZ,CA,CB,CC,CG,CI,CL,CM,CN,CO,CP,CQ,CR,CS,CU;B=$packages[\"errors\"];D=$packages[\"internal/bytealg\"];A=$packages[\"math\"];C=$packages[\"math/bits\"];E=$packages[\"unicode/utf8\"];U=$pkg.NumError=$newType(0,$kindStruct,\"strconv.NumError\",true,\"strconv\",true,function(Func_,Num_,Err_){this.$val=this;if(arguments.length===0){this.Func=\"\";this.Num=\"\";this.Err=$ifaceNil;return;}this.Func=Func_;this.Num=Num_;this.Err=Err_;});AC=$pkg.decimal=$newType(0,$kindStruct,\"strconv.decimal\",true,\"strconv\",false,function(d_,nd_,dp_,neg_,trunc_){this.$val=this;if(arguments.length===0){this.d=DD.zero();this.nd=0;this.dp=0;this.neg=false;this.trunc=false;return;}this.d=d_;this.nd=nd_;this.dp=dp_;this.neg=neg_;this.trunc=trunc_;});AG=$pkg.leftCheat=$newType(0,$kindStruct,\"strconv.leftCheat\",true,\"strconv\",false,function(delta_,cutoff_){this.$val=this;if(arguments.length===0){this.delta=0;this.cutoff=\"\";return;}this.delta=delta_;this.cutoff=cutoff_;});AL=$pkg.extFloat=$newType(0,$kindStruct,\"strconv.extFloat\",true,\"strconv\",false,function(mant_,exp_,neg_){this.$val=this;if(arguments.length===0){this.mant=new $Uint64(0,0);this.exp=0;this.neg=false;return;}this.mant=mant_;this.exp=exp_;this.neg=neg_;});AS=$pkg.floatInfo=$newType(0,$kindStruct,\"strconv.floatInfo\",true,\"strconv\",false,function(mantbits_,expbits_,bias_){this.$val=this;if(arguments.length===0){this.mantbits=0;this.expbits=0;this.bias=0;return;}this.mantbits=mantbits_;this.expbits=expbits_;this.bias=bias_;});BB=$pkg.decimalSlice=$newType(0,$kindStruct,\"strconv.decimalSlice\",true,\"strconv\",false,function(d_,nd_,dp_,neg_){this.$val=this;if(arguments.length===0){this.d=DE.nil;this.nd=0;this.dp=0;this.neg=false;return;}this.d=d_;this.nd=nd_;this.dp=dp_;this.neg=neg_;});DA=$sliceType(AG);DB=$sliceType($Uint16);DC=$sliceType($Uint32);DD=$arrayType($Uint8,800);DE=$sliceType($Uint8);DF=$ptrType(U);DG=$arrayType($Uint8,24);DH=$arrayType($Uint8,32);DI=$ptrType(AS);DJ=$arrayType($Uint8,65);DK=$arrayType($Uint8,4);DL=$ptrType(AC);DM=$ptrType(BB);DN=$ptrType(AL);U.ptr.prototype.Error=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.Err.Error();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return\"strconv.\"+a.Func+\": \"+\"parsing \"+BZ(a.Num)+\": \"+b;}return;}if($f===undefined){$f={$blk:U.ptr.prototype.Error};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};U.prototype.Error=function(){return this.$val.Error();};V=function(a,b){var a,b;return new U.ptr(a,b,$pkg.ErrSyntax);};W=function(a,b){var a,b;return new U.ptr(a,b,$pkg.ErrRange);};X=function(a,b,c){var a,b,c;return new U.ptr(a,b,B.New(\"invalid base \"+BO(c)));};Y=function(a,b,c){var a,b,c;return new U.ptr(a,b,B.New(\"invalid bit size \"+BO(c)));};Z=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;if(a.length===0){return[new $Uint64(0,0),V(\"ParseUint\",a)];}d=a;if(2<=b&&b<=36){}else if((b===0)){if((a.charCodeAt(0)===48)&&a.length>1&&((a.charCodeAt(1)===120)||(a.charCodeAt(1)===88))){if(a.length<3){return[new $Uint64(0,0),V(\"ParseUint\",d)];}b=16;a=$substring(a,2);}else if((a.charCodeAt(0)===48)){b=8;a=$substring(a,1);}else{b=10;}}else{return[new $Uint64(0,0),X(\"ParseUint\",d,b)];}if(c===0){c=32;}else if(c<0||c>64){return[new $Uint64(0,0),Y(\"ParseUint\",d,c)];}e=new $Uint64(0,0);f=b;if(f===(10)){e=new $Uint64(429496729,2576980378);}else if(f===(16)){e=new $Uint64(268435456,0);}else{e=(g=$div64(new $Uint64(4294967295,4294967295),(new $Uint64(0,b)),false),new $Uint64(g.$high+0,g.$low+1));}i=(h=$shiftLeft64(new $Uint64(0,1),((c>>>0))),new $Uint64(h.$high-0,h.$low-1));j=new $Uint64(0,0);k=(new DE($stringToBytes(a)));l=0;while(true){if(!(l<k.$length)){break;}m=((l<0||l>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+l]);n=0;if(48<=m&&m<=57){n=m-48<<24>>>24;}else if(97<=m&&m<=122){n=(m-97<<24>>>24)+10<<24>>>24;}else if(65<=m&&m<=90){n=(m-65<<24>>>24)+10<<24>>>24;}else{return[new $Uint64(0,0),V(\"ParseUint\",d)];}if(n>=((b<<24>>>24))){return[new $Uint64(0,0),V(\"ParseUint\",d)];}if((j.$high>e.$high||(j.$high===e.$high&&j.$low>=e.$low))){return[i,W(\"ParseUint\",d)];}j=$mul64(j,((new $Uint64(0,b))));p=(o=(new $Uint64(0,n)),new $Uint64(j.$high+o.$high,j.$low+o.$low));if((p.$high<j.$high||(p.$high===j.$high&&p.$low<j.$low))||(p.$high>i.$high||(p.$high===i.$high&&p.$low>i.$low))){return[i,W(\"ParseUint\",d)];}j=p;l++;}return[j,$ifaceNil];};$pkg.ParseUint=Z;AA=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;d=new $Int64(0,0);e=$ifaceNil;if(a.length===0){f=new $Int64(0,0);g=V(\"ParseInt\",a);d=f;e=g;return[d,e];}h=a;i=false;if(a.charCodeAt(0)===43){a=$substring(a,1);}else if(a.charCodeAt(0)===45){i=true;a=$substring(a,1);}j=new $Uint64(0,0);k=Z(a,b,c);j=k[0];e=k[1];if(!($interfaceIsEqual(e,$ifaceNil))&&!($interfaceIsEqual($assertType(e,DF).Err,$pkg.ErrRange))){$assertType(e,DF).Func=\"ParseInt\";$assertType(e,DF).Num=h;l=new $Int64(0,0);m=e;d=l;e=m;return[d,e];}if(c===0){c=32;}n=($shiftLeft64(new $Uint64(0,1),(((c-1>>0)>>>0))));if(!i&&(j.$high>n.$high||(j.$high===n.$high&&j.$low>=n.$low))){o=((p=new $Uint64(n.$high-0,n.$low-1),new $Int64(p.$high,p.$low)));q=W(\"ParseInt\",h);d=o;e=q;return[d,e];}if(i&&(j.$high>n.$high||(j.$high===n.$high&&j.$low>n.$low))){r=(s=(new $Int64(n.$high,n.$low)),new $Int64(-s.$high,-s.$low));t=W(\"ParseInt\",h);d=r;e=t;return[d,e];}u=(new $Int64(j.$high,j.$low));if(i){u=new $Int64(-u.$high,-u.$low);}v=u;w=$ifaceNil;d=v;e=w;return[d,e];};$pkg.ParseInt=AA;AB=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m;b=a.length;if(true&&(0<b&&b<10)||false&&(0<b&&b<19)){c=a;if((a.charCodeAt(0)===45)||(a.charCodeAt(0)===43)){a=$substring(a,1);if(a.length<1){return[0,new U.ptr(\"Atoi\",c,$pkg.ErrSyntax)];}}d=0;e=(new DE($stringToBytes(a)));f=0;while(true){if(!(f<e.$length)){break;}g=((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]);g=g-(48)<<24>>>24;if(g>9){return[0,new U.ptr(\"Atoi\",c,$pkg.ErrSyntax)];}d=($imul(d,10))+((g>>0))>>0;f++;}if(c.charCodeAt(0)===45){d=-d;}return[d,$ifaceNil];}h=AA(a,10,0);i=h[0];j=h[1];k=$assertType(j,DF,true);l=k[0];m=k[1];if(m){l.Func=\"Atoi\";}return[(((i.$low+((i.$high>>31)*4294967296))>>0)),j];};$pkg.Atoi=AB;AC.ptr.prototype.String=function(){var a,b,c,d;a=this;b=10+a.nd>>0;if(a.dp>0){b=b+(a.dp)>>0;}if(a.dp<0){b=b+(-a.dp)>>0;}c=$makeSlice(DE,b);d=0;if((a.nd===0)){return\"0\";}else if(a.dp<=0){((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=48);d=d+(1)>>0;((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=46);d=d+(1)>>0;d=d+(AD($subslice(c,d,(d+-a.dp>>0))))>>0;d=d+($copySlice($subslice(c,d),$subslice(new DE(a.d),0,a.nd)))>>0;}else if(a.dp<a.nd){d=d+($copySlice($subslice(c,d),$subslice(new DE(a.d),0,a.dp)))>>0;((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=46);d=d+(1)>>0;d=d+($copySlice($subslice(c,d),$subslice(new DE(a.d),a.dp,a.nd)))>>0;}else{d=d+($copySlice($subslice(c,d),$subslice(new DE(a.d),0,a.nd)))>>0;d=d+(AD($subslice(c,d,((d+a.dp>>0)-a.nd>>0))))>>0;}return($bytesToString($subslice(c,0,d)));};AC.prototype.String=function(){return this.$val.String();};AD=function(a){var a,b,c,d;b=a;c=0;while(true){if(!(c<b.$length)){break;}d=c;((d<0||d>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+d]=48);c++;}return a.$length;};AE=function(a){var a,b,c;while(true){if(!(a.nd>0&&((b=a.d,c=a.nd-1>>0,((c<0||c>=b.length)?($throwRuntimeError(\"index out of range\"),undefined):b[c]))===48))){break;}a.nd=a.nd-(1)>>0;}if(a.nd===0){a.dp=0;}};AC.ptr.prototype.Assign=function(a){var a,b,c,d,e,f,g,h;b=this;c=DG.zero();d=0;while(true){if(!((a.$high>0||(a.$high===0&&a.$low>0)))){break;}e=$div64(a,new $Uint64(0,10),false);a=(f=$mul64(new $Uint64(0,10),e),new $Uint64(a.$high-f.$high,a.$low-f.$low));((d<0||d>=c.length)?($throwRuntimeError(\"index out of range\"),undefined):c[d]=((new $Uint64(a.$high+0,a.$low+48).$low<<24>>>24)));d=d+(1)>>0;a=e;}b.nd=0;d=d-(1)>>0;while(true){if(!(d>=0)){break;}(g=b.d,h=b.nd,((h<0||h>=g.length)?($throwRuntimeError(\"index out of range\"),undefined):g[h]=((d<0||d>=c.length)?($throwRuntimeError(\"index out of range\"),undefined):c[d])));b.nd=b.nd+(1)>>0;d=d-(1)>>0;}b.dp=b.nd;AE(b);};AC.prototype.Assign=function(a){return this.$val.Assign(a);};AF=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;c=0;d=0;e=0;while(true){if(!(((f=b,f<32?(e>>>f):0)>>>0)===0)){break;}if(c>=a.nd){if(e===0){a.nd=0;return;}while(true){if(!(((g=b,g<32?(e>>>g):0)>>>0)===0)){break;}e=e*10>>>0;c=c+(1)>>0;}break;}i=(((h=a.d,((c<0||c>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[c]))>>>0));e=((e*10>>>0)+i>>>0)-48>>>0;c=c+(1)>>0;}a.dp=a.dp-((c-1>>0))>>0;k=(((j=b,j<32?(1<<j):0)>>>0))-1>>>0;while(true){if(!(c<a.nd)){break;}m=(((l=a.d,((c<0||c>=l.length)?($throwRuntimeError(\"index out of range\"),undefined):l[c]))>>>0));o=(n=b,n<32?(e>>>n):0)>>>0;e=(e&(k))>>>0;(p=a.d,((d<0||d>=p.length)?($throwRuntimeError(\"index out of range\"),undefined):p[d]=(((o+48>>>0)<<24>>>24))));d=d+(1)>>0;e=((e*10>>>0)+m>>>0)-48>>>0;c=c+(1)>>0;}while(true){if(!(e>0)){break;}r=(q=b,q<32?(e>>>q):0)>>>0;e=(e&(k))>>>0;if(d<800){(s=a.d,((d<0||d>=s.length)?($throwRuntimeError(\"index out of range\"),undefined):s[d]=(((r+48>>>0)<<24>>>24))));d=d+(1)>>0;}else if(r>0){a.trunc=true;}e=e*10>>>0;}a.nd=d;AE(a);};AI=function(a,b){var a,b,c;c=0;while(true){if(!(c<b.length)){break;}if(c>=a.$length){return true;}if(!((((c<0||c>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+c])===b.charCodeAt(c)))){return((c<0||c>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+c])<b.charCodeAt(c);}c=c+(1)>>0;}return false;};AJ=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;c=((b<0||b>=AH.$length)?($throwRuntimeError(\"index out of range\"),undefined):AH.$array[AH.$offset+b]).delta;if(AI($subslice(new DE(a.d),0,a.nd),((b<0||b>=AH.$length)?($throwRuntimeError(\"index out of range\"),undefined):AH.$array[AH.$offset+b]).cutoff)){c=c-(1)>>0;}d=a.nd;e=a.nd+c>>0;f=0;d=d-(1)>>0;while(true){if(!(d>=0)){break;}f=f+(((g=b,g<32?((((((h=a.d,((d<0||d>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[d]))>>>0))-48>>>0))<<g):0)>>>0))>>>0;j=(i=f/10,(i===i&&i!==1/0&&i!==-1/0)?i>>>0:$throwRuntimeError(\"integer divide by zero\"));k=f-(10*j>>>0)>>>0;e=e-(1)>>0;if(e<800){(l=a.d,((e<0||e>=l.length)?($throwRuntimeError(\"index out of range\"),undefined):l[e]=(((k+48>>>0)<<24>>>24))));}else if(!((k===0))){a.trunc=true;}f=j;d=d-(1)>>0;}while(true){if(!(f>0)){break;}n=(m=f/10,(m===m&&m!==1/0&&m!==-1/0)?m>>>0:$throwRuntimeError(\"integer divide by zero\"));o=f-(10*n>>>0)>>>0;e=e-(1)>>0;if(e<800){(p=a.d,((e<0||e>=p.length)?($throwRuntimeError(\"index out of range\"),undefined):p[e]=(((o+48>>>0)<<24>>>24))));}else if(!((o===0))){a.trunc=true;}f=n;}a.nd=a.nd+(c)>>0;if(a.nd>=800){a.nd=800;}a.dp=a.dp+(c)>>0;AE(a);};AC.ptr.prototype.Shift=function(a){var a,b;b=this;if((b.nd===0)){}else if(a>0){while(true){if(!(a>28)){break;}AJ(b,28);a=a-(28)>>0;}AJ(b,((a>>>0)));}else if(a<0){while(true){if(!(a<-28)){break;}AF(b,28);a=a+(28)>>0;}AF(b,((-a>>>0)));}};AC.prototype.Shift=function(a){return this.$val.Shift(a);};AK=function(a,b){var a,b,c,d,e,f,g;if(b<0||b>=a.nd){return false;}if(((c=a.d,((b<0||b>=c.length)?($throwRuntimeError(\"index out of range\"),undefined):c[b]))===53)&&((b+1>>0)===a.nd)){if(a.trunc){return true;}return b>0&&!(((d=(((e=a.d,f=b-1>>0,((f<0||f>=e.length)?($throwRuntimeError(\"index out of range\"),undefined):e[f]))-48<<24>>>24))%2,d===d?d:$throwRuntimeError(\"integer divide by zero\"))===0));}return(g=a.d,((b<0||b>=g.length)?($throwRuntimeError(\"index out of range\"),undefined):g[b]))>=53;};AC.ptr.prototype.Round=function(a){var a,b;b=this;if(a<0||a>=b.nd){return;}if(AK(b,a)){b.RoundUp(a);}else{b.RoundDown(a);}};AC.prototype.Round=function(a){return this.$val.Round(a);};AC.ptr.prototype.RoundDown=function(a){var a,b;b=this;if(a<0||a>=b.nd){return;}b.nd=a;AE(b);};AC.prototype.RoundDown=function(a){return this.$val.RoundDown(a);};AC.ptr.prototype.RoundUp=function(a){var a,b,c,d,e,f,g;b=this;if(a<0||a>=b.nd){return;}c=a-1>>0;while(true){if(!(c>=0)){break;}e=(d=b.d,((c<0||c>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[c]));if(e<57){(g=b.d,((c<0||c>=g.length)?($throwRuntimeError(\"index out of range\"),undefined):g[c]=((f=b.d,((c<0||c>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[c]))+(1)<<24>>>24)));b.nd=c+1>>0;return;}c=c-(1)>>0;}b.d[0]=49;b.nd=1;b.dp=b.dp+(1)>>0;};AC.prototype.RoundUp=function(a){return this.$val.RoundUp(a);};AC.ptr.prototype.RoundedInteger=function(){var a,b,c,d,e,f,g;a=this;if(a.dp>20){return new $Uint64(4294967295,4294967295);}b=0;c=new $Uint64(0,0);b=0;while(true){if(!(b<a.dp&&b<a.nd)){break;}c=(d=$mul64(c,new $Uint64(0,10)),e=(new $Uint64(0,((f=a.d,((b<0||b>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[b]))-48<<24>>>24))),new $Uint64(d.$high+e.$high,d.$low+e.$low));b=b+(1)>>0;}while(true){if(!(b<a.dp)){break;}c=$mul64(c,(new $Uint64(0,10)));b=b+(1)>>0;}if(AK(a,a.dp)){c=(g=new $Uint64(0,1),new $Uint64(c.$high+g.$high,c.$low+g.$low));}return c;};AC.prototype.RoundedInteger=function(){return this.$val.RoundedInteger();};AL.ptr.prototype.AssignComputeBounds=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;e=new AL.ptr(new $Uint64(0,0),0,false);f=new AL.ptr(new $Uint64(0,0),0,false);g=this;g.mant=a;g.exp=b-((d.mantbits>>0))>>0;g.neg=c;if(g.exp<=0&&(h=$shiftLeft64(($shiftRightUint64(a,((-g.exp>>>0)))),((-g.exp>>>0))),(a.$high===h.$high&&a.$low===h.$low))){g.mant=$shiftRightUint64(g.mant,(((-g.exp>>>0))));g.exp=0;i=$clone(g,AL);j=$clone(g,AL);AL.copy(e,i);AL.copy(f,j);return[e,f];}k=b-d.bias>>0;AL.copy(f,new AL.ptr((l=$mul64(new $Uint64(0,2),g.mant),new $Uint64(l.$high+0,l.$low+1)),g.exp-1>>0,g.neg));if(!((m=$shiftLeft64(new $Uint64(0,1),d.mantbits),(a.$high===m.$high&&a.$low===m.$low)))||(k===1)){AL.copy(e,new AL.ptr((n=$mul64(new $Uint64(0,2),g.mant),new $Uint64(n.$high-0,n.$low-1)),g.exp-1>>0,g.neg));}else{AL.copy(e,new AL.ptr((o=$mul64(new $Uint64(0,4),g.mant),new $Uint64(o.$high-0,o.$low-1)),g.exp-2>>0,g.neg));}return[e,f];};AL.prototype.AssignComputeBounds=function(a,b,c,d){return this.$val.AssignComputeBounds(a,b,c,d);};AL.ptr.prototype.Normalize=function(){var a,b,c;a=this;if((b=a.mant,(b.$high===0&&b.$low===0))){return 0;}c=C.LeadingZeros64(a.mant);a.mant=$shiftLeft64(a.mant,(((c>>>0))));a.exp=a.exp-(c)>>0;return((c>>>0));};AL.prototype.Normalize=function(){return this.$val.Normalize();};AL.ptr.prototype.Multiply=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;b=this;c=$shiftRightUint64(b.mant,32);d=(new $Uint64(0,((b.mant.$low>>>0))));e=c;f=d;g=$shiftRightUint64(a.mant,32);h=(new $Uint64(0,((a.mant.$low>>>0))));i=g;j=h;k=$mul64(e,j);l=$mul64(f,i);b.mant=(m=(n=$mul64(e,i),o=$shiftRightUint64(k,32),new $Uint64(n.$high+o.$high,n.$low+o.$low)),p=$shiftRightUint64(l,32),new $Uint64(m.$high+p.$high,m.$low+p.$low));u=(q=(r=(new $Uint64(0,((k.$low>>>0)))),s=(new $Uint64(0,((l.$low>>>0)))),new $Uint64(r.$high+s.$high,r.$low+s.$low)),t=$shiftRightUint64(($mul64(f,j)),32),new $Uint64(q.$high+t.$high,q.$low+t.$low));u=(v=new $Uint64(0,2147483648),new $Uint64(u.$high+v.$high,u.$low+v.$low));b.mant=(w=b.mant,x=($shiftRightUint64(u,32)),new $Uint64(w.$high+x.$high,w.$low+x.$low));b.exp=(b.exp+a.exp>>0)+64>>0;};AL.prototype.Multiply=function(a){return this.$val.Multiply(a);};AL.ptr.prototype.AssignDecimal=function(a,b,c,d,e){var a,aa,ab,ac,ad,ae,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;f=false;g=this;h=0;if(d){h=h+(4)>>0;}g.mant=a;g.exp=0;g.neg=c;j=(i=((b- -348>>0))/8,(i===i&&i!==1/0&&i!==-1/0)?i>>0:$throwRuntimeError(\"integer divide by zero\"));if(b<-348||j>=87){f=false;return f;}l=(k=((b- -348>>0))%8,k===k?k:$throwRuntimeError(\"integer divide by zero\"));if(l<19&&(m=(n=19-l>>0,((n<0||n>=AO.length)?($throwRuntimeError(\"index out of range\"),undefined):AO[n])),(a.$high<m.$high||(a.$high===m.$high&&a.$low<m.$low)))){g.mant=$mul64(g.mant,(((l<0||l>=AO.length)?($throwRuntimeError(\"index out of range\"),undefined):AO[l])));g.Normalize();}else{g.Normalize();g.Multiply($clone(((l<0||l>=AM.length)?($throwRuntimeError(\"index out of range\"),undefined):AM[l]),AL));h=h+(4)>>0;}g.Multiply($clone(((j<0||j>=AN.length)?($throwRuntimeError(\"index out of range\"),undefined):AN[j]),AL));if(h>0){h=h+(1)>>0;}h=h+(4)>>0;o=g.Normalize();h=(p=(o),p<32?(h<<p):0)>>0;q=e.bias-63>>0;r=0;if(g.exp<=q){r=((63-e.mantbits>>>0)+1>>>0)+(((q-g.exp>>0)>>>0))>>>0;}else{r=63-e.mantbits>>>0;}s=$shiftLeft64(new $Uint64(0,1),((r-1>>>0)));w=(t=g.mant,u=(v=$shiftLeft64(new $Uint64(0,1),r),new $Uint64(v.$high-0,v.$low-1)),new $Uint64(t.$high&u.$high,(t.$low&u.$low)>>>0));if((x=(y=(new $Int64(s.$high,s.$low)),z=(new $Int64(0,h)),new $Int64(y.$high-z.$high,y.$low-z.$low)),aa=(new $Int64(w.$high,w.$low)),(x.$high<aa.$high||(x.$high===aa.$high&&x.$low<aa.$low)))&&(ab=(new $Int64(w.$high,w.$low)),ac=(ad=(new $Int64(s.$high,s.$low)),ae=(new $Int64(0,h)),new $Int64(ad.$high+ae.$high,ad.$low+ae.$low)),(ab.$high<ac.$high||(ab.$high===ac.$high&&ab.$low<ac.$low)))){f=false;return f;}f=true;return f;};AL.prototype.AssignDecimal=function(a,b,c,d,e){return this.$val.AssignDecimal(a,b,c,d,e);};AL.ptr.prototype.frexp10=function(){var a,b,c,d,e,f,g,h,i,j;a=0;b=0;c=this;e=(d=($imul(((-46-c.exp>>0)),28))/93,(d===d&&d!==1/0&&d!==-1/0)?d>>0:$throwRuntimeError(\"integer divide by zero\"));g=(f=((e- -348>>0))/8,(f===f&&f!==1/0&&f!==-1/0)?f>>0:$throwRuntimeError(\"integer divide by zero\"));Loop:while(true){h=(c.exp+((g<0||g>=AN.length)?($throwRuntimeError(\"index out of range\"),undefined):AN[g]).exp>>0)+64>>0;if(h<-60){g=g+(1)>>0;}else if(h>-32){g=g-(1)>>0;}else{break Loop;}}c.Multiply($clone(((g<0||g>=AN.length)?($throwRuntimeError(\"index out of range\"),undefined):AN[g]),AL));i=-((-348+($imul(g,8))>>0));j=g;a=i;b=j;return[a,b];};AL.prototype.frexp10=function(){return this.$val.frexp10();};AP=function(a,b,c){var a,b,c,d,e,f;d=0;e=c.frexp10();d=e[0];f=e[1];a.Multiply($clone(((f<0||f>=AN.length)?($throwRuntimeError(\"index out of range\"),undefined):AN[f]),AL));b.Multiply($clone(((f<0||f>=AN.length)?($throwRuntimeError(\"index out of range\"),undefined):AN[f]),AL));return d;};AL.ptr.prototype.FixedDecimal=function(a,b){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;c=this;if((d=c.mant,(d.$high===0&&d.$low===0))){a.nd=0;a.dp=0;a.neg=c.neg;return true;}if(b===0){$panic(new $String(\"strconv: internal error: extFloat.FixedDecimal called with n == 0\"));}c.Normalize();e=c.frexp10();f=e[0];g=((-c.exp>>>0));h=(($shiftRightUint64(c.mant,g).$low>>>0));k=(i=c.mant,j=$shiftLeft64((new $Uint64(0,h)),g),new $Uint64(i.$high-j.$high,i.$low-j.$low));l=new $Uint64(0,1);m=b;n=0;o=new $Uint64(0,1);p=0;q=new $Uint64(0,1);r=p;s=q;while(true){if(!(r<20)){break;}if((t=(new $Uint64(0,h)),(s.$high>t.$high||(s.$high===t.$high&&s.$low>t.$low)))){n=r;break;}s=$mul64(s,(new $Uint64(0,10)));r=r+(1)>>0;}u=h;if(n>m){o=(v=n-m>>0,((v<0||v>=AO.length)?($throwRuntimeError(\"index out of range\"),undefined):AO[v]));h=(w=h/(((o.$low>>>0))),(w===w&&w!==1/0&&w!==-1/0)?w>>>0:$throwRuntimeError(\"integer divide by zero\"));u=u-(($imul(h,((o.$low>>>0)))>>>0))>>>0;}else{u=0;}x=DH.zero();y=32;z=h;while(true){if(!(z>0)){break;}ab=(aa=z/10,(aa===aa&&aa!==1/0&&aa!==-1/0)?aa>>>0:$throwRuntimeError(\"integer divide by zero\"));z=z-(($imul(10,ab)>>>0))>>>0;y=y-(1)>>0;((y<0||y>=x.length)?($throwRuntimeError(\"index out of range\"),undefined):x[y]=(((z+48>>>0)<<24>>>24)));z=ab;}ac=y;while(true){if(!(ac<32)){break;}(ad=a.d,ae=ac-y>>0,((ae<0||ae>=ad.$length)?($throwRuntimeError(\"index out of range\"),undefined):ad.$array[ad.$offset+ae]=((ac<0||ac>=x.length)?($throwRuntimeError(\"index out of range\"),undefined):x[ac])));ac=ac+(1)>>0;}af=32-y>>0;a.nd=af;a.dp=n+f>>0;m=m-(af)>>0;if(m>0){if(!((u===0))||!((o.$high===0&&o.$low===1))){$panic(new $String(\"strconv: internal error, rest != 0 but needed > 0\"));}while(true){if(!(m>0)){break;}k=$mul64(k,(new $Uint64(0,10)));l=$mul64(l,(new $Uint64(0,10)));if((ag=$mul64(new $Uint64(0,2),l),ah=$shiftLeft64(new $Uint64(0,1),g),(ag.$high>ah.$high||(ag.$high===ah.$high&&ag.$low>ah.$low)))){return false;}ai=$shiftRightUint64(k,g);(aj=a.d,((af<0||af>=aj.$length)?($throwRuntimeError(\"index out of range\"),undefined):aj.$array[aj.$offset+af]=((new $Uint64(ai.$high+0,ai.$low+48).$low<<24>>>24))));k=(ak=$shiftLeft64(ai,g),new $Uint64(k.$high-ak.$high,k.$low-ak.$low));af=af+(1)>>0;m=m-(1)>>0;}a.nd=af;}am=AQ(a,(al=$shiftLeft64((new $Uint64(0,u)),g),new $Uint64(al.$high|k.$high,(al.$low|k.$low)>>>0)),o,g,l);if(!am){return false;}an=a.nd-1>>0;while(true){if(!(an>=0)){break;}if(!(((ao=a.d,((an<0||an>=ao.$length)?($throwRuntimeError(\"index out of range\"),undefined):ao.$array[ao.$offset+an]))===48))){a.nd=an+1>>0;break;}an=an-(1)>>0;}return true;};AL.prototype.FixedDecimal=function(a,b){return this.$val.FixedDecimal(a,b);};AQ=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;if((f=$shiftLeft64(c,d),(b.$high>f.$high||(b.$high===f.$high&&b.$low>f.$low)))){$panic(new $String(\"strconv: num > den<<shift in adjustLastDigitFixed\"));}if((g=$mul64(new $Uint64(0,2),e),h=$shiftLeft64(c,d),(g.$high>h.$high||(g.$high===h.$high&&g.$low>h.$low)))){$panic(new $String(\"strconv: \\xCE\\xB5 > (den<<shift)/2\"));}if((i=$mul64(new $Uint64(0,2),(new $Uint64(b.$high+e.$high,b.$low+e.$low))),j=$shiftLeft64(c,d),(i.$high<j.$high||(i.$high===j.$high&&i.$low<j.$low)))){return true;}if((k=$mul64(new $Uint64(0,2),(new $Uint64(b.$high-e.$high,b.$low-e.$low))),l=$shiftLeft64(c,d),(k.$high>l.$high||(k.$high===l.$high&&k.$low>l.$low)))){m=a.nd-1>>0;while(true){if(!(m>=0)){break;}if((n=a.d,((m<0||m>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+m]))===57){a.nd=a.nd-(1)>>0;}else{break;}m=m-(1)>>0;}if(m<0){(o=a.d,(0>=o.$length?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+0]=49));a.nd=1;a.dp=a.dp+(1)>>0;}else{(q=a.d,((m<0||m>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+m]=((p=a.d,((m<0||m>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+m]))+(1)<<24>>>24)));}return true;}return false;};AL.ptr.prototype.ShortestDecimal=function(a,b,c){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;d=this;if((e=d.mant,(e.$high===0&&e.$low===0))){a.nd=0;a.dp=0;a.neg=d.neg;return true;}if((d.exp===0)&&$equal(b,d,AL)&&$equal(b,c,AL)){f=DG.zero();g=23;h=d.mant;while(true){if(!((h.$high>0||(h.$high===0&&h.$low>0)))){break;}i=$div64(h,new $Uint64(0,10),false);h=(j=$mul64(new $Uint64(0,10),i),new $Uint64(h.$high-j.$high,h.$low-j.$low));((g<0||g>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[g]=((new $Uint64(h.$high+0,h.$low+48).$low<<24>>>24)));g=g-(1)>>0;h=i;}k=(24-g>>0)-1>>0;l=0;while(true){if(!(l<k)){break;}(n=a.d,((l<0||l>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+l]=(m=(g+1>>0)+l>>0,((m<0||m>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[m]))));l=l+(1)>>0;}o=k;p=k;a.nd=o;a.dp=p;while(true){if(!(a.nd>0&&((q=a.d,r=a.nd-1>>0,((r<0||r>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+r]))===48))){break;}a.nd=a.nd-(1)>>0;}if(a.nd===0){a.dp=0;}a.neg=d.neg;return true;}c.Normalize();if(d.exp>c.exp){d.mant=$shiftLeft64(d.mant,((((d.exp-c.exp>>0)>>>0))));d.exp=c.exp;}if(b.exp>c.exp){b.mant=$shiftLeft64(b.mant,((((b.exp-c.exp>>0)>>>0))));b.exp=c.exp;}s=AP(b,d,c);c.mant=(t=c.mant,u=new $Uint64(0,1),new $Uint64(t.$high+u.$high,t.$low+u.$low));b.mant=(v=b.mant,w=new $Uint64(0,1),new $Uint64(v.$high-w.$high,v.$low-w.$low));x=((-c.exp>>>0));y=(($shiftRightUint64(c.mant,x).$low>>>0));ab=(z=c.mant,aa=$shiftLeft64((new $Uint64(0,y)),x),new $Uint64(z.$high-aa.$high,z.$low-aa.$low));ae=(ac=c.mant,ad=b.mant,new $Uint64(ac.$high-ad.$high,ac.$low-ad.$low));ah=(af=c.mant,ag=d.mant,new $Uint64(af.$high-ag.$high,af.$low-ag.$low));ai=0;aj=0;ak=new $Uint64(0,1);al=aj;am=ak;while(true){if(!(al<20)){break;}if((an=(new $Uint64(0,y)),(am.$high>an.$high||(am.$high===an.$high&&am.$low>an.$low)))){ai=al;break;}am=$mul64(am,(new $Uint64(0,10)));al=al+(1)>>0;}ao=0;while(true){if(!(ao<ai)){break;}aq=(ap=(ai-ao>>0)-1>>0,((ap<0||ap>=AO.length)?($throwRuntimeError(\"index out of range\"),undefined):AO[ap]));as=(ar=y/((aq.$low>>>0)),(ar===ar&&ar!==1/0&&ar!==-1/0)?ar>>>0:$throwRuntimeError(\"integer divide by zero\"));(at=a.d,((ao<0||ao>=at.$length)?($throwRuntimeError(\"index out of range\"),undefined):at.$array[at.$offset+ao]=(((as+48>>>0)<<24>>>24))));y=y-(($imul(as,((aq.$low>>>0)))>>>0))>>>0;av=(au=$shiftLeft64((new $Uint64(0,y)),x),new $Uint64(au.$high+ab.$high,au.$low+ab.$low));if((av.$high<ae.$high||(av.$high===ae.$high&&av.$low<ae.$low))){a.nd=ao+1>>0;a.dp=ai+s>>0;a.neg=d.neg;return AR(a,av,ah,ae,$shiftLeft64(aq,x),new $Uint64(0,2));}ao=ao+(1)>>0;}a.nd=ai;a.dp=a.nd+s>>0;a.neg=d.neg;aw=0;ax=new $Uint64(0,1);while(true){ab=$mul64(ab,(new $Uint64(0,10)));ax=$mul64(ax,(new $Uint64(0,10)));aw=(($shiftRightUint64(ab,x).$low>>0));(ay=a.d,az=a.nd,((az<0||az>=ay.$length)?($throwRuntimeError(\"index out of range\"),undefined):ay.$array[ay.$offset+az]=(((aw+48>>0)<<24>>>24))));a.nd=a.nd+(1)>>0;ab=(ba=$shiftLeft64((new $Uint64(0,aw)),x),new $Uint64(ab.$high-ba.$high,ab.$low-ba.$low));if((bb=$mul64(ae,ax),(ab.$high<bb.$high||(ab.$high===bb.$high&&ab.$low<bb.$low)))){return AR(a,ab,$mul64(ah,ax),$mul64(ae,ax),$shiftLeft64(new $Uint64(0,1),x),$mul64(ax,new $Uint64(0,2)));}}};AL.prototype.ShortestDecimal=function(a,b,c){return this.$val.ShortestDecimal(a,b,c);};AR=function(a,b,c,d,e,f){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;if((g=$mul64(new $Uint64(0,2),f),(e.$high<g.$high||(e.$high===g.$high&&e.$low<g.$low)))){return false;}while(true){if(!((h=(i=(j=$div64(e,new $Uint64(0,2),false),new $Uint64(b.$high+j.$high,b.$low+j.$low)),new $Uint64(i.$high+f.$high,i.$low+f.$low)),(h.$high<c.$high||(h.$high===c.$high&&h.$low<c.$low))))){break;}k=a.nd-1>>0;(m=a.d,((k<0||k>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+k]=((l=a.d,((k<0||k>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+k]))-(1)<<24>>>24)));b=(n=e,new $Uint64(b.$high+n.$high,b.$low+n.$low));}if((o=new $Uint64(b.$high+e.$high,b.$low+e.$low),p=(q=(r=$div64(e,new $Uint64(0,2),false),new $Uint64(c.$high+r.$high,c.$low+r.$low)),new $Uint64(q.$high+f.$high,q.$low+f.$low)),(o.$high<p.$high||(o.$high===p.$high&&o.$low<=p.$low)))){return false;}if((b.$high<f.$high||(b.$high===f.$high&&b.$low<f.$low))||(s=new $Uint64(d.$high-f.$high,d.$low-f.$low),(b.$high>s.$high||(b.$high===s.$high&&b.$low>s.$low)))){return false;}if((a.nd===1)&&((t=a.d,(0>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+0]))===48)){a.nd=0;a.dp=0;}return true;};AW=function(a,b,c,d,e){var a,b,c,d,e;return AX(a,b,c,d,e);};$pkg.AppendFloat=AW;AX=function(a,b,c,d,e){var a,aa,ab,ac,ad,ae,af,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;f=new $Uint64(0,0);g=DI.nil;h=e;if(h===(32)){f=(new $Uint64(0,A.Float32bits(($fround(b)))));g=AT;}else if(h===(64)){f=A.Float64bits(b);g=AU;}else{$panic(new $String(\"strconv: illegal AppendFloat/FormatFloat bitSize\"));}j=!((i=$shiftRightUint64(f,((g.expbits+g.mantbits>>>0))),(i.$high===0&&i.$low===0)));l=(($shiftRightUint64(f,g.mantbits).$low>>0))&((((k=g.expbits,k<32?(1<<k):0)>>0)-1>>0));o=(m=(n=$shiftLeft64(new $Uint64(0,1),g.mantbits),new $Uint64(n.$high-0,n.$low-1)),new $Uint64(f.$high&m.$high,(f.$low&m.$low)>>>0));p=l;if(p===((((q=g.expbits,q<32?(1<<q):0)>>0)-1>>0))){r=\"\";if(!((o.$high===0&&o.$low===0))){r=\"NaN\";}else if(j){r=\"-Inf\";}else{r=\"+Inf\";}return $appendSlice(a,r);}else if(p===(0)){l=l+(1)>>0;}else{o=(s=$shiftLeft64(new $Uint64(0,1),g.mantbits),new $Uint64(o.$high|s.$high,(o.$low|s.$low)>>>0));}l=l+(g.bias)>>0;if(c===98){return BE(a,j,o,l,g);}if(!I){return AY(a,d,c,j,o,l,g);}t=new BB.ptr(DE.nil,0,0,false);u=false;v=d<0;if(v){w=new AL.ptr(new $Uint64(0,0),0,false);x=w.AssignComputeBounds(o,l,j,g);y=$clone(x[0],AL);z=$clone(x[1],AL);aa=DH.zero();t.d=new DE(aa);u=w.ShortestDecimal(t,y,z);if(!u){return AY(a,d,c,j,o,l,g);}ab=c;if((ab===(101))||(ab===(69))){d=BG(t.nd-1>>0,0);}else if(ab===(102)){d=BG(t.nd-t.dp>>0,0);}else if((ab===(103))||(ab===(71))){d=t.nd;}}else if(!((c===102))){ac=d;ad=c;if((ad===(101))||(ad===(69))){ac=ac+(1)>>0;}else if((ad===(103))||(ad===(71))){if(d===0){d=1;}ac=d;}if(ac<=15){ae=DG.zero();t.d=new DE(ae);af=new AL.ptr(o,l-((g.mantbits>>0))>>0,j);u=af.FixedDecimal(t,ac);}}if(!u){return AY(a,d,c,j,o,l,g);}return AZ(a,v,j,$clone(t,BB),d,c);};AY=function(a,b,c,d,e,f,g){var a,b,c,d,e,f,g,h,i,j,k,l;h=new AC.ptr(DD.zero(),0,0,false,false);h.Assign(e);h.Shift(f-((g.mantbits>>0))>>0);i=new BB.ptr(DE.nil,0,0,false);j=b<0;if(j){BA(h,e,f,g);BB.copy(i,new BB.ptr(new DE(h.d),h.nd,h.dp,false));k=c;if((k===(101))||(k===(69))){b=i.nd-1>>0;}else if(k===(102)){b=BG(i.nd-i.dp>>0,0);}else if((k===(103))||(k===(71))){b=i.nd;}}else{l=c;if((l===(101))||(l===(69))){h.Round(b+1>>0);}else if(l===(102)){h.Round(h.dp+b>>0);}else if((l===(103))||(l===(71))){if(b===0){b=1;}h.Round(b);}BB.copy(i,new BB.ptr(new DE(h.d),h.nd,h.dp,false));}return AZ(a,j,d,$clone(i,BB),b,c);};AZ=function(a,b,c,d,e,f){var a,b,c,d,e,f,g,h,i;g=f;if((g===(101))||(g===(69))){return BC(a,c,$clone(d,BB),e,f);}else if(g===(102)){return BD(a,c,$clone(d,BB),e);}else if((g===(103))||(g===(71))){h=e;if(h>d.nd&&d.nd>=d.dp){h=d.nd;}if(b){h=6;}i=d.dp-1>>0;if(i<-4||i>=h){if(e>d.nd){e=d.nd;}return BC(a,c,$clone(d,BB),e-1>>0,(f+101<<24>>>24)-103<<24>>>24);}if(e>d.dp){e=d.nd;}return BD(a,c,$clone(d,BB),BG(e-d.dp>>0,0));}return $append(a,37,f);};BA=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;if((b.$high===0&&b.$low===0)){a.nd=0;return;}e=d.bias+1>>0;if(c>e&&($imul(332,((a.dp-a.nd>>0))))>=($imul(100,((c-((d.mantbits>>0))>>0))))){return;}f=new AC.ptr(DD.zero(),0,0,false,false);f.Assign((g=$mul64(b,new $Uint64(0,2)),new $Uint64(g.$high+0,g.$low+1)));f.Shift((c-((d.mantbits>>0))>>0)-1>>0);h=new $Uint64(0,0);i=0;if((j=$shiftLeft64(new $Uint64(0,1),d.mantbits),(b.$high>j.$high||(b.$high===j.$high&&b.$low>j.$low)))||(c===e)){h=new $Uint64(b.$high-0,b.$low-1);i=c;}else{h=(k=$mul64(b,new $Uint64(0,2)),new $Uint64(k.$high-0,k.$low-1));i=c-1>>0;}l=new AC.ptr(DD.zero(),0,0,false,false);l.Assign((m=$mul64(h,new $Uint64(0,2)),new $Uint64(m.$high+0,m.$low+1)));l.Shift((i-((d.mantbits>>0))>>0)-1>>0);o=(n=$div64(b,new $Uint64(0,2),true),(n.$high===0&&n.$low===0));p=0;while(true){if(!(p<a.nd)){break;}q=48;if(p<l.nd){q=(r=l.d,((p<0||p>=r.length)?($throwRuntimeError(\"index out of range\"),undefined):r[p]));}t=(s=a.d,((p<0||p>=s.length)?($throwRuntimeError(\"index out of range\"),undefined):s[p]));u=48;if(p<f.nd){u=(v=f.d,((p<0||p>=v.length)?($throwRuntimeError(\"index out of range\"),undefined):v[p]));}w=!((q===t))||o&&((p+1>>0)===l.nd);x=!((t===u))&&(o||(t+1<<24>>>24)<u||(p+1>>0)<f.nd);if(w&&x){a.Round(p+1>>0);return;}else if(w){a.RoundDown(p+1>>0);return;}else if(x){a.RoundUp(p+1>>0);return;}p=p+(1)>>0;}};BC=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;if(b){a=$append(a,45);}f=48;if(!((c.nd===0))){f=(g=c.d,(0>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+0]));}a=$append(a,f);if(d>0){a=$append(a,46);h=1;i=BF(c.nd,d+1>>0);if(h<i){a=$appendSlice(a,$subslice(c.d,h,i));h=i;}while(true){if(!(h<=d)){break;}a=$append(a,48);h=h+(1)>>0;}}a=$append(a,e);j=c.dp-1>>0;if(c.nd===0){j=0;}if(j<0){f=45;j=-j;}else{f=43;}a=$append(a,f);if(j<10){a=$append(a,48,((j<<24>>>24))+48<<24>>>24);}else if(j<100){a=$append(a,(((k=j/10,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\"))<<24>>>24))+48<<24>>>24,(((l=j%10,l===l?l:$throwRuntimeError(\"integer divide by zero\"))<<24>>>24))+48<<24>>>24);}else{a=$append(a,(((m=j/100,(m===m&&m!==1/0&&m!==-1/0)?m>>0:$throwRuntimeError(\"integer divide by zero\"))<<24>>>24))+48<<24>>>24,(n=(((o=j/10,(o===o&&o!==1/0&&o!==-1/0)?o>>0:$throwRuntimeError(\"integer divide by zero\"))<<24>>>24))%10,n===n?n:$throwRuntimeError(\"integer divide by zero\"))+48<<24>>>24,(((p=j%10,p===p?p:$throwRuntimeError(\"integer divide by zero\"))<<24>>>24))+48<<24>>>24);}return a;};BD=function(a,b,c,d){var a,b,c,d,e,f,g,h,i;if(b){a=$append(a,45);}if(c.dp>0){e=BF(c.nd,c.dp);a=$appendSlice(a,$subslice(c.d,0,e));while(true){if(!(e<c.dp)){break;}a=$append(a,48);e=e+(1)>>0;}}else{a=$append(a,48);}if(d>0){a=$append(a,46);f=0;while(true){if(!(f<d)){break;}g=48;h=c.dp+f>>0;if(0<=h&&h<c.nd){g=(i=c.d,((h<0||h>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+h]));}a=$append(a,g);f=f+(1)>>0;}}return a;};BE=function(a,b,c,d,e){var a,b,c,d,e,f,g;if(b){a=$append(a,45);}f=BS(a,c,10,false,true);a=f[0];a=$append(a,112);d=d-(((e.mantbits>>0)))>>0;if(d>=0){a=$append(a,43);}g=BS(a,(new $Uint64(0,d)),10,d<0,true);a=g[0];return a;};BF=function(a,b){var a,b;if(a<b){return a;}return b;};BG=function(a,b){var a,b;if(a>b){return a;}return b;};BM=function(a,b){var a,b,c,d;if(true&&(a.$high<0||(a.$high===0&&a.$low<100))&&(b===10)){return BR(((a.$low>>0)));}c=BS(DE.nil,a,b,false,false);d=c[1];return d;};$pkg.FormatUint=BM;BN=function(a,b){var a,b,c,d;if(true&&(0<a.$high||(0===a.$high&&0<=a.$low))&&(a.$high<0||(a.$high===0&&a.$low<100))&&(b===10)){return BR((((a.$low+((a.$high>>31)*4294967296))>>0)));}c=BS(DE.nil,(new $Uint64(a.$high,a.$low)),b,(a.$high<0||(a.$high===0&&a.$low<0)),false);d=c[1];return d;};$pkg.FormatInt=BN;BO=function(a){var a;return BN((new $Int64(0,a)),10);};$pkg.Itoa=BO;BR=function(a){var a;if(a<10){return $substring(\"0123456789abcdefghijklmnopqrstuvwxyz\",a,(a+1>>0));}return $substring(\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\",($imul(a,2)),(($imul(a,2))+2>>0));};BS=function(a,b,c,d,e){var a,aa,ab,ac,ad,ae,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;f=DE.nil;g=\"\";if(c<2||c>36){$panic(new $String(\"strconv: illegal AppendInt/FormatInt base\"));}h=DJ.zero();i=65;if(d){b=new $Uint64(-b.$high,-b.$low);}if(c===10){if(true){while(true){if(!((b.$high>0||(b.$high===0&&b.$low>=1000000000)))){break;}j=$div64(b,new $Uint64(0,1000000000),false);l=(((k=$mul64(j,new $Uint64(0,1000000000)),new $Uint64(b.$high-k.$high,b.$low-k.$low)).$low>>>0));m=4;while(true){if(!(m>0)){break;}o=(n=l%100,n===n?n:$throwRuntimeError(\"integer divide by zero\"))*2>>>0;l=(p=l/(100),(p===p&&p!==1/0&&p!==-1/0)?p>>>0:$throwRuntimeError(\"integer divide by zero\"));i=i-(2)>>0;(q=i+1>>0,((q<0||q>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[q]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt((o+1>>>0))));(r=i+0>>0,((r<0||r>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[r]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt((o+0>>>0))));m=m-(1)>>0;}i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt(((l*2>>>0)+1>>>0)));b=j;}}s=((b.$low>>>0));while(true){if(!(s>=100)){break;}u=(t=s%100,t===t?t:$throwRuntimeError(\"integer divide by zero\"))*2>>>0;s=(v=s/(100),(v===v&&v!==1/0&&v!==-1/0)?v>>>0:$throwRuntimeError(\"integer divide by zero\"));i=i-(2)>>0;(w=i+1>>0,((w<0||w>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[w]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt((u+1>>>0))));(x=i+0>>0,((x<0||x>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[x]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt((u+0>>>0))));}y=s*2>>>0;i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt((y+1>>>0)));if(s>=10){i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\".charCodeAt(y));}}else if(BT(c)){z=(((C.TrailingZeros(((c>>>0)))>>>0))&7)>>>0;aa=(new $Uint64(0,c));ab=((c>>>0))-1>>>0;while(true){if(!((b.$high>aa.$high||(b.$high===aa.$high&&b.$low>=aa.$low)))){break;}i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"0123456789abcdefghijklmnopqrstuvwxyz\".charCodeAt(((((b.$low>>>0))&ab)>>>0)));b=$shiftRightUint64(b,(z));}i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"0123456789abcdefghijklmnopqrstuvwxyz\".charCodeAt(((b.$low>>>0))));}else{ac=(new $Uint64(0,c));while(true){if(!((b.$high>ac.$high||(b.$high===ac.$high&&b.$low>=ac.$low)))){break;}i=i-(1)>>0;ad=$div64(b,ac,false);((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"0123456789abcdefghijklmnopqrstuvwxyz\".charCodeAt((((ae=$mul64(ad,ac),new $Uint64(b.$high-ae.$high,b.$low-ae.$low)).$low>>>0))));b=ad;}i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=\"0123456789abcdefghijklmnopqrstuvwxyz\".charCodeAt(((b.$low>>>0))));}if(d){i=i-(1)>>0;((i<0||i>=h.length)?($throwRuntimeError(\"index out of range\"),undefined):h[i]=45);}if(e){f=$appendSlice(a,$subslice(new DE(h),i));return[f,g];}g=($bytesToString($subslice(new DE(h),i)));return[f,g];};BT=function(a){var a;return(a&((a-1>>0)))===0;};BU=function(a,b,c,d){var a,b,c,d,e;return($bytesToString(BW($makeSlice(DE,0,(e=($imul(3,a.length))/2,(e===e&&e!==1/0&&e!==-1/0)?e>>0:$throwRuntimeError(\"integer divide by zero\"))),a,b,c,d)));};BW=function(a,b,c,d,e){var a,b,c,d,e,f,g,h;a=$append(a,c);f=0;while(true){if(!(b.length>0)){break;}g=((b.charCodeAt(0)>>0));f=1;if(g>=128){h=E.DecodeRuneInString(b);g=h[0];f=h[1];}if((f===1)&&(g===65533)){a=$appendSlice(a,\"\\\\x\");a=$append(a,\"0123456789abcdef\".charCodeAt((b.charCodeAt(0)>>>4<<24>>>24)));a=$append(a,\"0123456789abcdef\".charCodeAt(((b.charCodeAt(0)&15)>>>0)));b=$substring(b,f);continue;}a=BY(a,g,c,d,e);b=$substring(b,f);}a=$append(a,c);return a;};BX=function(a,b,c,d,e){var a,b,c,d,e;a=$append(a,c);if(!E.ValidRune(b)){b=65533;}a=BY(a,b,c,d,e);a=$append(a,c);return a;};BY=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j;f=DK.zero();if((b===((c>>0)))||(b===92)){a=$append(a,92);a=$append(a,((b<<24>>>24)));return a;}if(d){if(b<128&&CS(b)){a=$append(a,((b<<24>>>24)));return a;}}else if(CS(b)||e&&CU(b)){g=E.EncodeRune(new DE(f),b);a=$appendSlice(a,$subslice(new DE(f),0,g));return a;}h=b;if(h===(7)){a=$appendSlice(a,\"\\\\a\");}else if(h===(8)){a=$appendSlice(a,\"\\\\b\");}else if(h===(12)){a=$appendSlice(a,\"\\\\f\");}else if(h===(10)){a=$appendSlice(a,\"\\\\n\");}else if(h===(13)){a=$appendSlice(a,\"\\\\r\");}else if(h===(9)){a=$appendSlice(a,\"\\\\t\");}else if(h===(11)){a=$appendSlice(a,\"\\\\v\");}else{if(b<32){a=$appendSlice(a,\"\\\\x\");a=$append(a,\"0123456789abcdef\".charCodeAt((((b<<24>>>24))>>>4<<24>>>24)));a=$append(a,\"0123456789abcdef\".charCodeAt(((((b<<24>>>24))&15)>>>0)));}else if(b>1114111){b=65533;a=$appendSlice(a,\"\\\\u\");i=12;while(true){if(!(i>=0)){break;}a=$append(a,\"0123456789abcdef\".charCodeAt((((b>>$min(((i>>>0)),31))>>0)&15)));i=i-(4)>>0;}}else if(b<65536){a=$appendSlice(a,\"\\\\u\");i=12;while(true){if(!(i>=0)){break;}a=$append(a,\"0123456789abcdef\".charCodeAt((((b>>$min(((i>>>0)),31))>>0)&15)));i=i-(4)>>0;}}else{a=$appendSlice(a,\"\\\\U\");j=28;while(true){if(!(j>=0)){break;}a=$append(a,\"0123456789abcdef\".charCodeAt((((b>>$min(((j>>>0)),31))>>0)&15)));j=j-(4)>>0;}}}return a;};BZ=function(a){var a;return BU(a,34,false,false);};$pkg.Quote=BZ;CA=function(a,b){var a,b;return BW(a,b,34,false,false);};$pkg.AppendQuote=CA;CB=function(a){var a;return BU(a,34,true,false);};$pkg.QuoteToASCII=CB;CC=function(a,b){var a,b;return BW(a,b,34,true,false);};$pkg.AppendQuoteToASCII=CC;CG=function(a,b){var a,b;return BX(a,b,39,false,false);};$pkg.AppendQuoteRune=CG;CI=function(a,b){var a,b;return BX(a,b,39,true,false);};$pkg.AppendQuoteRuneToASCII=CI;CL=function(a){var a,b,c,d;while(true){if(!(a.length>0)){break;}b=E.DecodeRuneInString(a);c=b[0];d=b[1];a=$substring(a,d);if(d>1){if(c===65279){return false;}continue;}if(c===65533){return false;}if((c<32&&!((c===9)))||(c===96)||(c===127)){return false;}}return true;};$pkg.CanBackquote=CL;CM=function(a){var a,b,c,d,e,f,g,h,i,j;b=0;c=false;d=((a>>0));if(48<=d&&d<=57){e=d-48>>0;f=true;b=e;c=f;return[b,c];}else if(97<=d&&d<=102){g=(d-97>>0)+10>>0;h=true;b=g;c=h;return[b,c];}else if(65<=d&&d<=70){i=(d-65>>0)+10>>0;j=true;b=i;c=j;return[b,c];}return[b,c];};CN=function(a,b){var a,aa,ab,ac,ad,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;c=0;d=false;e=\"\";f=$ifaceNil;if(a.length===0){f=$pkg.ErrSyntax;return[c,d,e,f];}g=a.charCodeAt(0);if((g===b)&&((b===39)||(b===34))){f=$pkg.ErrSyntax;return[c,d,e,f];}else if(g>=128){h=E.DecodeRuneInString(a);i=h[0];j=h[1];k=i;l=true;m=$substring(a,j);n=$ifaceNil;c=k;d=l;e=m;f=n;return[c,d,e,f];}else if(!((g===92))){o=((a.charCodeAt(0)>>0));p=false;q=$substring(a,1);r=$ifaceNil;c=o;d=p;e=q;f=r;return[c,d,e,f];}if(a.length<=1){f=$pkg.ErrSyntax;return[c,d,e,f];}s=a.charCodeAt(1);a=$substring(a,2);switch(0){default:t=s;if(t===(97)){c=7;}else if(t===(98)){c=8;}else if(t===(102)){c=12;}else if(t===(110)){c=10;}else if(t===(114)){c=13;}else if(t===(116)){c=9;}else if(t===(118)){c=11;}else if((t===(120))||(t===(117))||(t===(85))){u=0;v=s;if(v===(120)){u=2;}else if(v===(117)){u=4;}else if(v===(85)){u=8;}w=0;if(a.length<u){f=$pkg.ErrSyntax;return[c,d,e,f];}x=0;while(true){if(!(x<u)){break;}y=CM(a.charCodeAt(x));z=y[0];aa=y[1];if(!aa){f=$pkg.ErrSyntax;return[c,d,e,f];}w=(w<<4>>0)|z;x=x+(1)>>0;}a=$substring(a,u);if(s===120){c=w;break;}if(w>1114111){f=$pkg.ErrSyntax;return[c,d,e,f];}c=w;d=true;}else if((t===(48))||(t===(49))||(t===(50))||(t===(51))||(t===(52))||(t===(53))||(t===(54))||(t===(55))){ab=((s>>0))-48>>0;if(a.length<2){f=$pkg.ErrSyntax;return[c,d,e,f];}ac=0;while(true){if(!(ac<2)){break;}ad=((a.charCodeAt(ac)>>0))-48>>0;if(ad<0||ad>7){f=$pkg.ErrSyntax;return[c,d,e,f];}ab=((ab<<3>>0))|ad;ac=ac+(1)>>0;}a=$substring(a,2);if(ab>255){f=$pkg.ErrSyntax;return[c,d,e,f];}c=ab;}else if(t===(92)){c=92;}else if((t===(39))||(t===(34))){if(!((s===b))){f=$pkg.ErrSyntax;return[c,d,e,f];}c=((s>>0));}else{f=$pkg.ErrSyntax;return[c,d,e,f];}}e=a;return[c,d,e,f];};$pkg.UnquoteChar=CN;CO=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;b=a.length;if(b<2){return[\"\",$pkg.ErrSyntax];}c=a.charCodeAt(0);if(!((c===a.charCodeAt((b-1>>0))))){return[\"\",$pkg.ErrSyntax];}a=$substring(a,1,(b-1>>0));if(c===96){if(CP(a,96)){return[\"\",$pkg.ErrSyntax];}if(CP(a,13)){d=$makeSlice(DE,0,(a.length-1>>0));e=0;while(true){if(!(e<a.length)){break;}if(!((a.charCodeAt(e)===13))){d=$append(d,a.charCodeAt(e));}e=e+(1)>>0;}return[($bytesToString(d)),$ifaceNil];}return[a,$ifaceNil];}if(!((c===34))&&!((c===39))){return[\"\",$pkg.ErrSyntax];}if(CP(a,10)){return[\"\",$pkg.ErrSyntax];}if(!CP(a,92)&&!CP(a,c)){f=c;if(f===(34)){if(E.ValidString(a)){return[a,$ifaceNil];}}else if(f===(39)){g=E.DecodeRuneInString(a);h=g[0];i=g[1];if((i===a.length)&&(!((h===65533))||!((i===1)))){return[a,$ifaceNil];}}}j=DK.zero();l=$makeSlice(DE,0,(k=($imul(3,a.length))/2,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\")));while(true){if(!(a.length>0)){break;}m=CN(a,c);n=m[0];o=m[1];p=m[2];q=m[3];if(!($interfaceIsEqual(q,$ifaceNil))){return[\"\",q];}a=p;if(n<128||!o){l=$append(l,((n<<24>>>24)));}else{r=E.EncodeRune(new DE(j),n);l=$appendSlice(l,$subslice(new DE(j),0,r));}if((c===39)&&!((a.length===0))){return[\"\",$pkg.ErrSyntax];}}return[($bytesToString(l)),$ifaceNil];};$pkg.Unquote=CO;CP=function(a,b){var a,b;return!((D.IndexByteString(a,b)===-1));};CQ=function(a,b){var a,b,c,d,e,f,g,h;c=0;d=a.$length;e=c;f=d;while(true){if(!(e<f)){break;}h=e+(g=((f-e>>0))/2,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;if(((h<0||h>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+h])<b){e=h+1>>0;}else{f=h;}}return e;};CR=function(a,b){var a,b,c,d,e,f,g,h;c=0;d=a.$length;e=c;f=d;while(true){if(!(e<f)){break;}h=e+(g=((f-e>>0))/2,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;if(((h<0||h>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+h])<b){e=h+1>>0;}else{f=h;}}return e;};CS=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;if(a<=255){if(32<=a&&a<=126){return true;}if(161<=a&&a<=255){return!((a===173));}return false;}if(0<=a&&a<65536){b=((a<<16>>>16));c=BH;d=BI;e=b;f=c;g=d;h=CQ(f,e);if(h>=f.$length||e<(i=(h&~1)>>0,((i<0||i>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+i]))||(j=h|1,((j<0||j>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+j]))<e){return false;}k=CQ(g,e);return k>=g.$length||!((((k<0||k>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+k])===e));}l=((a>>>0));m=BJ;n=BK;o=l;p=m;q=n;r=CR(p,o);if(r>=p.$length||o<(s=(r&~1)>>0,((s<0||s>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+s]))||(t=r|1,((t<0||t>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+t]))<o){return false;}if(a>=131072){return true;}a=a-(65536)>>0;u=CQ(q,((a<<16>>>16)));return u>=q.$length||!((((u<0||u>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+u])===((a<<16>>>16))));};$pkg.IsPrint=CS;CU=function(a){var a,b,c;if(a>65535){return false;}b=((a<<16>>>16));c=CQ(BL,b);return c<BL.$length&&(b===((c<0||c>=BL.$length)?($throwRuntimeError(\"index out of range\"),undefined):BL.$array[BL.$offset+c]));};DF.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];DL.methods=[{prop:\"set\",name:\"set\",pkg:\"strconv\",typ:$funcType([$String],[$Bool],false)},{prop:\"floatBits\",name:\"floatBits\",pkg:\"strconv\",typ:$funcType([DI],[$Uint64,$Bool],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Assign\",name:\"Assign\",pkg:\"\",typ:$funcType([$Uint64],[],false)},{prop:\"Shift\",name:\"Shift\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"Round\",name:\"Round\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"RoundDown\",name:\"RoundDown\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"RoundUp\",name:\"RoundUp\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"RoundedInteger\",name:\"RoundedInteger\",pkg:\"\",typ:$funcType([],[$Uint64],false)}];DN.methods=[{prop:\"floatBits\",name:\"floatBits\",pkg:\"strconv\",typ:$funcType([DI],[$Uint64,$Bool],false)},{prop:\"AssignComputeBounds\",name:\"AssignComputeBounds\",pkg:\"\",typ:$funcType([$Uint64,$Int,$Bool,DI],[AL,AL],false)},{prop:\"Normalize\",name:\"Normalize\",pkg:\"\",typ:$funcType([],[$Uint],false)},{prop:\"Multiply\",name:\"Multiply\",pkg:\"\",typ:$funcType([AL],[],false)},{prop:\"AssignDecimal\",name:\"AssignDecimal\",pkg:\"\",typ:$funcType([$Uint64,$Int,$Bool,$Bool,DI],[$Bool],false)},{prop:\"frexp10\",name:\"frexp10\",pkg:\"strconv\",typ:$funcType([],[$Int,$Int],false)},{prop:\"FixedDecimal\",name:\"FixedDecimal\",pkg:\"\",typ:$funcType([DM,$Int],[$Bool],false)},{prop:\"ShortestDecimal\",name:\"ShortestDecimal\",pkg:\"\",typ:$funcType([DM,DN,DN],[$Bool],false)}];U.init(\"\",[{prop:\"Func\",name:\"Func\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Num\",name:\"Num\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$error,tag:\"\"}]);AC.init(\"strconv\",[{prop:\"d\",name:\"d\",embedded:false,exported:false,typ:DD,tag:\"\"},{prop:\"nd\",name:\"nd\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"dp\",name:\"dp\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"neg\",name:\"neg\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"trunc\",name:\"trunc\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);AG.init(\"strconv\",[{prop:\"delta\",name:\"delta\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"cutoff\",name:\"cutoff\",embedded:false,exported:false,typ:$String,tag:\"\"}]);AL.init(\"strconv\",[{prop:\"mant\",name:\"mant\",embedded:false,exported:false,typ:$Uint64,tag:\"\"},{prop:\"exp\",name:\"exp\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"neg\",name:\"neg\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);AS.init(\"strconv\",[{prop:\"mantbits\",name:\"mantbits\",embedded:false,exported:false,typ:$Uint,tag:\"\"},{prop:\"expbits\",name:\"expbits\",embedded:false,exported:false,typ:$Uint,tag:\"\"},{prop:\"bias\",name:\"bias\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);BB.init(\"strconv\",[{prop:\"d\",name:\"d\",embedded:false,exported:false,typ:DE,tag:\"\"},{prop:\"nd\",name:\"nd\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"dp\",name:\"dp\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"neg\",name:\"neg\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}I=true;$pkg.ErrRange=B.New(\"value out of range\");$pkg.ErrSyntax=B.New(\"invalid syntax\");AH=new DA([new AG.ptr(0,\"\"),new AG.ptr(1,\"5\"),new AG.ptr(1,\"25\"),new AG.ptr(1,\"125\"),new AG.ptr(2,\"625\"),new AG.ptr(2,\"3125\"),new AG.ptr(2,\"15625\"),new AG.ptr(3,\"78125\"),new AG.ptr(3,\"390625\"),new AG.ptr(3,\"1953125\"),new AG.ptr(4,\"9765625\"),new AG.ptr(4,\"48828125\"),new AG.ptr(4,\"244140625\"),new AG.ptr(4,\"1220703125\"),new AG.ptr(5,\"6103515625\"),new AG.ptr(5,\"30517578125\"),new AG.ptr(5,\"152587890625\"),new AG.ptr(6,\"762939453125\"),new AG.ptr(6,\"3814697265625\"),new AG.ptr(6,\"19073486328125\"),new AG.ptr(7,\"95367431640625\"),new AG.ptr(7,\"476837158203125\"),new AG.ptr(7,\"2384185791015625\"),new AG.ptr(7,\"11920928955078125\"),new AG.ptr(8,\"59604644775390625\"),new AG.ptr(8,\"298023223876953125\"),new AG.ptr(8,\"1490116119384765625\"),new AG.ptr(9,\"7450580596923828125\"),new AG.ptr(9,\"37252902984619140625\"),new AG.ptr(9,\"186264514923095703125\"),new AG.ptr(10,\"931322574615478515625\"),new AG.ptr(10,\"4656612873077392578125\"),new AG.ptr(10,\"23283064365386962890625\"),new AG.ptr(10,\"116415321826934814453125\"),new AG.ptr(11,\"582076609134674072265625\"),new AG.ptr(11,\"2910383045673370361328125\"),new AG.ptr(11,\"14551915228366851806640625\"),new AG.ptr(12,\"72759576141834259033203125\"),new AG.ptr(12,\"363797880709171295166015625\"),new AG.ptr(12,\"1818989403545856475830078125\"),new AG.ptr(13,\"9094947017729282379150390625\"),new AG.ptr(13,\"45474735088646411895751953125\"),new AG.ptr(13,\"227373675443232059478759765625\"),new AG.ptr(13,\"1136868377216160297393798828125\"),new AG.ptr(14,\"5684341886080801486968994140625\"),new AG.ptr(14,\"28421709430404007434844970703125\"),new AG.ptr(14,\"142108547152020037174224853515625\"),new AG.ptr(15,\"710542735760100185871124267578125\"),new AG.ptr(15,\"3552713678800500929355621337890625\"),new AG.ptr(15,\"17763568394002504646778106689453125\"),new AG.ptr(16,\"88817841970012523233890533447265625\"),new AG.ptr(16,\"444089209850062616169452667236328125\"),new AG.ptr(16,\"2220446049250313080847263336181640625\"),new AG.ptr(16,\"11102230246251565404236316680908203125\"),new AG.ptr(17,\"55511151231257827021181583404541015625\"),new AG.ptr(17,\"277555756156289135105907917022705078125\"),new AG.ptr(17,\"1387778780781445675529539585113525390625\"),new AG.ptr(18,\"6938893903907228377647697925567626953125\"),new AG.ptr(18,\"34694469519536141888238489627838134765625\"),new AG.ptr(18,\"173472347597680709441192448139190673828125\"),new AG.ptr(19,\"867361737988403547205962240695953369140625\")]);AM=$toNativeArray($kindStruct,[new AL.ptr(new $Uint64(2147483648,0),-63,false),new AL.ptr(new $Uint64(2684354560,0),-60,false),new AL.ptr(new $Uint64(3355443200,0),-57,false),new AL.ptr(new $Uint64(4194304000,0),-54,false),new AL.ptr(new $Uint64(2621440000,0),-50,false),new AL.ptr(new $Uint64(3276800000,0),-47,false),new AL.ptr(new $Uint64(4096000000,0),-44,false),new AL.ptr(new $Uint64(2560000000,0),-40,false)]);AN=$toNativeArray($kindStruct,[new AL.ptr(new $Uint64(4203730336,136053384),-1220,false),new AL.ptr(new $Uint64(3132023167,2722021238),-1193,false),new AL.ptr(new $Uint64(2333539104,810921078),-1166,false),new AL.ptr(new $Uint64(3477244234,1573795306),-1140,false),new AL.ptr(new $Uint64(2590748842,1432697645),-1113,false),new AL.ptr(new $Uint64(3860516611,1025131999),-1087,false),new AL.ptr(new $Uint64(2876309015,3348809418),-1060,false),new AL.ptr(new $Uint64(4286034428,3200048207),-1034,false),new AL.ptr(new $Uint64(3193344495,1097586188),-1007,false),new AL.ptr(new $Uint64(2379227053,2424306748),-980,false),new AL.ptr(new $Uint64(3545324584,827693699),-954,false),new AL.ptr(new $Uint64(2641472655,2913388981),-927,false),new AL.ptr(new $Uint64(3936100983,602835915),-901,false),new AL.ptr(new $Uint64(2932623761,1081627501),-874,false),new AL.ptr(new $Uint64(2184974969,1572261463),-847,false),new AL.ptr(new $Uint64(3255866422,1308317239),-821,false),new AL.ptr(new $Uint64(2425809519,944281679),-794,false),new AL.ptr(new $Uint64(3614737867,629291719),-768,false),new AL.ptr(new $Uint64(2693189581,2545915892),-741,false),new AL.ptr(new $Uint64(4013165208,388672741),-715,false),new AL.ptr(new $Uint64(2990041083,708162190),-688,false),new AL.ptr(new $Uint64(2227754207,3536207675),-661,false),new AL.ptr(new $Uint64(3319612455,450088378),-635,false),new AL.ptr(new $Uint64(2473304014,3139815830),-608,false),new AL.ptr(new $Uint64(3685510180,2103616900),-582,false),new AL.ptr(new $Uint64(2745919064,224385782),-555,false),new AL.ptr(new $Uint64(4091738259,3737383206),-529,false),new AL.ptr(new $Uint64(3048582568,2868871352),-502,false),new AL.ptr(new $Uint64(2271371013,1820084875),-475,false),new AL.ptr(new $Uint64(3384606560,885076051),-449,false),new AL.ptr(new $Uint64(2521728396,2444895829),-422,false),new AL.ptr(new $Uint64(3757668132,1881767613),-396,false),new AL.ptr(new $Uint64(2799680927,3102062735),-369,false),new AL.ptr(new $Uint64(4171849679,2289335700),-343,false),new AL.ptr(new $Uint64(3108270227,2410191823),-316,false),new AL.ptr(new $Uint64(2315841784,3205436779),-289,false),new AL.ptr(new $Uint64(3450873173,1697722806),-263,false),new AL.ptr(new $Uint64(2571100870,3497754540),-236,false),new AL.ptr(new $Uint64(3831238852,707476230),-210,false),new AL.ptr(new $Uint64(2854495385,1769181907),-183,false),new AL.ptr(new $Uint64(4253529586,2197867022),-157,false),new AL.ptr(new $Uint64(3169126500,2450594539),-130,false),new AL.ptr(new $Uint64(2361183241,1867548876),-103,false),new AL.ptr(new $Uint64(3518437208,3793315116),-77,false),new AL.ptr(new $Uint64(2621440000,0),-50,false),new AL.ptr(new $Uint64(3906250000,0),-24,false),new AL.ptr(new $Uint64(2910383045,2892103680),3,false),new AL.ptr(new $Uint64(2168404344,4170451332),30,false),new AL.ptr(new $Uint64(3231174267,3372684723),56,false),new AL.ptr(new $Uint64(2407412430,2078956656),83,false),new AL.ptr(new $Uint64(3587324068,2884206696),109,false),new AL.ptr(new $Uint64(2672764710,395977285),136,false),new AL.ptr(new $Uint64(3982729777,3569679143),162,false),new AL.ptr(new $Uint64(2967364920,2361961896),189,false),new AL.ptr(new $Uint64(2210859150,447440347),216,false),new AL.ptr(new $Uint64(3294436857,1114709402),242,false),new AL.ptr(new $Uint64(2454546732,2786846552),269,false),new AL.ptr(new $Uint64(3657559652,443583978),295,false),new AL.ptr(new $Uint64(2725094297,2599384906),322,false),new AL.ptr(new $Uint64(4060706939,3028118405),348,false),new AL.ptr(new $Uint64(3025462433,2044532855),375,false),new AL.ptr(new $Uint64(2254145170,1536935362),402,false),new AL.ptr(new $Uint64(3358938053,3365297469),428,false),new AL.ptr(new $Uint64(2502603868,4204241075),455,false),new AL.ptr(new $Uint64(3729170365,2577424355),481,false),new AL.ptr(new $Uint64(2778448436,3677981733),508,false),new AL.ptr(new $Uint64(4140210802,2744688476),534,false),new AL.ptr(new $Uint64(3084697427,1424604878),561,false),new AL.ptr(new $Uint64(2298278679,4062331362),588,false),new AL.ptr(new $Uint64(3424702107,3546052773),614,false),new AL.ptr(new $Uint64(2551601907,2065781727),641,false),new AL.ptr(new $Uint64(3802183132,2535403578),667,false),new AL.ptr(new $Uint64(2832847187,1558426518),694,false),new AL.ptr(new $Uint64(4221271257,2762425404),720,false),new AL.ptr(new $Uint64(3145092172,2812560400),747,false),new AL.ptr(new $Uint64(2343276271,3057687578),774,false),new AL.ptr(new $Uint64(3491753744,2790753324),800,false),new AL.ptr(new $Uint64(2601559269,3918606633),827,false),new AL.ptr(new $Uint64(3876625403,2711358621),853,false),new AL.ptr(new $Uint64(2888311001,1648096297),880,false),new AL.ptr(new $Uint64(2151959390,2057817989),907,false),new AL.ptr(new $Uint64(3206669376,61660461),933,false),new AL.ptr(new $Uint64(2389154863,1581580175),960,false),new AL.ptr(new $Uint64(3560118173,2626467905),986,false),new AL.ptr(new $Uint64(2652494738,3034782633),1013,false),new AL.ptr(new $Uint64(3952525166,3135207385),1039,false),new AL.ptr(new $Uint64(2944860731,2616258155),1066,false)]);AO=$toNativeArray($kindUint64,[new $Uint64(0,1),new $Uint64(0,10),new $Uint64(0,100),new $Uint64(0,1000),new $Uint64(0,10000),new $Uint64(0,100000),new $Uint64(0,1000000),new $Uint64(0,10000000),new $Uint64(0,100000000),new $Uint64(0,1000000000),new $Uint64(2,1410065408),new $Uint64(23,1215752192),new $Uint64(232,3567587328),new $Uint64(2328,1316134912),new $Uint64(23283,276447232),new $Uint64(232830,2764472320),new $Uint64(2328306,1874919424),new $Uint64(23283064,1569325056),new $Uint64(232830643,2808348672),new $Uint64(2328306436,2313682944)]);AT=new AS.ptr(23,8,-127);AU=new AS.ptr(52,11,-1023);BH=new DB([32,126,161,887,890,895,900,1366,1369,1418,1421,1479,1488,1514,1520,1524,1542,1563,1566,1805,1808,1866,1869,1969,1984,2042,2048,2093,2096,2139,2142,2154,2208,2237,2260,2444,2447,2448,2451,2482,2486,2489,2492,2500,2503,2504,2507,2510,2519,2519,2524,2531,2534,2557,2561,2570,2575,2576,2579,2617,2620,2626,2631,2632,2635,2637,2641,2641,2649,2654,2662,2677,2689,2745,2748,2765,2768,2768,2784,2787,2790,2801,2809,2828,2831,2832,2835,2873,2876,2884,2887,2888,2891,2893,2902,2903,2908,2915,2918,2935,2946,2954,2958,2965,2969,2975,2979,2980,2984,2986,2990,3001,3006,3010,3014,3021,3024,3024,3031,3031,3046,3066,3072,3129,3133,3149,3157,3162,3168,3171,3174,3183,3192,3257,3260,3277,3285,3286,3294,3299,3302,3314,3328,3407,3412,3427,3430,3455,3458,3478,3482,3517,3520,3526,3530,3530,3535,3551,3558,3567,3570,3572,3585,3642,3647,3675,3713,3716,3719,3722,3725,3725,3732,3751,3754,3773,3776,3789,3792,3801,3804,3807,3840,3948,3953,4058,4096,4295,4301,4301,4304,4685,4688,4701,4704,4749,4752,4789,4792,4805,4808,4885,4888,4954,4957,4988,4992,5017,5024,5109,5112,5117,5120,5788,5792,5880,5888,5908,5920,5942,5952,5971,5984,6003,6016,6109,6112,6121,6128,6137,6144,6157,6160,6169,6176,6263,6272,6314,6320,6389,6400,6443,6448,6459,6464,6464,6468,6509,6512,6516,6528,6571,6576,6601,6608,6618,6622,6683,6686,6780,6783,6793,6800,6809,6816,6829,6832,6846,6912,6987,6992,7036,7040,7155,7164,7223,7227,7241,7245,7304,7360,7367,7376,7417,7424,7957,7960,7965,7968,8005,8008,8013,8016,8061,8064,8147,8150,8175,8178,8190,8208,8231,8240,8286,8304,8305,8308,8348,8352,8383,8400,8432,8448,8587,8592,9254,9280,9290,9312,11123,11126,11157,11160,11193,11197,11218,11244,11247,11264,11507,11513,11559,11565,11565,11568,11623,11631,11632,11647,11670,11680,11849,11904,12019,12032,12245,12272,12283,12289,12438,12441,12543,12549,12590,12593,12730,12736,12771,12784,19893,19904,40938,40960,42124,42128,42182,42192,42539,42560,42743,42752,42935,42999,43051,43056,43065,43072,43127,43136,43205,43214,43225,43232,43261,43264,43347,43359,43388,43392,43481,43486,43574,43584,43597,43600,43609,43612,43714,43739,43766,43777,43782,43785,43790,43793,43798,43808,43877,43888,44013,44016,44025,44032,55203,55216,55238,55243,55291,63744,64109,64112,64217,64256,64262,64275,64279,64285,64449,64467,64831,64848,64911,64914,64967,65008,65021,65024,65049,65056,65131,65136,65276,65281,65470,65474,65479,65482,65487,65490,65495,65498,65500,65504,65518,65532,65533]);BI=new DB([173,907,909,930,1328,1376,1416,1424,1757,2111,2143,2229,2274,2436,2473,2481,2526,2564,2601,2609,2612,2615,2621,2653,2692,2702,2706,2729,2737,2740,2758,2762,2816,2820,2857,2865,2868,2910,2948,2961,2971,2973,3017,3076,3085,3089,3113,3141,3145,3159,3204,3213,3217,3241,3252,3269,3273,3295,3312,3332,3341,3345,3397,3401,3460,3506,3516,3541,3543,3715,3721,3736,3744,3748,3750,3756,3770,3781,3783,3912,3992,4029,4045,4294,4681,4695,4697,4745,4785,4799,4801,4823,4881,5760,5901,5997,6001,6431,6751,7674,8024,8026,8028,8030,8117,8133,8156,8181,8335,11209,11311,11359,11558,11687,11695,11703,11711,11719,11727,11735,11743,11930,12352,12687,12831,13055,42927,43470,43519,43815,43823,64311,64317,64319,64322,64325,65107,65127,65141,65511]);BJ=new DC([65536,65613,65616,65629,65664,65786,65792,65794,65799,65843,65847,65947,65952,65952,66000,66045,66176,66204,66208,66256,66272,66299,66304,66339,66349,66378,66384,66426,66432,66499,66504,66517,66560,66717,66720,66729,66736,66771,66776,66811,66816,66855,66864,66915,66927,66927,67072,67382,67392,67413,67424,67431,67584,67589,67592,67640,67644,67644,67647,67742,67751,67759,67808,67829,67835,67867,67871,67897,67903,67903,67968,68023,68028,68047,68050,68102,68108,68147,68152,68154,68159,68167,68176,68184,68192,68255,68288,68326,68331,68342,68352,68405,68409,68437,68440,68466,68472,68497,68505,68508,68521,68527,68608,68680,68736,68786,68800,68850,68858,68863,69216,69246,69632,69709,69714,69743,69759,69825,69840,69864,69872,69881,69888,69955,69968,70006,70016,70093,70096,70132,70144,70206,70272,70313,70320,70378,70384,70393,70400,70412,70415,70416,70419,70457,70460,70468,70471,70472,70475,70477,70480,70480,70487,70487,70493,70499,70502,70508,70512,70516,70656,70749,70784,70855,70864,70873,71040,71093,71096,71133,71168,71236,71248,71257,71264,71276,71296,71351,71360,71369,71424,71449,71453,71467,71472,71487,71840,71922,71935,71935,72192,72263,72272,72323,72326,72354,72384,72440,72704,72773,72784,72812,72816,72847,72850,72886,72960,73014,73018,73031,73040,73049,73728,74649,74752,74868,74880,75075,77824,78894,82944,83526,92160,92728,92736,92777,92782,92783,92880,92909,92912,92917,92928,92997,93008,93047,93053,93071,93952,94020,94032,94078,94095,94111,94176,94177,94208,100332,100352,101106,110592,110878,110960,111355,113664,113770,113776,113788,113792,113800,113808,113817,113820,113823,118784,119029,119040,119078,119081,119154,119163,119272,119296,119365,119552,119638,119648,119665,119808,119967,119970,119970,119973,119974,119977,120074,120077,120134,120138,120485,120488,120779,120782,121483,121499,121519,122880,122904,122907,122922,124928,125124,125127,125142,125184,125258,125264,125273,125278,125279,126464,126500,126503,126523,126530,126530,126535,126548,126551,126564,126567,126619,126625,126651,126704,126705,126976,127019,127024,127123,127136,127150,127153,127221,127232,127244,127248,127339,127344,127404,127462,127490,127504,127547,127552,127560,127568,127569,127584,127589,127744,128724,128736,128748,128752,128760,128768,128883,128896,128980,129024,129035,129040,129095,129104,129113,129120,129159,129168,129197,129280,129291,129296,129356,129360,129387,129408,129431,129472,129472,129488,129510,131072,173782,173824,177972,177984,178205,178208,183969,183984,191456,194560,195101,917760,917999]);BK=new DB([12,39,59,62,399,926,2057,2102,2134,2291,2564,2580,2584,4285,4405,4576,4626,4743,4745,4750,4766,4868,4905,4913,4916,5210,5212,6813,7177,7223,7336,7431,7434,7483,7486,9327,27231,27482,27490,54357,54429,54445,54458,54460,54468,54534,54549,54557,54586,54591,54597,54609,55968,57351,57378,57381,60932,60960,60963,60968,60979,60984,60986,61000,61002,61004,61008,61011,61016,61018,61020,61022,61024,61027,61035,61043,61048,61053,61055,61066,61092,61098,61632,61648,61743,63807]);BL=new DB([160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/race\"]=(function(){var $pkg={},$init,A,B,C,D,E,H,I;A=function(a){var a;};$pkg.Acquire=A;B=function(a){var a;};$pkg.Release=B;C=function(a){var a;};$pkg.ReleaseMerge=C;D=function(){};$pkg.Disable=D;E=function(){};$pkg.Enable=E;H=function(a,b){var a,b;};$pkg.ReadRange=H;I=function(a,b){var a,b;};$pkg.WriteRange=I;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"sync/atomic\"]=(function(){var $pkg={},$init,A,AF,AJ,H,K,N,O,S,U,V,Y,AA;A=$packages[\"github.com/gopherjs/gopherjs/js\"];AF=$pkg.Value=$newType(0,$kindStruct,\"atomic.Value\",true,\"sync/atomic\",true,function(v_){this.$val=this;if(arguments.length===0){this.v=$ifaceNil;return;}this.v=v_;});AJ=$ptrType(AF);H=function(ad,ae,af){var ad,ae,af;if(ad.$get()===ae){ad.$set(af);return true;}return false;};$pkg.CompareAndSwapInt32=H;K=function(ad,ae,af){var ad,ae,af,ag;if((ag=ad.$get(),(ag.$high===ae.$high&&ag.$low===ae.$low))){ad.$set(af);return true;}return false;};$pkg.CompareAndSwapUint64=K;N=function(ad,ae){var ad,ae,af;af=ad.$get()+ae>>0;ad.$set(af);return af;};$pkg.AddInt32=N;O=function(ad,ae){var ad,ae,af;af=ad.$get()+ae>>>0;ad.$set(af);return af;};$pkg.AddUint32=O;S=function(ad){var ad;return ad.$get();};$pkg.LoadInt32=S;U=function(ad){var ad;return ad.$get();};$pkg.LoadUint32=U;V=function(ad){var ad;return ad.$get();};$pkg.LoadUint64=V;Y=function(ad,ae){var ad,ae;ad.$set(ae);};$pkg.StoreInt32=Y;AA=function(ad,ae){var ad,ae;ad.$set(ae);};$pkg.StoreUint32=AA;AF.ptr.prototype.Load=function(){var ad,ae;ad=$ifaceNil;ae=this;ad=ae.v;return ad;};AF.prototype.Load=function(){return this.$val.Load();};AF.ptr.prototype.Store=function(ad){var ad,ae;ae=this;if($interfaceIsEqual(ad,$ifaceNil)){$panic(new $String(\"sync/atomic: store of nil value into Value\"));}if(!($interfaceIsEqual(ae.v,$ifaceNil))&&!(ad.constructor===ae.v.constructor)){$panic(new $String(\"sync/atomic: store of inconsistently typed value into Value\"));}ae.v=ad;};AF.prototype.Store=function(ad){return this.$val.Store(ad);};AJ.methods=[{prop:\"Load\",name:\"Load\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)},{prop:\"Store\",name:\"Store\",pkg:\"\",typ:$funcType([$emptyInterface],[],false)}];AF.init(\"sync/atomic\",[{prop:\"v\",name:\"v\",embedded:false,exported:false,typ:$emptyInterface,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"sync\"]=(function(){var $pkg={},$init,A,C,D,B,F,Z,AA,AB,AC,AD,AO,AV,AW,AY,AZ,BA,BB,BC,BI,BL,BM,BN,BO,BR,CA,CB,CC,CD,H,I,W,AJ,G,K,L,M,N,O,P,AH,AK,AL,AT,AU;A=$packages[\"github.com/gopherjs/gopherjs/js\"];C=$packages[\"internal/race\"];D=$packages[\"runtime\"];B=$packages[\"sync/atomic\"];F=$pkg.Pool=$newType(0,$kindStruct,\"sync.Pool\",true,\"sync\",true,function(local_,localSize_,store_,New_){this.$val=this;if(arguments.length===0){this.local=0;this.localSize=0;this.store=BM.nil;this.New=$throwNilPointerError;return;}this.local=local_;this.localSize=localSize_;this.store=store_;this.New=New_;});Z=$pkg.Mutex=$newType(0,$kindStruct,\"sync.Mutex\",true,\"sync\",true,function(state_,sema_){this.$val=this;if(arguments.length===0){this.state=0;this.sema=0;return;}this.state=state_;this.sema=sema_;});AA=$pkg.Locker=$newType(8,$kindInterface,\"sync.Locker\",true,\"sync\",true,null);AB=$pkg.Once=$newType(0,$kindStruct,\"sync.Once\",true,\"sync\",true,function(m_,done_){this.$val=this;if(arguments.length===0){this.m=new Z.ptr(0,0);this.done=0;return;}this.m=m_;this.done=done_;});AC=$pkg.poolLocalInternal=$newType(0,$kindStruct,\"sync.poolLocalInternal\",true,\"sync\",false,function(private$0_,shared_,Mutex_){this.$val=this;if(arguments.length===0){this.private$0=$ifaceNil;this.shared=BM.nil;this.Mutex=new Z.ptr(0,0);return;}this.private$0=private$0_;this.shared=shared_;this.Mutex=Mutex_;});AD=$pkg.poolLocal=$newType(0,$kindStruct,\"sync.poolLocal\",true,\"sync\",false,function(poolLocalInternal_,pad_){this.$val=this;if(arguments.length===0){this.poolLocalInternal=new AC.ptr($ifaceNil,BM.nil,new Z.ptr(0,0));this.pad=CD.zero();return;}this.poolLocalInternal=poolLocalInternal_;this.pad=pad_;});AO=$pkg.notifyList=$newType(0,$kindStruct,\"sync.notifyList\",true,\"sync\",false,function(wait_,notify_,lock_,head_,tail_){this.$val=this;if(arguments.length===0){this.wait=0;this.notify=0;this.lock=0;this.head=0;this.tail=0;return;}this.wait=wait_;this.notify=notify_;this.lock=lock_;this.head=head_;this.tail=tail_;});AV=$pkg.RWMutex=$newType(0,$kindStruct,\"sync.RWMutex\",true,\"sync\",true,function(w_,writerSem_,readerSem_,readerCount_,readerWait_){this.$val=this;if(arguments.length===0){this.w=new Z.ptr(0,0);this.writerSem=0;this.readerSem=0;this.readerCount=0;this.readerWait=0;return;}this.w=w_;this.writerSem=writerSem_;this.readerSem=readerSem_;this.readerCount=readerCount_;this.readerWait=readerWait_;});AW=$pkg.rlocker=$newType(0,$kindStruct,\"sync.rlocker\",true,\"sync\",false,function(w_,writerSem_,readerSem_,readerCount_,readerWait_){this.$val=this;if(arguments.length===0){this.w=new Z.ptr(0,0);this.writerSem=0;this.readerSem=0;this.readerCount=0;this.readerWait=0;return;}this.w=w_;this.writerSem=writerSem_;this.readerSem=readerSem_;this.readerCount=readerCount_;this.readerWait=readerWait_;});AY=$ptrType(F);AZ=$sliceType(AY);BA=$ptrType($Uint32);BB=$chanType($Bool,false,false);BC=$sliceType(BB);BI=$ptrType($Int32);BL=$ptrType(AD);BM=$sliceType($emptyInterface);BN=$ptrType(AW);BO=$ptrType(AV);BR=$funcType([],[$emptyInterface],false);CA=$ptrType(Z);CB=$funcType([],[],false);CC=$ptrType(AB);CD=$arrayType($Uint8,100);F.ptr.prototype.Get=function(){var l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(l.store.$length===0){$s=1;continue;}$s=2;continue;case 1:if(!(l.New===$throwNilPointerError)){$s=3;continue;}$s=4;continue;case 3:m=l.New();$s=5;case 5:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}$s=-1;return m;case 4:$s=-1;return $ifaceNil;case 2:p=(n=l.store,o=l.store.$length-1>>0,((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]));l.store=$subslice(l.store,0,(l.store.$length-1>>0));$s=-1;return p;}return;}if($f===undefined){$f={$blk:F.ptr.prototype.Get};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};F.prototype.Get=function(){return this.$val.Get();};F.ptr.prototype.Put=function(l){var l,m;m=this;if($interfaceIsEqual(l,$ifaceNil)){return;}m.store=$append(m.store,l);};F.prototype.Put=function(l){return this.$val.Put(l);};G=function(l){var l;};K=function(l,m){var l,m,n,o,p,q,r,s,t,u,v,w,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(((l.$get()-(n=I[BA.keyFor(l)],n!==undefined?n.v:0)>>>0))===0){$s=1;continue;}$s=2;continue;case 1:o=new $Chan($Bool,0);if(m){p=l;(H||$throwRuntimeError(\"assignment to entry in nil map\"))[BA.keyFor(p)]={k:p,v:$appendSlice(new BC([o]),(q=H[BA.keyFor(l)],q!==undefined?q.v:BC.nil))};}else{r=l;(H||$throwRuntimeError(\"assignment to entry in nil map\"))[BA.keyFor(r)]={k:r,v:$append((s=H[BA.keyFor(l)],s!==undefined?s.v:BC.nil),o)};}t=$recv(o);$s=3;case 3:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}t[0];u=l;(I||$throwRuntimeError(\"assignment to entry in nil map\"))[BA.keyFor(u)]={k:u,v:(v=I[BA.keyFor(l)],v!==undefined?v.v:0)-(1)>>>0};if((w=I[BA.keyFor(l)],w!==undefined?w.v:0)===0){delete I[BA.keyFor(l)];}case 2:l.$set(l.$get()-(1)>>>0);$s=-1;return;}return;}if($f===undefined){$f={$blk:K};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.$s=$s;$f.$r=$r;return $f;};L=function(l,m){var l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l.$set(l.$get()+(1)>>>0);o=(n=H[BA.keyFor(l)],n!==undefined?n.v:BC.nil);if(o.$length===0){$s=-1;return;}p=(0>=o.$length?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+0]);o=$subslice(o,1);q=l;(H||$throwRuntimeError(\"assignment to entry in nil map\"))[BA.keyFor(q)]={k:q,v:o};if(o.$length===0){delete H[BA.keyFor(l)];}r=l;(I||$throwRuntimeError(\"assignment to entry in nil map\"))[BA.keyFor(r)]={k:r,v:(s=I[BA.keyFor(l)],s!==undefined?s.v:0)+(1)>>>0};$r=$send(p,true);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:L};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};M=function(l){var l;};N=function(l){var l;return false;};O=function(){return $mul64($internalize(new($global.Date)().getTime(),$Int64),new $Int64(0,1000000));};P=function(l){var l;$throwRuntimeError($externalize(l,$String));};Z.ptr.prototype.Lock=function(){var l,m,n,o,p,q,r,s,t,u,v,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(B.CompareAndSwapInt32((l.$ptr_state||(l.$ptr_state=new BI(function(){return this.$target.state;},function($v){this.$target.state=$v;},l))),0,1)){if(false){C.Acquire((l));}$s=-1;return;}m=new $Int64(0,0);n=false;o=false;p=0;q=l.state;case 1:if(((q&5)===1)&&N(p)){$s=3;continue;}$s=4;continue;case 3:if(!o&&((q&2)===0)&&!(((q>>3>>0)===0))&&B.CompareAndSwapInt32((l.$ptr_state||(l.$ptr_state=new BI(function(){return this.$target.state;},function($v){this.$target.state=$v;},l))),q,q|2)){o=true;}AU();p=p+(1)>>0;q=l.state;$s=1;continue;case 4:r=q;if((q&4)===0){r=r|(1);}if(!(((q&5)===0))){r=r+(8)>>0;}if(n&&!(((q&1)===0))){r=r|(4);}if(o){if((r&2)===0){P(\"sync: inconsistent mutex state\");}r=(r&~(2))>>0;}if(B.CompareAndSwapInt32((l.$ptr_state||(l.$ptr_state=new BI(function(){return this.$target.state;},function($v){this.$target.state=$v;},l))),q,r)){$s=5;continue;}$s=6;continue;case 5:if((q&5)===0){$s=2;continue;}s=!((m.$high===0&&m.$low===0));if((m.$high===0&&m.$low===0)){m=O();}$r=K((l.$ptr_sema||(l.$ptr_sema=new BA(function(){return this.$target.sema;},function($v){this.$target.sema=$v;},l))),s);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}n=n||(t=(u=O(),new $Int64(u.$high-m.$high,u.$low-m.$low)),(t.$high>0||(t.$high===0&&t.$low>1000000)));q=l.state;if(!(((q&4)===0))){if(!(((q&3)===0))||((q>>3>>0)===0)){P(\"sync: inconsistent mutex state\");}v=-7;if(!n||((q>>3>>0)===1)){v=v-(4)>>0;}B.AddInt32((l.$ptr_state||(l.$ptr_state=new BI(function(){return this.$target.state;},function($v){this.$target.state=$v;},l))),v);$s=2;continue;}o=true;p=0;$s=7;continue;case 6:q=l.state;case 7:$s=1;continue;case 2:if(false){C.Acquire((l));}$s=-1;return;}return;}if($f===undefined){$f={$blk:Z.ptr.prototype.Lock};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.$s=$s;$f.$r=$r;return $f;};Z.prototype.Lock=function(){return this.$val.Lock();};Z.ptr.prototype.Unlock=function(){var l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(false){$unused(l.state);C.Release((l));}m=B.AddInt32((l.$ptr_state||(l.$ptr_state=new BI(function(){return this.$target.state;},function($v){this.$target.state=$v;},l))),-1);if((((m+1>>0))&1)===0){P(\"sync: unlock of unlocked mutex\");}if((m&4)===0){$s=1;continue;}$s=2;continue;case 1:n=m;case 4:if(((n>>3>>0)===0)||!(((n&7)===0))){$s=-1;return;}m=((n-8>>0))|2;if(B.CompareAndSwapInt32((l.$ptr_state||(l.$ptr_state=new BI(function(){return this.$target.state;},function($v){this.$target.state=$v;},l))),n,m)){$s=6;continue;}$s=7;continue;case 6:$r=L((l.$ptr_sema||(l.$ptr_sema=new BA(function(){return this.$target.sema;},function($v){this.$target.sema=$v;},l))),false);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 7:n=l.state;$s=4;continue;case 5:$s=3;continue;case 2:$r=L((l.$ptr_sema||(l.$ptr_sema=new BA(function(){return this.$target.sema;},function($v){this.$target.sema=$v;},l))),true);$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 3:$s=-1;return;}return;}if($f===undefined){$f={$blk:Z.ptr.prototype.Unlock};}$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};Z.prototype.Unlock=function(){return this.$val.Unlock();};AB.ptr.prototype.Do=function(l){var l,m,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);m=this;if(B.LoadUint32((m.$ptr_done||(m.$ptr_done=new BA(function(){return this.$target.done;},function($v){this.$target.done=$v;},m))))===1){$s=-1;return;}$r=m.m.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(m.m,\"Unlock\"),[]]);if(m.done===0){$s=2;continue;}$s=3;continue;case 2:$deferred.push([B.StoreUint32,[(m.$ptr_done||(m.$ptr_done=new BA(function(){return this.$target.done;},function($v){this.$target.done=$v;},m))),1]]);$r=l();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 3:$s=-1;return;}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AB.ptr.prototype.Do};}$f.l=l;$f.m=m;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AB.prototype.Do=function(l){return this.$val.Do(l);};AH=function(){var l,m,n,o,p,q,r,s,t,u;l=AJ;m=0;while(true){if(!(m<l.$length)){break;}n=m;o=((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m]);((n<0||n>=AJ.$length)?($throwRuntimeError(\"index out of range\"),undefined):AJ.$array[AJ.$offset+n]=AY.nil);p=0;while(true){if(!(p<((o.localSize>>0)))){break;}q=AL(o.local,p);q.poolLocalInternal.private$0=$ifaceNil;r=q.poolLocalInternal.shared;s=0;while(true){if(!(s<r.$length)){break;}t=s;(u=q.poolLocalInternal.shared,((t<0||t>=u.$length)?($throwRuntimeError(\"index out of range\"),undefined):u.$array[u.$offset+t]=$ifaceNil));s++;}q.poolLocalInternal.shared=BM.nil;p=p+(1)>>0;}o.local=0;o.localSize=0;m++;}AJ=new AZ([]);};AK=function(){G(AH);};AL=function(l,m){var l,m,n;n=(((l)+($imul(((m>>>0)),128)>>>0)>>>0));return($pointerOfStructConversion(n,BL));};AT=function(){var l;l=new AO.ptr(0,0,0,0,0);M(20);};AU=function(){$throwRuntimeError(\"native function not implemented: sync.runtime_doSpin\");};AV.ptr.prototype.RLock=function(){var l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(false){$unused(l.w.state);C.Disable();}if(B.AddInt32((l.$ptr_readerCount||(l.$ptr_readerCount=new BI(function(){return this.$target.readerCount;},function($v){this.$target.readerCount=$v;},l))),1)<0){$s=1;continue;}$s=2;continue;case 1:$r=K((l.$ptr_readerSem||(l.$ptr_readerSem=new BA(function(){return this.$target.readerSem;},function($v){this.$target.readerSem=$v;},l))),false);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:if(false){C.Enable();C.Acquire(((l.$ptr_readerSem||(l.$ptr_readerSem=new BA(function(){return this.$target.readerSem;},function($v){this.$target.readerSem=$v;},l)))));}$s=-1;return;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.RLock};}$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.RLock=function(){return this.$val.RLock();};AV.ptr.prototype.RUnlock=function(){var l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(false){$unused(l.w.state);C.ReleaseMerge(((l.$ptr_writerSem||(l.$ptr_writerSem=new BA(function(){return this.$target.writerSem;},function($v){this.$target.writerSem=$v;},l)))));C.Disable();}m=B.AddInt32((l.$ptr_readerCount||(l.$ptr_readerCount=new BI(function(){return this.$target.readerCount;},function($v){this.$target.readerCount=$v;},l))),-1);if(m<0){$s=1;continue;}$s=2;continue;case 1:if(((m+1>>0)===0)||((m+1>>0)===-1073741824)){C.Enable();P(\"sync: RUnlock of unlocked RWMutex\");}if(B.AddInt32((l.$ptr_readerWait||(l.$ptr_readerWait=new BI(function(){return this.$target.readerWait;},function($v){this.$target.readerWait=$v;},l))),-1)===0){$s=3;continue;}$s=4;continue;case 3:$r=L((l.$ptr_writerSem||(l.$ptr_writerSem=new BA(function(){return this.$target.writerSem;},function($v){this.$target.writerSem=$v;},l))),false);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 4:case 2:if(false){C.Enable();}$s=-1;return;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.RUnlock};}$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.RUnlock=function(){return this.$val.RUnlock();};AV.ptr.prototype.Lock=function(){var l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(false){$unused(l.w.state);C.Disable();}$r=l.w.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}m=B.AddInt32((l.$ptr_readerCount||(l.$ptr_readerCount=new BI(function(){return this.$target.readerCount;},function($v){this.$target.readerCount=$v;},l))),-1073741824)+1073741824>>0;if(!((m===0))&&!((B.AddInt32((l.$ptr_readerWait||(l.$ptr_readerWait=new BI(function(){return this.$target.readerWait;},function($v){this.$target.readerWait=$v;},l))),m)===0))){$s=2;continue;}$s=3;continue;case 2:$r=K((l.$ptr_writerSem||(l.$ptr_writerSem=new BA(function(){return this.$target.writerSem;},function($v){this.$target.writerSem=$v;},l))),false);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 3:if(false){C.Enable();C.Acquire(((l.$ptr_readerSem||(l.$ptr_readerSem=new BA(function(){return this.$target.readerSem;},function($v){this.$target.readerSem=$v;},l)))));C.Acquire(((l.$ptr_writerSem||(l.$ptr_writerSem=new BA(function(){return this.$target.writerSem;},function($v){this.$target.writerSem=$v;},l)))));}$s=-1;return;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.Lock};}$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.Lock=function(){return this.$val.Lock();};AV.ptr.prototype.Unlock=function(){var l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(false){$unused(l.w.state);C.Release(((l.$ptr_readerSem||(l.$ptr_readerSem=new BA(function(){return this.$target.readerSem;},function($v){this.$target.readerSem=$v;},l)))));C.Disable();}m=B.AddInt32((l.$ptr_readerCount||(l.$ptr_readerCount=new BI(function(){return this.$target.readerCount;},function($v){this.$target.readerCount=$v;},l))),1073741824);if(m>=1073741824){C.Enable();P(\"sync: Unlock of unlocked RWMutex\");}n=0;case 1:if(!(n<((m>>0)))){$s=2;continue;}$r=L((l.$ptr_readerSem||(l.$ptr_readerSem=new BA(function(){return this.$target.readerSem;},function($v){this.$target.readerSem=$v;},l))),false);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}n=n+(1)>>0;$s=1;continue;case 2:$r=l.w.Unlock();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(false){C.Enable();}$s=-1;return;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.Unlock};}$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.Unlock=function(){return this.$val.Unlock();};AV.ptr.prototype.RLocker=function(){var l;l=this;return($pointerOfStructConversion(l,BN));};AV.prototype.RLocker=function(){return this.$val.RLocker();};AW.ptr.prototype.Lock=function(){var l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;$r=($pointerOfStructConversion(l,BO)).RLock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AW.ptr.prototype.Lock};}$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AW.prototype.Lock=function(){return this.$val.Lock();};AW.ptr.prototype.Unlock=function(){var l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;$r=($pointerOfStructConversion(l,BO)).RUnlock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AW.ptr.prototype.Unlock};}$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AW.prototype.Unlock=function(){return this.$val.Unlock();};AY.methods=[{prop:\"Get\",name:\"Get\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)},{prop:\"Put\",name:\"Put\",pkg:\"\",typ:$funcType([$emptyInterface],[],false)},{prop:\"getSlow\",name:\"getSlow\",pkg:\"sync\",typ:$funcType([],[$emptyInterface],false)},{prop:\"pin\",name:\"pin\",pkg:\"sync\",typ:$funcType([],[BL],false)},{prop:\"pinSlow\",name:\"pinSlow\",pkg:\"sync\",typ:$funcType([],[BL],false)}];CA.methods=[{prop:\"Lock\",name:\"Lock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Unlock\",name:\"Unlock\",pkg:\"\",typ:$funcType([],[],false)}];CC.methods=[{prop:\"Do\",name:\"Do\",pkg:\"\",typ:$funcType([CB],[],false)}];BO.methods=[{prop:\"RLock\",name:\"RLock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"RUnlock\",name:\"RUnlock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Lock\",name:\"Lock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Unlock\",name:\"Unlock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"RLocker\",name:\"RLocker\",pkg:\"\",typ:$funcType([],[AA],false)}];BN.methods=[{prop:\"Lock\",name:\"Lock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Unlock\",name:\"Unlock\",pkg:\"\",typ:$funcType([],[],false)}];F.init(\"sync\",[{prop:\"local\",name:\"local\",embedded:false,exported:false,typ:$UnsafePointer,tag:\"\"},{prop:\"localSize\",name:\"localSize\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"},{prop:\"store\",name:\"store\",embedded:false,exported:false,typ:BM,tag:\"\"},{prop:\"New\",name:\"New\",embedded:false,exported:true,typ:BR,tag:\"\"}]);Z.init(\"sync\",[{prop:\"state\",name:\"state\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"sema\",name:\"sema\",embedded:false,exported:false,typ:$Uint32,tag:\"\"}]);AA.init([{prop:\"Lock\",name:\"Lock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Unlock\",name:\"Unlock\",pkg:\"\",typ:$funcType([],[],false)}]);AB.init(\"sync\",[{prop:\"m\",name:\"m\",embedded:false,exported:false,typ:Z,tag:\"\"},{prop:\"done\",name:\"done\",embedded:false,exported:false,typ:$Uint32,tag:\"\"}]);AC.init(\"sync\",[{prop:\"private$0\",name:\"private\",embedded:false,exported:false,typ:$emptyInterface,tag:\"\"},{prop:\"shared\",name:\"shared\",embedded:false,exported:false,typ:BM,tag:\"\"},{prop:\"Mutex\",name:\"Mutex\",embedded:true,exported:true,typ:Z,tag:\"\"}]);AD.init(\"sync\",[{prop:\"poolLocalInternal\",name:\"poolLocalInternal\",embedded:true,exported:false,typ:AC,tag:\"\"},{prop:\"pad\",name:\"pad\",embedded:false,exported:false,typ:CD,tag:\"\"}]);AO.init(\"sync\",[{prop:\"wait\",name:\"wait\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"notify\",name:\"notify\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"lock\",name:\"lock\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"},{prop:\"head\",name:\"head\",embedded:false,exported:false,typ:$UnsafePointer,tag:\"\"},{prop:\"tail\",name:\"tail\",embedded:false,exported:false,typ:$UnsafePointer,tag:\"\"}]);AV.init(\"sync\",[{prop:\"w\",name:\"w\",embedded:false,exported:false,typ:Z,tag:\"\"},{prop:\"writerSem\",name:\"writerSem\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"readerSem\",name:\"readerSem\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"readerCount\",name:\"readerCount\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"readerWait\",name:\"readerWait\",embedded:false,exported:false,typ:$Int32,tag:\"\"}]);AW.init(\"sync\",[{prop:\"w\",name:\"w\",embedded:false,exported:false,typ:Z,tag:\"\"},{prop:\"writerSem\",name:\"writerSem\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"readerSem\",name:\"readerSem\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"readerCount\",name:\"readerCount\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"readerWait\",name:\"readerWait\",embedded:false,exported:false,typ:$Int32,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}AJ=AZ.nil;H={};I={};W=(new Uint8Array(8));AK();AT();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"unicode\"]=(function(){var $pkg={},$init,O,P,Q,R,T,AF,IX,IY,IZ,JA,JB,JC,JD,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV,CW,CX,CY,CZ,DA,DB,DC,DD,DE,DF,DG,DH,DI,DJ,DK,DL,DM,DN,DO,DP,DQ,DR,DS,DT,DU,DV,DW,DX,DY,DZ,EA,EB,EC,ED,EE,EF,EG,EH,EI,EJ,EK,EL,EM,EN,EO,EP,EQ,ER,ES,ET,EU,EV,EW,EX,EY,EZ,FA,FB,FC,FD,FE,FF,FG,FH,FI,FJ,FK,FL,FM,FN,FO,FP,FQ,FR,FS,FT,FU,FV,FW,FX,FY,FZ,GA,GB,GC,GD,GE,GF,GG,GH,GI,GJ,GK,GL,GM,GN,GO,GP,GQ,GR,GS,GT,GU,GV,GW,GX,GY,GZ,HA,HB,IK,IL,IM,IN,IO,IP,IQ,IR,IS,IT,IU,IV,IW,A,C,E,G,I,U,V,W,X,AB,AC,AD,AG;O=$pkg.RangeTable=$newType(0,$kindStruct,\"unicode.RangeTable\",true,\"unicode\",true,function(R16_,R32_,LatinOffset_){this.$val=this;if(arguments.length===0){this.R16=IY.nil;this.R32=IZ.nil;this.LatinOffset=0;return;}this.R16=R16_;this.R32=R32_;this.LatinOffset=LatinOffset_;});P=$pkg.Range16=$newType(0,$kindStruct,\"unicode.Range16\",true,\"unicode\",true,function(Lo_,Hi_,Stride_){this.$val=this;if(arguments.length===0){this.Lo=0;this.Hi=0;this.Stride=0;return;}this.Lo=Lo_;this.Hi=Hi_;this.Stride=Stride_;});Q=$pkg.Range32=$newType(0,$kindStruct,\"unicode.Range32\",true,\"unicode\",true,function(Lo_,Hi_,Stride_){this.$val=this;if(arguments.length===0){this.Lo=0;this.Hi=0;this.Stride=0;return;}this.Lo=Lo_;this.Hi=Hi_;this.Stride=Stride_;});R=$pkg.CaseRange=$newType(0,$kindStruct,\"unicode.CaseRange\",true,\"unicode\",true,function(Lo_,Hi_,Delta_){this.$val=this;if(arguments.length===0){this.Lo=0;this.Hi=0;this.Delta=IX.zero();return;}this.Lo=Lo_;this.Hi=Hi_;this.Delta=Delta_;});T=$pkg.d=$newType(12,$kindArray,\"unicode.d\",true,\"unicode\",false,null);AF=$pkg.foldPair=$newType(0,$kindStruct,\"unicode.foldPair\",true,\"unicode\",false,function(From_,To_){this.$val=this;if(arguments.length===0){this.From=0;this.To=0;return;}this.From=From_;this.To=To_;});IX=$arrayType($Int32,3);IY=$sliceType(P);IZ=$sliceType(Q);JA=$ptrType(O);JB=$sliceType(JA);JC=$sliceType(R);JD=$sliceType(AF);A=function(b,c,d){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;e=0;f=false;if(b<0||3<=b){g=65533;h=false;e=g;f=h;return[e,f];}i=0;j=d.$length;while(true){if(!(i<j)){break;}l=i+(k=((j-i>>0))/2,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;m=((l<0||l>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+l]);if(((m.Lo>>0))<=c&&c<=((m.Hi>>0))){o=((n=m.Delta,((b<0||b>=n.length)?($throwRuntimeError(\"index out of range\"),undefined):n[b])));if(o>1114111){p=((m.Lo>>0))+((((((c-((m.Lo>>0))>>0))&~1)>>0)|(((b&1)>>0))))>>0;q=true;e=p;f=q;return[e,f];}r=c+o>>0;s=true;e=r;f=s;return[e,f];}if(c<((m.Lo>>0))){j=l;}else{i=l+1>>0;}}t=c;u=false;e=t;f=u;return[e,f];};C=function(b){var b;if(b<=255){return 48<=b&&b<=57;}return X($pkg.Digit,b);};$pkg.IsDigit=C;E=function(b){var b,c;if(((b>>>0))<=255){return!(((((c=((b<<24>>>24)),((c<0||c>=IL.length)?($throwRuntimeError(\"index out of range\"),undefined):IL[c]))&128)>>>0)===0));}return G(b,$pkg.PrintRanges);};$pkg.IsPrint=E;G=function(b,c){var b,c,d,e,f;d=c;e=0;while(true){if(!(e<d.$length)){break;}f=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);if(W(f,b)){return true;}e++;}return false;};$pkg.In=G;I=function(b){var b,c;if(((b>>>0))<=255){return!(((((c=((b<<24>>>24)),((c<0||c>=IL.length)?($throwRuntimeError(\"index out of range\"),undefined):IL[c]))&96)>>>0)===0));}return X($pkg.Letter,b);};$pkg.IsLetter=I;U=function(b,c){var b,c,d,e,f,g,h,i,j,k,l,m,n;if(b.$length<=18||c<=255){d=b;e=0;while(true){if(!(e<d.$length)){break;}f=e;g=((f<0||f>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+f]);if(c<g.Lo){return false;}if(c<=g.Hi){return(g.Stride===1)||((h=((c-g.Lo<<16>>>16))%g.Stride,h===h?h:$throwRuntimeError(\"integer divide by zero\"))===0);}e++;}return false;}i=0;j=b.$length;while(true){if(!(i<j)){break;}l=i+(k=((j-i>>0))/2,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;m=((l<0||l>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+l]);if(m.Lo<=c&&c<=m.Hi){return(m.Stride===1)||((n=((c-m.Lo<<16>>>16))%m.Stride,n===n?n:$throwRuntimeError(\"integer divide by zero\"))===0);}if(c<m.Lo){j=l;}else{i=l+1>>0;}}return false;};V=function(b,c){var b,c,d,e,f,g,h,i,j,k,l,m,n;if(b.$length<=18){d=b;e=0;while(true){if(!(e<d.$length)){break;}f=e;g=((f<0||f>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+f]);if(c<g.Lo){return false;}if(c<=g.Hi){return(g.Stride===1)||((h=((c-g.Lo>>>0))%g.Stride,h===h?h:$throwRuntimeError(\"integer divide by zero\"))===0);}e++;}return false;}i=0;j=b.$length;while(true){if(!(i<j)){break;}l=i+(k=((j-i>>0))/2,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;m=$clone(((l<0||l>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+l]),Q);if(m.Lo<=c&&c<=m.Hi){return(m.Stride===1)||((n=((c-m.Lo>>>0))%m.Stride,n===n?n:$throwRuntimeError(\"integer divide by zero\"))===0);}if(c<m.Lo){j=l;}else{i=l+1>>0;}}return false;};W=function(b,c){var b,c,d,e,f;d=b.R16;if(d.$length>0&&c<=(((e=d.$length-1>>0,((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e])).Hi>>0))){return U(d,((c<<16>>>16)));}f=b.R32;if(f.$length>0&&c>=(((0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0]).Lo>>0))){return V(f,((c>>>0)));}return false;};$pkg.Is=W;X=function(b,c){var b,c,d,e,f,g;d=b.R16;e=b.LatinOffset;if(d.$length>e&&c<=(((f=d.$length-1>>0,((f<0||f>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+f])).Hi>>0))){return U($subslice(d,e),((c<<16>>>16)));}g=b.R32;if(g.$length>0&&c>=(((0>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+0]).Lo>>0))){return V(g,((c>>>0)));}return false;};AB=function(b,c){var b,c,d;d=A(b,c,$pkg.CaseRanges);c=d[0];return c;};$pkg.To=AB;AC=function(b){var b;if(b<=127){if(97<=b&&b<=122){b=b-(32)>>0;}return b;}return AB(0,b);};$pkg.ToUpper=AC;AD=function(b){var b;if(b<=127){if(65<=b&&b<=90){b=b+(32)>>0;}return b;}return AB(1,b);};$pkg.ToLower=AD;AG=function(b){var b,c,d,e,f,g;if(b<0||b>1114111){return b;}if(((b>>0))<128){return((((b<0||b>=IM.length)?($throwRuntimeError(\"index out of range\"),undefined):IM[b])>>0));}c=0;d=IN.$length;while(true){if(!(c<d)){break;}f=c+(e=((d-c>>0))/2,(e===e&&e!==1/0&&e!==-1/0)?e>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;if(((((f<0||f>=IN.$length)?($throwRuntimeError(\"index out of range\"),undefined):IN.$array[IN.$offset+f]).From>>0))<b){c=f+1>>0;}else{d=f;}}if(c<IN.$length&&(((((c<0||c>=IN.$length)?($throwRuntimeError(\"index out of range\"),undefined):IN.$array[IN.$offset+c]).From>>0))===b)){return((((c<0||c>=IN.$length)?($throwRuntimeError(\"index out of range\"),undefined):IN.$array[IN.$offset+c]).To>>0));}g=AD(b);if(!((g===b))){return g;}return AC(b);};$pkg.SimpleFold=AG;O.init(\"\",[{prop:\"R16\",name:\"R16\",embedded:false,exported:true,typ:IY,tag:\"\"},{prop:\"R32\",name:\"R32\",embedded:false,exported:true,typ:IZ,tag:\"\"},{prop:\"LatinOffset\",name:\"LatinOffset\",embedded:false,exported:true,typ:$Int,tag:\"\"}]);P.init(\"\",[{prop:\"Lo\",name:\"Lo\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Hi\",name:\"Hi\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Stride\",name:\"Stride\",embedded:false,exported:true,typ:$Uint16,tag:\"\"}]);Q.init(\"\",[{prop:\"Lo\",name:\"Lo\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Hi\",name:\"Hi\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Stride\",name:\"Stride\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);R.init(\"\",[{prop:\"Lo\",name:\"Lo\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Hi\",name:\"Hi\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Delta\",name:\"Delta\",embedded:false,exported:true,typ:T,tag:\"\"}]);T.init($Int32,3);AF.init(\"\",[{prop:\"From\",name:\"From\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"To\",name:\"To\",embedded:false,exported:true,typ:$Uint16,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:AH=new O.ptr(new IY([new P.ptr(0,31,1),new P.ptr(127,159,1),new P.ptr(173,1536,1363),new P.ptr(1537,1541,1),new P.ptr(1564,1757,193),new P.ptr(1807,2274,467),new P.ptr(6158,8203,2045),new P.ptr(8204,8207,1),new P.ptr(8234,8238,1),new P.ptr(8288,8292,1),new P.ptr(8294,8303,1),new P.ptr(55296,63743,1),new P.ptr(65279,65529,250),new P.ptr(65530,65531,1)]),new IZ([new Q.ptr(69821,113824,44003),new Q.ptr(113825,113827,1),new Q.ptr(119155,119162,1),new Q.ptr(917505,917536,31),new Q.ptr(917537,917631,1),new Q.ptr(983040,1048573,1),new Q.ptr(1048576,1114109,1)]),2);AI=new O.ptr(new IY([new P.ptr(0,31,1),new P.ptr(127,159,1)]),IZ.nil,2);AJ=new O.ptr(new IY([new P.ptr(173,1536,1363),new P.ptr(1537,1541,1),new P.ptr(1564,1757,193),new P.ptr(1807,2274,467),new P.ptr(6158,8203,2045),new P.ptr(8204,8207,1),new P.ptr(8234,8238,1),new P.ptr(8288,8292,1),new P.ptr(8294,8303,1),new P.ptr(65279,65529,250),new P.ptr(65530,65531,1)]),new IZ([new Q.ptr(69821,113824,44003),new Q.ptr(113825,113827,1),new Q.ptr(119155,119162,1),new Q.ptr(917505,917536,31),new Q.ptr(917537,917631,1)]),0);AK=new O.ptr(new IY([new P.ptr(57344,63743,1)]),new IZ([new Q.ptr(983040,1048573,1),new Q.ptr(1048576,1114109,1)]),0);AL=new O.ptr(new IY([new P.ptr(55296,57343,1)]),IZ.nil,0);AM=new O.ptr(new IY([new P.ptr(65,90,1),new P.ptr(97,122,1),new P.ptr(170,181,11),new P.ptr(186,192,6),new P.ptr(193,214,1),new P.ptr(216,246,1),new P.ptr(248,705,1),new P.ptr(710,721,1),new P.ptr(736,740,1),new P.ptr(748,750,2),new P.ptr(880,884,1),new P.ptr(886,887,1),new P.ptr(890,893,1),new P.ptr(895,902,7),new P.ptr(904,906,1),new P.ptr(908,910,2),new P.ptr(911,929,1),new P.ptr(931,1013,1),new P.ptr(1015,1153,1),new P.ptr(1162,1327,1),new P.ptr(1329,1366,1),new P.ptr(1369,1377,8),new P.ptr(1378,1415,1),new P.ptr(1488,1514,1),new P.ptr(1520,1522,1),new P.ptr(1568,1610,1),new P.ptr(1646,1647,1),new P.ptr(1649,1747,1),new P.ptr(1749,1765,16),new P.ptr(1766,1774,8),new P.ptr(1775,1786,11),new P.ptr(1787,1788,1),new P.ptr(1791,1808,17),new P.ptr(1810,1839,1),new P.ptr(1869,1957,1),new P.ptr(1969,1994,25),new P.ptr(1995,2026,1),new P.ptr(2036,2037,1),new P.ptr(2042,2048,6),new P.ptr(2049,2069,1),new P.ptr(2074,2084,10),new P.ptr(2088,2112,24),new P.ptr(2113,2136,1),new P.ptr(2144,2154,1),new P.ptr(2208,2228,1),new P.ptr(2230,2237,1),new P.ptr(2308,2361,1),new P.ptr(2365,2384,19),new P.ptr(2392,2401,1),new P.ptr(2417,2432,1),new P.ptr(2437,2444,1),new P.ptr(2447,2448,1),new P.ptr(2451,2472,1),new P.ptr(2474,2480,1),new P.ptr(2482,2486,4),new P.ptr(2487,2489,1),new P.ptr(2493,2510,17),new P.ptr(2524,2525,1),new P.ptr(2527,2529,1),new P.ptr(2544,2545,1),new P.ptr(2556,2565,9),new P.ptr(2566,2570,1),new P.ptr(2575,2576,1),new P.ptr(2579,2600,1),new P.ptr(2602,2608,1),new P.ptr(2610,2611,1),new P.ptr(2613,2614,1),new P.ptr(2616,2617,1),new P.ptr(2649,2652,1),new P.ptr(2654,2674,20),new P.ptr(2675,2676,1),new P.ptr(2693,2701,1),new P.ptr(2703,2705,1),new P.ptr(2707,2728,1),new P.ptr(2730,2736,1),new P.ptr(2738,2739,1),new P.ptr(2741,2745,1),new P.ptr(2749,2768,19),new P.ptr(2784,2785,1),new P.ptr(2809,2821,12),new P.ptr(2822,2828,1),new P.ptr(2831,2832,1),new P.ptr(2835,2856,1),new P.ptr(2858,2864,1),new P.ptr(2866,2867,1),new P.ptr(2869,2873,1),new P.ptr(2877,2908,31),new P.ptr(2909,2911,2),new P.ptr(2912,2913,1),new P.ptr(2929,2947,18),new P.ptr(2949,2954,1),new P.ptr(2958,2960,1),new P.ptr(2962,2965,1),new P.ptr(2969,2970,1),new P.ptr(2972,2974,2),new P.ptr(2975,2979,4),new P.ptr(2980,2984,4),new P.ptr(2985,2986,1),new P.ptr(2990,3001,1),new P.ptr(3024,3077,53),new P.ptr(3078,3084,1),new P.ptr(3086,3088,1),new P.ptr(3090,3112,1),new P.ptr(3114,3129,1),new P.ptr(3133,3160,27),new P.ptr(3161,3162,1),new P.ptr(3168,3169,1),new P.ptr(3200,3205,5),new P.ptr(3206,3212,1),new P.ptr(3214,3216,1),new P.ptr(3218,3240,1),new P.ptr(3242,3251,1),new P.ptr(3253,3257,1),new P.ptr(3261,3294,33),new P.ptr(3296,3297,1),new P.ptr(3313,3314,1),new P.ptr(3333,3340,1),new P.ptr(3342,3344,1),new P.ptr(3346,3386,1),new P.ptr(3389,3406,17),new P.ptr(3412,3414,1),new P.ptr(3423,3425,1),new P.ptr(3450,3455,1),new P.ptr(3461,3478,1),new P.ptr(3482,3505,1),new P.ptr(3507,3515,1),new P.ptr(3517,3520,3),new P.ptr(3521,3526,1),new P.ptr(3585,3632,1),new P.ptr(3634,3635,1),new P.ptr(3648,3654,1),new P.ptr(3713,3714,1),new P.ptr(3716,3719,3),new P.ptr(3720,3722,2),new P.ptr(3725,3732,7),new P.ptr(3733,3735,1),new P.ptr(3737,3743,1),new P.ptr(3745,3747,1),new P.ptr(3749,3751,2),new P.ptr(3754,3755,1),new P.ptr(3757,3760,1),new P.ptr(3762,3763,1),new P.ptr(3773,3776,3),new P.ptr(3777,3780,1),new P.ptr(3782,3804,22),new P.ptr(3805,3807,1),new P.ptr(3840,3904,64),new P.ptr(3905,3911,1),new P.ptr(3913,3948,1),new P.ptr(3976,3980,1),new P.ptr(4096,4138,1),new P.ptr(4159,4176,17),new P.ptr(4177,4181,1),new P.ptr(4186,4189,1),new P.ptr(4193,4197,4),new P.ptr(4198,4206,8),new P.ptr(4207,4208,1),new P.ptr(4213,4225,1),new P.ptr(4238,4256,18),new P.ptr(4257,4293,1),new P.ptr(4295,4301,6),new P.ptr(4304,4346,1),new P.ptr(4348,4680,1),new P.ptr(4682,4685,1),new P.ptr(4688,4694,1),new P.ptr(4696,4698,2),new P.ptr(4699,4701,1),new P.ptr(4704,4744,1),new P.ptr(4746,4749,1),new P.ptr(4752,4784,1),new P.ptr(4786,4789,1),new P.ptr(4792,4798,1),new P.ptr(4800,4802,2),new P.ptr(4803,4805,1),new P.ptr(4808,4822,1),new P.ptr(4824,4880,1),new P.ptr(4882,4885,1),new P.ptr(4888,4954,1),new P.ptr(4992,5007,1),new P.ptr(5024,5109,1),new P.ptr(5112,5117,1),new P.ptr(5121,5740,1),new P.ptr(5743,5759,1),new P.ptr(5761,5786,1),new P.ptr(5792,5866,1),new P.ptr(5873,5880,1),new P.ptr(5888,5900,1),new P.ptr(5902,5905,1),new P.ptr(5920,5937,1),new P.ptr(5952,5969,1),new P.ptr(5984,5996,1),new P.ptr(5998,6000,1),new P.ptr(6016,6067,1),new P.ptr(6103,6108,5),new P.ptr(6176,6263,1),new P.ptr(6272,6276,1),new P.ptr(6279,6312,1),new P.ptr(6314,6320,6),new P.ptr(6321,6389,1),new P.ptr(6400,6430,1),new P.ptr(6480,6509,1),new P.ptr(6512,6516,1),new P.ptr(6528,6571,1),new P.ptr(6576,6601,1),new P.ptr(6656,6678,1),new P.ptr(6688,6740,1),new P.ptr(6823,6917,94),new P.ptr(6918,6963,1),new P.ptr(6981,6987,1),new P.ptr(7043,7072,1),new P.ptr(7086,7087,1),new P.ptr(7098,7141,1),new P.ptr(7168,7203,1),new P.ptr(7245,7247,1),new P.ptr(7258,7293,1),new P.ptr(7296,7304,1),new P.ptr(7401,7404,1),new P.ptr(7406,7409,1),new P.ptr(7413,7414,1),new P.ptr(7424,7615,1),new P.ptr(7680,7957,1),new P.ptr(7960,7965,1),new P.ptr(7968,8005,1),new P.ptr(8008,8013,1),new P.ptr(8016,8023,1),new P.ptr(8025,8031,2),new P.ptr(8032,8061,1),new P.ptr(8064,8116,1),new P.ptr(8118,8124,1),new P.ptr(8126,8130,4),new P.ptr(8131,8132,1),new P.ptr(8134,8140,1),new P.ptr(8144,8147,1),new P.ptr(8150,8155,1),new P.ptr(8160,8172,1),new P.ptr(8178,8180,1),new P.ptr(8182,8188,1),new P.ptr(8305,8319,14),new P.ptr(8336,8348,1),new P.ptr(8450,8455,5),new P.ptr(8458,8467,1),new P.ptr(8469,8473,4),new P.ptr(8474,8477,1),new P.ptr(8484,8490,2),new P.ptr(8491,8493,1),new P.ptr(8495,8505,1),new P.ptr(8508,8511,1),new P.ptr(8517,8521,1),new P.ptr(8526,8579,53),new P.ptr(8580,11264,2684),new P.ptr(11265,11310,1),new P.ptr(11312,11358,1),new P.ptr(11360,11492,1),new P.ptr(11499,11502,1),new P.ptr(11506,11507,1),new P.ptr(11520,11557,1),new P.ptr(11559,11565,6),new P.ptr(11568,11623,1),new P.ptr(11631,11648,17),new P.ptr(11649,11670,1),new P.ptr(11680,11686,1),new P.ptr(11688,11694,1),new P.ptr(11696,11702,1),new P.ptr(11704,11710,1),new P.ptr(11712,11718,1),new P.ptr(11720,11726,1),new P.ptr(11728,11734,1),new P.ptr(11736,11742,1),new P.ptr(11823,12293,470),new P.ptr(12294,12337,43),new P.ptr(12338,12341,1),new P.ptr(12347,12348,1),new P.ptr(12353,12438,1),new P.ptr(12445,12447,1),new P.ptr(12449,12538,1),new P.ptr(12540,12543,1),new P.ptr(12549,12590,1),new P.ptr(12593,12686,1),new P.ptr(12704,12730,1),new P.ptr(12784,12799,1),new P.ptr(13312,19893,1),new P.ptr(19968,40938,1),new P.ptr(40960,42124,1),new P.ptr(42192,42237,1),new P.ptr(42240,42508,1),new P.ptr(42512,42527,1),new P.ptr(42538,42539,1),new P.ptr(42560,42606,1),new P.ptr(42623,42653,1),new P.ptr(42656,42725,1),new P.ptr(42775,42783,1),new P.ptr(42786,42888,1),new P.ptr(42891,42926,1),new P.ptr(42928,42935,1),new P.ptr(42999,43009,1),new P.ptr(43011,43013,1),new P.ptr(43015,43018,1),new P.ptr(43020,43042,1),new P.ptr(43072,43123,1),new P.ptr(43138,43187,1),new P.ptr(43250,43255,1),new P.ptr(43259,43261,2),new P.ptr(43274,43301,1),new P.ptr(43312,43334,1),new P.ptr(43360,43388,1),new P.ptr(43396,43442,1),new P.ptr(43471,43488,17),new P.ptr(43489,43492,1),new P.ptr(43494,43503,1),new P.ptr(43514,43518,1),new P.ptr(43520,43560,1),new P.ptr(43584,43586,1),new P.ptr(43588,43595,1),new P.ptr(43616,43638,1),new P.ptr(43642,43646,4),new P.ptr(43647,43695,1),new P.ptr(43697,43701,4),new P.ptr(43702,43705,3),new P.ptr(43706,43709,1),new P.ptr(43712,43714,2),new P.ptr(43739,43741,1),new P.ptr(43744,43754,1),new P.ptr(43762,43764,1),new P.ptr(43777,43782,1),new P.ptr(43785,43790,1),new P.ptr(43793,43798,1),new P.ptr(43808,43814,1),new P.ptr(43816,43822,1),new P.ptr(43824,43866,1),new P.ptr(43868,43877,1),new P.ptr(43888,44002,1),new P.ptr(44032,55203,1),new P.ptr(55216,55238,1),new P.ptr(55243,55291,1),new P.ptr(63744,64109,1),new P.ptr(64112,64217,1),new P.ptr(64256,64262,1),new P.ptr(64275,64279,1),new P.ptr(64285,64287,2),new P.ptr(64288,64296,1),new P.ptr(64298,64310,1),new P.ptr(64312,64316,1),new P.ptr(64318,64320,2),new P.ptr(64321,64323,2),new P.ptr(64324,64326,2),new P.ptr(64327,64433,1),new P.ptr(64467,64829,1),new P.ptr(64848,64911,1),new P.ptr(64914,64967,1),new P.ptr(65008,65019,1),new P.ptr(65136,65140,1),new P.ptr(65142,65276,1),new P.ptr(65313,65338,1),new P.ptr(65345,65370,1),new P.ptr(65382,65470,1),new P.ptr(65474,65479,1),new P.ptr(65482,65487,1),new P.ptr(65490,65495,1),new P.ptr(65498,65500,1)]),new IZ([new Q.ptr(65536,65547,1),new Q.ptr(65549,65574,1),new Q.ptr(65576,65594,1),new Q.ptr(65596,65597,1),new Q.ptr(65599,65613,1),new Q.ptr(65616,65629,1),new Q.ptr(65664,65786,1),new Q.ptr(66176,66204,1),new Q.ptr(66208,66256,1),new Q.ptr(66304,66335,1),new Q.ptr(66349,66368,1),new Q.ptr(66370,66377,1),new Q.ptr(66384,66421,1),new Q.ptr(66432,66461,1),new Q.ptr(66464,66499,1),new Q.ptr(66504,66511,1),new Q.ptr(66560,66717,1),new Q.ptr(66736,66771,1),new Q.ptr(66776,66811,1),new Q.ptr(66816,66855,1),new Q.ptr(66864,66915,1),new Q.ptr(67072,67382,1),new Q.ptr(67392,67413,1),new Q.ptr(67424,67431,1),new Q.ptr(67584,67589,1),new Q.ptr(67592,67594,2),new Q.ptr(67595,67637,1),new Q.ptr(67639,67640,1),new Q.ptr(67644,67647,3),new Q.ptr(67648,67669,1),new Q.ptr(67680,67702,1),new Q.ptr(67712,67742,1),new Q.ptr(67808,67826,1),new Q.ptr(67828,67829,1),new Q.ptr(67840,67861,1),new Q.ptr(67872,67897,1),new Q.ptr(67968,68023,1),new Q.ptr(68030,68031,1),new Q.ptr(68096,68112,16),new Q.ptr(68113,68115,1),new Q.ptr(68117,68119,1),new Q.ptr(68121,68147,1),new Q.ptr(68192,68220,1),new Q.ptr(68224,68252,1),new Q.ptr(68288,68295,1),new Q.ptr(68297,68324,1),new Q.ptr(68352,68405,1),new Q.ptr(68416,68437,1),new Q.ptr(68448,68466,1),new Q.ptr(68480,68497,1),new Q.ptr(68608,68680,1),new Q.ptr(68736,68786,1),new Q.ptr(68800,68850,1),new Q.ptr(69635,69687,1),new Q.ptr(69763,69807,1),new Q.ptr(69840,69864,1),new Q.ptr(69891,69926,1),new Q.ptr(69968,70002,1),new Q.ptr(70006,70019,13),new Q.ptr(70020,70066,1),new Q.ptr(70081,70084,1),new Q.ptr(70106,70108,2),new Q.ptr(70144,70161,1),new Q.ptr(70163,70187,1),new Q.ptr(70272,70278,1),new Q.ptr(70280,70282,2),new Q.ptr(70283,70285,1),new Q.ptr(70287,70301,1),new Q.ptr(70303,70312,1),new Q.ptr(70320,70366,1),new Q.ptr(70405,70412,1),new Q.ptr(70415,70416,1),new Q.ptr(70419,70440,1),new Q.ptr(70442,70448,1),new Q.ptr(70450,70451,1),new Q.ptr(70453,70457,1),new Q.ptr(70461,70480,19),new Q.ptr(70493,70497,1),new Q.ptr(70656,70708,1),new Q.ptr(70727,70730,1),new Q.ptr(70784,70831,1),new Q.ptr(70852,70853,1),new Q.ptr(70855,71040,185),new Q.ptr(71041,71086,1),new Q.ptr(71128,71131,1),new Q.ptr(71168,71215,1),new Q.ptr(71236,71296,60),new Q.ptr(71297,71338,1),new Q.ptr(71424,71449,1),new Q.ptr(71840,71903,1),new Q.ptr(71935,72192,257),new Q.ptr(72203,72242,1),new Q.ptr(72250,72272,22),new Q.ptr(72284,72323,1),new Q.ptr(72326,72329,1),new Q.ptr(72384,72440,1),new Q.ptr(72704,72712,1),new Q.ptr(72714,72750,1),new Q.ptr(72768,72818,50),new Q.ptr(72819,72847,1),new Q.ptr(72960,72966,1),new Q.ptr(72968,72969,1),new Q.ptr(72971,73008,1),new Q.ptr(73030,73728,698),new Q.ptr(73729,74649,1),new Q.ptr(74880,75075,1),new Q.ptr(77824,78894,1),new Q.ptr(82944,83526,1),new Q.ptr(92160,92728,1),new Q.ptr(92736,92766,1),new Q.ptr(92880,92909,1),new Q.ptr(92928,92975,1),new Q.ptr(92992,92995,1),new Q.ptr(93027,93047,1),new Q.ptr(93053,93071,1),new Q.ptr(93952,94020,1),new Q.ptr(94032,94099,67),new Q.ptr(94100,94111,1),new Q.ptr(94176,94177,1),new Q.ptr(94208,100332,1),new Q.ptr(100352,101106,1),new Q.ptr(110592,110878,1),new Q.ptr(110960,111355,1),new Q.ptr(113664,113770,1),new Q.ptr(113776,113788,1),new Q.ptr(113792,113800,1),new Q.ptr(113808,113817,1),new Q.ptr(119808,119892,1),new Q.ptr(119894,119964,1),new Q.ptr(119966,119967,1),new Q.ptr(119970,119973,3),new Q.ptr(119974,119977,3),new Q.ptr(119978,119980,1),new Q.ptr(119982,119993,1),new Q.ptr(119995,119997,2),new Q.ptr(119998,120003,1),new Q.ptr(120005,120069,1),new Q.ptr(120071,120074,1),new Q.ptr(120077,120084,1),new Q.ptr(120086,120092,1),new Q.ptr(120094,120121,1),new Q.ptr(120123,120126,1),new Q.ptr(120128,120132,1),new Q.ptr(120134,120138,4),new Q.ptr(120139,120144,1),new Q.ptr(120146,120485,1),new Q.ptr(120488,120512,1),new Q.ptr(120514,120538,1),new Q.ptr(120540,120570,1),new Q.ptr(120572,120596,1),new Q.ptr(120598,120628,1),new Q.ptr(120630,120654,1),new Q.ptr(120656,120686,1),new Q.ptr(120688,120712,1),new Q.ptr(120714,120744,1),new Q.ptr(120746,120770,1),new Q.ptr(120772,120779,1),new Q.ptr(124928,125124,1),new Q.ptr(125184,125251,1),new Q.ptr(126464,126467,1),new Q.ptr(126469,126495,1),new Q.ptr(126497,126498,1),new Q.ptr(126500,126503,3),new Q.ptr(126505,126514,1),new Q.ptr(126516,126519,1),new Q.ptr(126521,126523,2),new Q.ptr(126530,126535,5),new Q.ptr(126537,126541,2),new Q.ptr(126542,126543,1),new Q.ptr(126545,126546,1),new Q.ptr(126548,126551,3),new Q.ptr(126553,126561,2),new Q.ptr(126562,126564,2),new Q.ptr(126567,126570,1),new Q.ptr(126572,126578,1),new Q.ptr(126580,126583,1),new Q.ptr(126585,126588,1),new Q.ptr(126590,126592,2),new Q.ptr(126593,126601,1),new Q.ptr(126603,126619,1),new Q.ptr(126625,126627,1),new Q.ptr(126629,126633,1),new Q.ptr(126635,126651,1),new Q.ptr(131072,173782,1),new Q.ptr(173824,177972,1),new Q.ptr(177984,178205,1),new Q.ptr(178208,183969,1),new Q.ptr(183984,191456,1),new Q.ptr(194560,195101,1)]),6);AN=new O.ptr(new IY([new P.ptr(97,122,1),new P.ptr(181,223,42),new P.ptr(224,246,1),new P.ptr(248,255,1),new P.ptr(257,311,2),new P.ptr(312,328,2),new P.ptr(329,375,2),new P.ptr(378,382,2),new P.ptr(383,384,1),new P.ptr(387,389,2),new P.ptr(392,396,4),new P.ptr(397,402,5),new P.ptr(405,409,4),new P.ptr(410,411,1),new P.ptr(414,417,3),new P.ptr(419,421,2),new P.ptr(424,426,2),new P.ptr(427,429,2),new P.ptr(432,436,4),new P.ptr(438,441,3),new P.ptr(442,445,3),new P.ptr(446,447,1),new P.ptr(454,460,3),new P.ptr(462,476,2),new P.ptr(477,495,2),new P.ptr(496,499,3),new P.ptr(501,505,4),new P.ptr(507,563,2),new P.ptr(564,569,1),new P.ptr(572,575,3),new P.ptr(576,578,2),new P.ptr(583,591,2),new P.ptr(592,659,1),new P.ptr(661,687,1),new P.ptr(881,883,2),new P.ptr(887,891,4),new P.ptr(892,893,1),new P.ptr(912,940,28),new P.ptr(941,974,1),new P.ptr(976,977,1),new P.ptr(981,983,1),new P.ptr(985,1007,2),new P.ptr(1008,1011,1),new P.ptr(1013,1019,3),new P.ptr(1020,1072,52),new P.ptr(1073,1119,1),new P.ptr(1121,1153,2),new P.ptr(1163,1215,2),new P.ptr(1218,1230,2),new P.ptr(1231,1327,2),new P.ptr(1377,1415,1),new P.ptr(5112,5117,1),new P.ptr(7296,7304,1),new P.ptr(7424,7467,1),new P.ptr(7531,7543,1),new P.ptr(7545,7578,1),new P.ptr(7681,7829,2),new P.ptr(7830,7837,1),new P.ptr(7839,7935,2),new P.ptr(7936,7943,1),new P.ptr(7952,7957,1),new P.ptr(7968,7975,1),new P.ptr(7984,7991,1),new P.ptr(8000,8005,1),new P.ptr(8016,8023,1),new P.ptr(8032,8039,1),new P.ptr(8048,8061,1),new P.ptr(8064,8071,1),new P.ptr(8080,8087,1),new P.ptr(8096,8103,1),new P.ptr(8112,8116,1),new P.ptr(8118,8119,1),new P.ptr(8126,8130,4),new P.ptr(8131,8132,1),new P.ptr(8134,8135,1),new P.ptr(8144,8147,1),new P.ptr(8150,8151,1),new P.ptr(8160,8167,1),new P.ptr(8178,8180,1),new P.ptr(8182,8183,1),new P.ptr(8458,8462,4),new P.ptr(8463,8467,4),new P.ptr(8495,8505,5),new P.ptr(8508,8509,1),new P.ptr(8518,8521,1),new P.ptr(8526,8580,54),new P.ptr(11312,11358,1),new P.ptr(11361,11365,4),new P.ptr(11366,11372,2),new P.ptr(11377,11379,2),new P.ptr(11380,11382,2),new P.ptr(11383,11387,1),new P.ptr(11393,11491,2),new P.ptr(11492,11500,8),new P.ptr(11502,11507,5),new P.ptr(11520,11557,1),new P.ptr(11559,11565,6),new P.ptr(42561,42605,2),new P.ptr(42625,42651,2),new P.ptr(42787,42799,2),new P.ptr(42800,42801,1),new P.ptr(42803,42865,2),new P.ptr(42866,42872,1),new P.ptr(42874,42876,2),new P.ptr(42879,42887,2),new P.ptr(42892,42894,2),new P.ptr(42897,42899,2),new P.ptr(42900,42901,1),new P.ptr(42903,42921,2),new P.ptr(42933,42935,2),new P.ptr(43002,43824,822),new P.ptr(43825,43866,1),new P.ptr(43872,43877,1),new P.ptr(43888,43967,1),new P.ptr(64256,64262,1),new P.ptr(64275,64279,1),new P.ptr(65345,65370,1)]),new IZ([new Q.ptr(66600,66639,1),new Q.ptr(66776,66811,1),new Q.ptr(68800,68850,1),new Q.ptr(71872,71903,1),new Q.ptr(119834,119859,1),new Q.ptr(119886,119892,1),new Q.ptr(119894,119911,1),new Q.ptr(119938,119963,1),new Q.ptr(119990,119993,1),new Q.ptr(119995,119997,2),new Q.ptr(119998,120003,1),new Q.ptr(120005,120015,1),new Q.ptr(120042,120067,1),new Q.ptr(120094,120119,1),new Q.ptr(120146,120171,1),new Q.ptr(120198,120223,1),new Q.ptr(120250,120275,1),new Q.ptr(120302,120327,1),new Q.ptr(120354,120379,1),new Q.ptr(120406,120431,1),new Q.ptr(120458,120485,1),new Q.ptr(120514,120538,1),new Q.ptr(120540,120545,1),new Q.ptr(120572,120596,1),new Q.ptr(120598,120603,1),new Q.ptr(120630,120654,1),new Q.ptr(120656,120661,1),new Q.ptr(120688,120712,1),new Q.ptr(120714,120719,1),new Q.ptr(120746,120770,1),new Q.ptr(120772,120777,1),new Q.ptr(120779,125218,4439),new Q.ptr(125219,125251,1)]),4);AO=new O.ptr(new IY([new P.ptr(688,705,1),new P.ptr(710,721,1),new P.ptr(736,740,1),new P.ptr(748,750,2),new P.ptr(884,890,6),new P.ptr(1369,1600,231),new P.ptr(1765,1766,1),new P.ptr(2036,2037,1),new P.ptr(2042,2074,32),new P.ptr(2084,2088,4),new P.ptr(2417,3654,1237),new P.ptr(3782,4348,566),new P.ptr(6103,6211,108),new P.ptr(6823,7288,465),new P.ptr(7289,7293,1),new P.ptr(7468,7530,1),new P.ptr(7544,7579,35),new P.ptr(7580,7615,1),new P.ptr(8305,8319,14),new P.ptr(8336,8348,1),new P.ptr(11388,11389,1),new P.ptr(11631,11823,192),new P.ptr(12293,12337,44),new P.ptr(12338,12341,1),new P.ptr(12347,12445,98),new P.ptr(12446,12540,94),new P.ptr(12541,12542,1),new P.ptr(40981,42232,1251),new P.ptr(42233,42237,1),new P.ptr(42508,42623,115),new P.ptr(42652,42653,1),new P.ptr(42775,42783,1),new P.ptr(42864,42888,24),new P.ptr(43000,43001,1),new P.ptr(43471,43494,23),new P.ptr(43632,43741,109),new P.ptr(43763,43764,1),new P.ptr(43868,43871,1),new P.ptr(65392,65438,46),new P.ptr(65439,65439,1)]),new IZ([new Q.ptr(92992,92992,1),new Q.ptr(92993,92995,1),new Q.ptr(94099,94111,1),new Q.ptr(94176,94177,1)]),0);AP=new O.ptr(new IY([new P.ptr(170,186,16),new P.ptr(443,448,5),new P.ptr(449,451,1),new P.ptr(660,1488,828),new P.ptr(1489,1514,1),new P.ptr(1520,1522,1),new P.ptr(1568,1599,1),new P.ptr(1601,1610,1),new P.ptr(1646,1647,1),new P.ptr(1649,1747,1),new P.ptr(1749,1774,25),new P.ptr(1775,1786,11),new P.ptr(1787,1788,1),new P.ptr(1791,1808,17),new P.ptr(1810,1839,1),new P.ptr(1869,1957,1),new P.ptr(1969,1994,25),new P.ptr(1995,2026,1),new P.ptr(2048,2069,1),new P.ptr(2112,2136,1),new P.ptr(2144,2154,1),new P.ptr(2208,2228,1),new P.ptr(2230,2237,1),new P.ptr(2308,2361,1),new P.ptr(2365,2384,19),new P.ptr(2392,2401,1),new P.ptr(2418,2432,1),new P.ptr(2437,2444,1),new P.ptr(2447,2448,1),new P.ptr(2451,2472,1),new P.ptr(2474,2480,1),new P.ptr(2482,2486,4),new P.ptr(2487,2489,1),new P.ptr(2493,2510,17),new P.ptr(2524,2525,1),new P.ptr(2527,2529,1),new P.ptr(2544,2545,1),new P.ptr(2556,2565,9),new P.ptr(2566,2570,1),new P.ptr(2575,2576,1),new P.ptr(2579,2600,1),new P.ptr(2602,2608,1),new P.ptr(2610,2611,1),new P.ptr(2613,2614,1),new P.ptr(2616,2617,1),new P.ptr(2649,2652,1),new P.ptr(2654,2674,20),new P.ptr(2675,2676,1),new P.ptr(2693,2701,1),new P.ptr(2703,2705,1),new P.ptr(2707,2728,1),new P.ptr(2730,2736,1),new P.ptr(2738,2739,1),new P.ptr(2741,2745,1),new P.ptr(2749,2768,19),new P.ptr(2784,2785,1),new P.ptr(2809,2821,12),new P.ptr(2822,2828,1),new P.ptr(2831,2832,1),new P.ptr(2835,2856,1),new P.ptr(2858,2864,1),new P.ptr(2866,2867,1),new P.ptr(2869,2873,1),new P.ptr(2877,2908,31),new P.ptr(2909,2911,2),new P.ptr(2912,2913,1),new P.ptr(2929,2947,18),new P.ptr(2949,2954,1),new P.ptr(2958,2960,1),new P.ptr(2962,2965,1),new P.ptr(2969,2970,1),new P.ptr(2972,2974,2),new P.ptr(2975,2979,4),new P.ptr(2980,2984,4),new P.ptr(2985,2986,1),new P.ptr(2990,3001,1),new P.ptr(3024,3077,53),new P.ptr(3078,3084,1),new P.ptr(3086,3088,1),new P.ptr(3090,3112,1),new P.ptr(3114,3129,1),new P.ptr(3133,3160,27),new P.ptr(3161,3162,1),new P.ptr(3168,3169,1),new P.ptr(3200,3205,5),new P.ptr(3206,3212,1),new P.ptr(3214,3216,1),new P.ptr(3218,3240,1),new P.ptr(3242,3251,1),new P.ptr(3253,3257,1),new P.ptr(3261,3294,33),new P.ptr(3296,3297,1),new P.ptr(3313,3314,1),new P.ptr(3333,3340,1),new P.ptr(3342,3344,1),new P.ptr(3346,3386,1),new P.ptr(3389,3406,17),new P.ptr(3412,3414,1),new P.ptr(3423,3425,1),new P.ptr(3450,3455,1),new P.ptr(3461,3478,1),new P.ptr(3482,3505,1),new P.ptr(3507,3515,1),new P.ptr(3517,3520,3),new P.ptr(3521,3526,1),new P.ptr(3585,3632,1),new P.ptr(3634,3635,1),new P.ptr(3648,3653,1),new P.ptr(3713,3714,1),new P.ptr(3716,3719,3),new P.ptr(3720,3722,2),new P.ptr(3725,3732,7),new P.ptr(3733,3735,1),new P.ptr(3737,3743,1),new P.ptr(3745,3747,1),new P.ptr(3749,3751,2),new P.ptr(3754,3755,1),new P.ptr(3757,3760,1),new P.ptr(3762,3763,1),new P.ptr(3773,3776,3),new P.ptr(3777,3780,1),new P.ptr(3804,3807,1),new P.ptr(3840,3904,64),new P.ptr(3905,3911,1),new P.ptr(3913,3948,1),new P.ptr(3976,3980,1),new P.ptr(4096,4138,1),new P.ptr(4159,4176,17),new P.ptr(4177,4181,1),new P.ptr(4186,4189,1),new P.ptr(4193,4197,4),new P.ptr(4198,4206,8),new P.ptr(4207,4208,1),new P.ptr(4213,4225,1),new P.ptr(4238,4304,66),new P.ptr(4305,4346,1),new P.ptr(4349,4680,1),new P.ptr(4682,4685,1),new P.ptr(4688,4694,1),new P.ptr(4696,4698,2),new P.ptr(4699,4701,1),new P.ptr(4704,4744,1),new P.ptr(4746,4749,1),new P.ptr(4752,4784,1),new P.ptr(4786,4789,1),new P.ptr(4792,4798,1),new P.ptr(4800,4802,2),new P.ptr(4803,4805,1),new P.ptr(4808,4822,1),new P.ptr(4824,4880,1),new P.ptr(4882,4885,1),new P.ptr(4888,4954,1),new P.ptr(4992,5007,1),new P.ptr(5121,5740,1),new P.ptr(5743,5759,1),new P.ptr(5761,5786,1),new P.ptr(5792,5866,1),new P.ptr(5873,5880,1),new P.ptr(5888,5900,1),new P.ptr(5902,5905,1),new P.ptr(5920,5937,1),new P.ptr(5952,5969,1),new P.ptr(5984,5996,1),new P.ptr(5998,6000,1),new P.ptr(6016,6067,1),new P.ptr(6108,6176,68),new P.ptr(6177,6210,1),new P.ptr(6212,6263,1),new P.ptr(6272,6276,1),new P.ptr(6279,6312,1),new P.ptr(6314,6320,6),new P.ptr(6321,6389,1),new P.ptr(6400,6430,1),new P.ptr(6480,6509,1),new P.ptr(6512,6516,1),new P.ptr(6528,6571,1),new P.ptr(6576,6601,1),new P.ptr(6656,6678,1),new P.ptr(6688,6740,1),new P.ptr(6917,6963,1),new P.ptr(6981,6987,1),new P.ptr(7043,7072,1),new P.ptr(7086,7087,1),new P.ptr(7098,7141,1),new P.ptr(7168,7203,1),new P.ptr(7245,7247,1),new P.ptr(7258,7287,1),new P.ptr(7401,7404,1),new P.ptr(7406,7409,1),new P.ptr(7413,7414,1),new P.ptr(8501,8504,1),new P.ptr(11568,11623,1),new P.ptr(11648,11670,1),new P.ptr(11680,11686,1),new P.ptr(11688,11694,1),new P.ptr(11696,11702,1),new P.ptr(11704,11710,1),new P.ptr(11712,11718,1),new P.ptr(11720,11726,1),new P.ptr(11728,11734,1),new P.ptr(11736,11742,1),new P.ptr(12294,12348,54),new P.ptr(12353,12438,1),new P.ptr(12447,12449,2),new P.ptr(12450,12538,1),new P.ptr(12543,12549,6),new P.ptr(12550,12590,1),new P.ptr(12593,12686,1),new P.ptr(12704,12730,1),new P.ptr(12784,12799,1),new P.ptr(13312,19893,1),new P.ptr(19968,40938,1),new P.ptr(40960,40980,1),new P.ptr(40982,42124,1),new P.ptr(42192,42231,1),new P.ptr(42240,42507,1),new P.ptr(42512,42527,1),new P.ptr(42538,42539,1),new P.ptr(42606,42656,50),new P.ptr(42657,42725,1),new P.ptr(42895,42999,104),new P.ptr(43003,43009,1),new P.ptr(43011,43013,1),new P.ptr(43015,43018,1),new P.ptr(43020,43042,1),new P.ptr(43072,43123,1),new P.ptr(43138,43187,1),new P.ptr(43250,43255,1),new P.ptr(43259,43261,2),new P.ptr(43274,43301,1),new P.ptr(43312,43334,1),new P.ptr(43360,43388,1),new P.ptr(43396,43442,1),new P.ptr(43488,43492,1),new P.ptr(43495,43503,1),new P.ptr(43514,43518,1),new P.ptr(43520,43560,1),new P.ptr(43584,43586,1),new P.ptr(43588,43595,1),new P.ptr(43616,43631,1),new P.ptr(43633,43638,1),new P.ptr(43642,43646,4),new P.ptr(43647,43695,1),new P.ptr(43697,43701,4),new P.ptr(43702,43705,3),new P.ptr(43706,43709,1),new P.ptr(43712,43714,2),new P.ptr(43739,43740,1),new P.ptr(43744,43754,1),new P.ptr(43762,43777,15),new P.ptr(43778,43782,1),new P.ptr(43785,43790,1),new P.ptr(43793,43798,1),new P.ptr(43808,43814,1),new P.ptr(43816,43822,1),new P.ptr(43968,44002,1),new P.ptr(44032,55203,1),new P.ptr(55216,55238,1),new P.ptr(55243,55291,1),new P.ptr(63744,64109,1),new P.ptr(64112,64217,1),new P.ptr(64285,64287,2),new P.ptr(64288,64296,1),new P.ptr(64298,64310,1),new P.ptr(64312,64316,1),new P.ptr(64318,64320,2),new P.ptr(64321,64323,2),new P.ptr(64324,64326,2),new P.ptr(64327,64433,1),new P.ptr(64467,64829,1),new P.ptr(64848,64911,1),new P.ptr(64914,64967,1),new P.ptr(65008,65019,1),new P.ptr(65136,65140,1),new P.ptr(65142,65276,1),new P.ptr(65382,65391,1),new P.ptr(65393,65437,1),new P.ptr(65440,65470,1),new P.ptr(65474,65479,1),new P.ptr(65482,65487,1),new P.ptr(65490,65495,1),new P.ptr(65498,65500,1)]),new IZ([new Q.ptr(65536,65547,1),new Q.ptr(65549,65574,1),new Q.ptr(65576,65594,1),new Q.ptr(65596,65597,1),new Q.ptr(65599,65613,1),new Q.ptr(65616,65629,1),new Q.ptr(65664,65786,1),new Q.ptr(66176,66204,1),new Q.ptr(66208,66256,1),new Q.ptr(66304,66335,1),new Q.ptr(66349,66368,1),new Q.ptr(66370,66377,1),new Q.ptr(66384,66421,1),new Q.ptr(66432,66461,1),new Q.ptr(66464,66499,1),new Q.ptr(66504,66511,1),new Q.ptr(66640,66717,1),new Q.ptr(66816,66855,1),new Q.ptr(66864,66915,1),new Q.ptr(67072,67382,1),new Q.ptr(67392,67413,1),new Q.ptr(67424,67431,1),new Q.ptr(67584,67589,1),new Q.ptr(67592,67594,2),new Q.ptr(67595,67637,1),new Q.ptr(67639,67640,1),new Q.ptr(67644,67647,3),new Q.ptr(67648,67669,1),new Q.ptr(67680,67702,1),new Q.ptr(67712,67742,1),new Q.ptr(67808,67826,1),new Q.ptr(67828,67829,1),new Q.ptr(67840,67861,1),new Q.ptr(67872,67897,1),new Q.ptr(67968,68023,1),new Q.ptr(68030,68031,1),new Q.ptr(68096,68112,16),new Q.ptr(68113,68115,1),new Q.ptr(68117,68119,1),new Q.ptr(68121,68147,1),new Q.ptr(68192,68220,1),new Q.ptr(68224,68252,1),new Q.ptr(68288,68295,1),new Q.ptr(68297,68324,1),new Q.ptr(68352,68405,1),new Q.ptr(68416,68437,1),new Q.ptr(68448,68466,1),new Q.ptr(68480,68497,1),new Q.ptr(68608,68680,1),new Q.ptr(69635,69687,1),new Q.ptr(69763,69807,1),new Q.ptr(69840,69864,1),new Q.ptr(69891,69926,1),new Q.ptr(69968,70002,1),new Q.ptr(70006,70019,13),new Q.ptr(70020,70066,1),new Q.ptr(70081,70084,1),new Q.ptr(70106,70108,2),new Q.ptr(70144,70161,1),new Q.ptr(70163,70187,1),new Q.ptr(70272,70278,1),new Q.ptr(70280,70282,2),new Q.ptr(70283,70285,1),new Q.ptr(70287,70301,1),new Q.ptr(70303,70312,1),new Q.ptr(70320,70366,1),new Q.ptr(70405,70412,1),new Q.ptr(70415,70416,1),new Q.ptr(70419,70440,1),new Q.ptr(70442,70448,1),new Q.ptr(70450,70451,1),new Q.ptr(70453,70457,1),new Q.ptr(70461,70480,19),new Q.ptr(70493,70497,1),new Q.ptr(70656,70708,1),new Q.ptr(70727,70730,1),new Q.ptr(70784,70831,1),new Q.ptr(70852,70853,1),new Q.ptr(70855,71040,185),new Q.ptr(71041,71086,1),new Q.ptr(71128,71131,1),new Q.ptr(71168,71215,1),new Q.ptr(71236,71296,60),new Q.ptr(71297,71338,1),new Q.ptr(71424,71449,1),new Q.ptr(71935,72192,257),new Q.ptr(72203,72242,1),new Q.ptr(72250,72272,22),new Q.ptr(72284,72323,1),new Q.ptr(72326,72329,1),new Q.ptr(72384,72440,1),new Q.ptr(72704,72712,1),new Q.ptr(72714,72750,1),new Q.ptr(72768,72818,50),new Q.ptr(72819,72847,1),new Q.ptr(72960,72966,1),new Q.ptr(72968,72969,1),new Q.ptr(72971,73008,1),new Q.ptr(73030,73728,698),new Q.ptr(73729,74649,1),new Q.ptr(74880,75075,1),new Q.ptr(77824,78894,1),new Q.ptr(82944,83526,1),new Q.ptr(92160,92728,1),new Q.ptr(92736,92766,1),new Q.ptr(92880,92909,1),new Q.ptr(92928,92975,1),new Q.ptr(93027,93047,1),new Q.ptr(93053,93071,1),new Q.ptr(93952,94020,1),new Q.ptr(94032,94208,176),new Q.ptr(94209,100332,1),new Q.ptr(100352,101106,1),new Q.ptr(110592,110878,1),new Q.ptr(110960,111355,1),new Q.ptr(113664,113770,1),new Q.ptr(113776,113788,1),new Q.ptr(113792,113800,1),new Q.ptr(113808,113817,1),new Q.ptr(124928,125124,1),new Q.ptr(126464,126467,1),new Q.ptr(126469,126495,1),new Q.ptr(126497,126498,1),new Q.ptr(126500,126503,3),new Q.ptr(126505,126514,1),new Q.ptr(126516,126519,1),new Q.ptr(126521,126523,2),new Q.ptr(126530,126535,5),new Q.ptr(126537,126541,2),new Q.ptr(126542,126543,1),new Q.ptr(126545,126546,1),new Q.ptr(126548,126551,3),new Q.ptr(126553,126561,2),new Q.ptr(126562,126564,2),new Q.ptr(126567,126570,1),new Q.ptr(126572,126578,1),new Q.ptr(126580,126583,1),new Q.ptr(126585,126588,1),new Q.ptr(126590,126592,2),new Q.ptr(126593,126601,1),new Q.ptr(126603,126619,1),new Q.ptr(126625,126627,1),new Q.ptr(126629,126633,1),new Q.ptr(126635,126651,1),new Q.ptr(131072,173782,1),new Q.ptr(173824,177972,1),new Q.ptr(177984,178205,1),new Q.ptr(178208,183969,1),new Q.ptr(183984,191456,1),new Q.ptr(194560,195101,1)]),1);AQ=new O.ptr(new IY([new P.ptr(453,459,3),new P.ptr(498,8072,7574),new P.ptr(8073,8079,1),new P.ptr(8088,8095,1),new P.ptr(8104,8111,1),new P.ptr(8124,8140,16),new P.ptr(8188,8188,1)]),IZ.nil,0);AR=new O.ptr(new IY([new P.ptr(65,90,1),new P.ptr(192,214,1),new P.ptr(216,222,1),new P.ptr(256,310,2),new P.ptr(313,327,2),new P.ptr(330,376,2),new P.ptr(377,381,2),new P.ptr(385,386,1),new P.ptr(388,390,2),new P.ptr(391,393,2),new P.ptr(394,395,1),new P.ptr(398,401,1),new P.ptr(403,404,1),new P.ptr(406,408,1),new P.ptr(412,413,1),new P.ptr(415,416,1),new P.ptr(418,422,2),new P.ptr(423,425,2),new P.ptr(428,430,2),new P.ptr(431,433,2),new P.ptr(434,435,1),new P.ptr(437,439,2),new P.ptr(440,444,4),new P.ptr(452,461,3),new P.ptr(463,475,2),new P.ptr(478,494,2),new P.ptr(497,500,3),new P.ptr(502,504,1),new P.ptr(506,562,2),new P.ptr(570,571,1),new P.ptr(573,574,1),new P.ptr(577,579,2),new P.ptr(580,582,1),new P.ptr(584,590,2),new P.ptr(880,882,2),new P.ptr(886,895,9),new P.ptr(902,904,2),new P.ptr(905,906,1),new P.ptr(908,910,2),new P.ptr(911,913,2),new P.ptr(914,929,1),new P.ptr(931,939,1),new P.ptr(975,978,3),new P.ptr(979,980,1),new P.ptr(984,1006,2),new P.ptr(1012,1015,3),new P.ptr(1017,1018,1),new P.ptr(1021,1071,1),new P.ptr(1120,1152,2),new P.ptr(1162,1216,2),new P.ptr(1217,1229,2),new P.ptr(1232,1326,2),new P.ptr(1329,1366,1),new P.ptr(4256,4293,1),new P.ptr(4295,4301,6),new P.ptr(5024,5109,1),new P.ptr(7680,7828,2),new P.ptr(7838,7934,2),new P.ptr(7944,7951,1),new P.ptr(7960,7965,1),new P.ptr(7976,7983,1),new P.ptr(7992,7999,1),new P.ptr(8008,8013,1),new P.ptr(8025,8031,2),new P.ptr(8040,8047,1),new P.ptr(8120,8123,1),new P.ptr(8136,8139,1),new P.ptr(8152,8155,1),new P.ptr(8168,8172,1),new P.ptr(8184,8187,1),new P.ptr(8450,8455,5),new P.ptr(8459,8461,1),new P.ptr(8464,8466,1),new P.ptr(8469,8473,4),new P.ptr(8474,8477,1),new P.ptr(8484,8490,2),new P.ptr(8491,8493,1),new P.ptr(8496,8499,1),new P.ptr(8510,8511,1),new P.ptr(8517,8579,62),new P.ptr(11264,11310,1),new P.ptr(11360,11362,2),new P.ptr(11363,11364,1),new P.ptr(11367,11373,2),new P.ptr(11374,11376,1),new P.ptr(11378,11381,3),new P.ptr(11390,11392,1),new P.ptr(11394,11490,2),new P.ptr(11499,11501,2),new P.ptr(11506,42560,31054),new P.ptr(42562,42604,2),new P.ptr(42624,42650,2),new P.ptr(42786,42798,2),new P.ptr(42802,42862,2),new P.ptr(42873,42877,2),new P.ptr(42878,42886,2),new P.ptr(42891,42893,2),new P.ptr(42896,42898,2),new P.ptr(42902,42922,2),new P.ptr(42923,42926,1),new P.ptr(42928,42932,1),new P.ptr(42934,65313,22379),new P.ptr(65314,65338,1)]),new IZ([new Q.ptr(66560,66599,1),new Q.ptr(66736,66771,1),new Q.ptr(68736,68786,1),new Q.ptr(71840,71871,1),new Q.ptr(119808,119833,1),new Q.ptr(119860,119885,1),new Q.ptr(119912,119937,1),new Q.ptr(119964,119966,2),new Q.ptr(119967,119973,3),new Q.ptr(119974,119977,3),new Q.ptr(119978,119980,1),new Q.ptr(119982,119989,1),new Q.ptr(120016,120041,1),new Q.ptr(120068,120069,1),new Q.ptr(120071,120074,1),new Q.ptr(120077,120084,1),new Q.ptr(120086,120092,1),new Q.ptr(120120,120121,1),new Q.ptr(120123,120126,1),new Q.ptr(120128,120132,1),new Q.ptr(120134,120138,4),new Q.ptr(120139,120144,1),new Q.ptr(120172,120197,1),new Q.ptr(120224,120249,1),new Q.ptr(120276,120301,1),new Q.ptr(120328,120353,1),new Q.ptr(120380,120405,1),new Q.ptr(120432,120457,1),new Q.ptr(120488,120512,1),new Q.ptr(120546,120570,1),new Q.ptr(120604,120628,1),new Q.ptr(120662,120686,1),new Q.ptr(120720,120744,1),new Q.ptr(120778,125184,4406),new Q.ptr(125185,125217,1)]),3);AS=new O.ptr(new IY([new P.ptr(768,879,1),new P.ptr(1155,1161,1),new P.ptr(1425,1469,1),new P.ptr(1471,1473,2),new P.ptr(1474,1476,2),new P.ptr(1477,1479,2),new P.ptr(1552,1562,1),new P.ptr(1611,1631,1),new P.ptr(1648,1750,102),new P.ptr(1751,1756,1),new P.ptr(1759,1764,1),new P.ptr(1767,1768,1),new P.ptr(1770,1773,1),new P.ptr(1809,1840,31),new P.ptr(1841,1866,1),new P.ptr(1958,1968,1),new P.ptr(2027,2035,1),new P.ptr(2070,2073,1),new P.ptr(2075,2083,1),new P.ptr(2085,2087,1),new P.ptr(2089,2093,1),new P.ptr(2137,2139,1),new P.ptr(2260,2273,1),new P.ptr(2275,2307,1),new P.ptr(2362,2364,1),new P.ptr(2366,2383,1),new P.ptr(2385,2391,1),new P.ptr(2402,2403,1),new P.ptr(2433,2435,1),new P.ptr(2492,2494,2),new P.ptr(2495,2500,1),new P.ptr(2503,2504,1),new P.ptr(2507,2509,1),new P.ptr(2519,2530,11),new P.ptr(2531,2561,30),new P.ptr(2562,2563,1),new P.ptr(2620,2622,2),new P.ptr(2623,2626,1),new P.ptr(2631,2632,1),new P.ptr(2635,2637,1),new P.ptr(2641,2672,31),new P.ptr(2673,2677,4),new P.ptr(2689,2691,1),new P.ptr(2748,2750,2),new P.ptr(2751,2757,1),new P.ptr(2759,2761,1),new P.ptr(2763,2765,1),new P.ptr(2786,2787,1),new P.ptr(2810,2815,1),new P.ptr(2817,2819,1),new P.ptr(2876,2878,2),new P.ptr(2879,2884,1),new P.ptr(2887,2888,1),new P.ptr(2891,2893,1),new P.ptr(2902,2903,1),new P.ptr(2914,2915,1),new P.ptr(2946,3006,60),new P.ptr(3007,3010,1),new P.ptr(3014,3016,1),new P.ptr(3018,3021,1),new P.ptr(3031,3072,41),new P.ptr(3073,3075,1),new P.ptr(3134,3140,1),new P.ptr(3142,3144,1),new P.ptr(3146,3149,1),new P.ptr(3157,3158,1),new P.ptr(3170,3171,1),new P.ptr(3201,3203,1),new P.ptr(3260,3262,2),new P.ptr(3263,3268,1),new P.ptr(3270,3272,1),new P.ptr(3274,3277,1),new P.ptr(3285,3286,1),new P.ptr(3298,3299,1),new P.ptr(3328,3331,1),new P.ptr(3387,3388,1),new P.ptr(3390,3396,1),new P.ptr(3398,3400,1),new P.ptr(3402,3405,1),new P.ptr(3415,3426,11),new P.ptr(3427,3458,31),new P.ptr(3459,3530,71),new P.ptr(3535,3540,1),new P.ptr(3542,3544,2),new P.ptr(3545,3551,1),new P.ptr(3570,3571,1),new P.ptr(3633,3636,3),new P.ptr(3637,3642,1),new P.ptr(3655,3662,1),new P.ptr(3761,3764,3),new P.ptr(3765,3769,1),new P.ptr(3771,3772,1),new P.ptr(3784,3789,1),new P.ptr(3864,3865,1),new P.ptr(3893,3897,2),new P.ptr(3902,3903,1),new P.ptr(3953,3972,1),new P.ptr(3974,3975,1),new P.ptr(3981,3991,1),new P.ptr(3993,4028,1),new P.ptr(4038,4139,101),new P.ptr(4140,4158,1),new P.ptr(4182,4185,1),new P.ptr(4190,4192,1),new P.ptr(4194,4196,1),new P.ptr(4199,4205,1),new P.ptr(4209,4212,1),new P.ptr(4226,4237,1),new P.ptr(4239,4250,11),new P.ptr(4251,4253,1),new P.ptr(4957,4959,1),new P.ptr(5906,5908,1),new P.ptr(5938,5940,1),new P.ptr(5970,5971,1),new P.ptr(6002,6003,1),new P.ptr(6068,6099,1),new P.ptr(6109,6155,46),new P.ptr(6156,6157,1),new P.ptr(6277,6278,1),new P.ptr(6313,6432,119),new P.ptr(6433,6443,1),new P.ptr(6448,6459,1),new P.ptr(6679,6683,1),new P.ptr(6741,6750,1),new P.ptr(6752,6780,1),new P.ptr(6783,6832,49),new P.ptr(6833,6846,1),new P.ptr(6912,6916,1),new P.ptr(6964,6980,1),new P.ptr(7019,7027,1),new P.ptr(7040,7042,1),new P.ptr(7073,7085,1),new P.ptr(7142,7155,1),new P.ptr(7204,7223,1),new P.ptr(7376,7378,1),new P.ptr(7380,7400,1),new P.ptr(7405,7410,5),new P.ptr(7411,7412,1),new P.ptr(7415,7417,1),new P.ptr(7616,7673,1),new P.ptr(7675,7679,1),new P.ptr(8400,8432,1),new P.ptr(11503,11505,1),new P.ptr(11647,11744,97),new P.ptr(11745,11775,1),new P.ptr(12330,12335,1),new P.ptr(12441,12442,1),new P.ptr(42607,42610,1),new P.ptr(42612,42621,1),new P.ptr(42654,42655,1),new P.ptr(42736,42737,1),new P.ptr(43010,43014,4),new P.ptr(43019,43043,24),new P.ptr(43044,43047,1),new P.ptr(43136,43137,1),new P.ptr(43188,43205,1),new P.ptr(43232,43249,1),new P.ptr(43302,43309,1),new P.ptr(43335,43347,1),new P.ptr(43392,43395,1),new P.ptr(43443,43456,1),new P.ptr(43493,43561,68),new P.ptr(43562,43574,1),new P.ptr(43587,43596,9),new P.ptr(43597,43643,46),new P.ptr(43644,43645,1),new P.ptr(43696,43698,2),new P.ptr(43699,43700,1),new P.ptr(43703,43704,1),new P.ptr(43710,43711,1),new P.ptr(43713,43755,42),new P.ptr(43756,43759,1),new P.ptr(43765,43766,1),new P.ptr(44003,44010,1),new P.ptr(44012,44013,1),new P.ptr(64286,65024,738),new P.ptr(65025,65039,1),new P.ptr(65056,65071,1)]),new IZ([new Q.ptr(66045,66272,227),new Q.ptr(66422,66426,1),new Q.ptr(68097,68099,1),new Q.ptr(68101,68102,1),new Q.ptr(68108,68111,1),new Q.ptr(68152,68154,1),new Q.ptr(68159,68325,166),new Q.ptr(68326,69632,1306),new Q.ptr(69633,69634,1),new Q.ptr(69688,69702,1),new Q.ptr(69759,69762,1),new Q.ptr(69808,69818,1),new Q.ptr(69888,69890,1),new Q.ptr(69927,69940,1),new Q.ptr(70003,70016,13),new Q.ptr(70017,70018,1),new Q.ptr(70067,70080,1),new Q.ptr(70090,70092,1),new Q.ptr(70188,70199,1),new Q.ptr(70206,70367,161),new Q.ptr(70368,70378,1),new Q.ptr(70400,70403,1),new Q.ptr(70460,70462,2),new Q.ptr(70463,70468,1),new Q.ptr(70471,70472,1),new Q.ptr(70475,70477,1),new Q.ptr(70487,70498,11),new Q.ptr(70499,70502,3),new Q.ptr(70503,70508,1),new Q.ptr(70512,70516,1),new Q.ptr(70709,70726,1),new Q.ptr(70832,70851,1),new Q.ptr(71087,71093,1),new Q.ptr(71096,71104,1),new Q.ptr(71132,71133,1),new Q.ptr(71216,71232,1),new Q.ptr(71339,71351,1),new Q.ptr(71453,71467,1),new Q.ptr(72193,72202,1),new Q.ptr(72243,72249,1),new Q.ptr(72251,72254,1),new Q.ptr(72263,72273,10),new Q.ptr(72274,72283,1),new Q.ptr(72330,72345,1),new Q.ptr(72751,72758,1),new Q.ptr(72760,72767,1),new Q.ptr(72850,72871,1),new Q.ptr(72873,72886,1),new Q.ptr(73009,73014,1),new Q.ptr(73018,73020,2),new Q.ptr(73021,73023,2),new Q.ptr(73024,73029,1),new Q.ptr(73031,92912,19881),new Q.ptr(92913,92916,1),new Q.ptr(92976,92982,1),new Q.ptr(94033,94078,1),new Q.ptr(94095,94098,1),new Q.ptr(113821,113822,1),new Q.ptr(119141,119145,1),new Q.ptr(119149,119154,1),new Q.ptr(119163,119170,1),new Q.ptr(119173,119179,1),new Q.ptr(119210,119213,1),new Q.ptr(119362,119364,1),new Q.ptr(121344,121398,1),new Q.ptr(121403,121452,1),new Q.ptr(121461,121476,15),new Q.ptr(121499,121503,1),new Q.ptr(121505,121519,1),new Q.ptr(122880,122886,1),new Q.ptr(122888,122904,1),new Q.ptr(122907,122913,1),new Q.ptr(122915,122916,1),new Q.ptr(122918,122922,1),new Q.ptr(125136,125142,1),new Q.ptr(125252,125258,1),new Q.ptr(917760,917999,1)]),0);AT=new O.ptr(new IY([new P.ptr(2307,2363,56),new P.ptr(2366,2368,1),new P.ptr(2377,2380,1),new P.ptr(2382,2383,1),new P.ptr(2434,2435,1),new P.ptr(2494,2496,1),new P.ptr(2503,2504,1),new P.ptr(2507,2508,1),new P.ptr(2519,2563,44),new P.ptr(2622,2624,1),new P.ptr(2691,2750,59),new P.ptr(2751,2752,1),new P.ptr(2761,2763,2),new P.ptr(2764,2818,54),new P.ptr(2819,2878,59),new P.ptr(2880,2887,7),new P.ptr(2888,2891,3),new P.ptr(2892,2903,11),new P.ptr(3006,3007,1),new P.ptr(3009,3010,1),new P.ptr(3014,3016,1),new P.ptr(3018,3020,1),new P.ptr(3031,3073,42),new P.ptr(3074,3075,1),new P.ptr(3137,3140,1),new P.ptr(3202,3203,1),new P.ptr(3262,3264,2),new P.ptr(3265,3268,1),new P.ptr(3271,3272,1),new P.ptr(3274,3275,1),new P.ptr(3285,3286,1),new P.ptr(3330,3331,1),new P.ptr(3390,3392,1),new P.ptr(3398,3400,1),new P.ptr(3402,3404,1),new P.ptr(3415,3458,43),new P.ptr(3459,3535,76),new P.ptr(3536,3537,1),new P.ptr(3544,3551,1),new P.ptr(3570,3571,1),new P.ptr(3902,3903,1),new P.ptr(3967,4139,172),new P.ptr(4140,4145,5),new P.ptr(4152,4155,3),new P.ptr(4156,4182,26),new P.ptr(4183,4194,11),new P.ptr(4195,4196,1),new P.ptr(4199,4205,1),new P.ptr(4227,4228,1),new P.ptr(4231,4236,1),new P.ptr(4239,4250,11),new P.ptr(4251,4252,1),new P.ptr(6070,6078,8),new P.ptr(6079,6085,1),new P.ptr(6087,6088,1),new P.ptr(6435,6438,1),new P.ptr(6441,6443,1),new P.ptr(6448,6449,1),new P.ptr(6451,6456,1),new P.ptr(6681,6682,1),new P.ptr(6741,6743,2),new P.ptr(6753,6755,2),new P.ptr(6756,6765,9),new P.ptr(6766,6770,1),new P.ptr(6916,6965,49),new P.ptr(6971,6973,2),new P.ptr(6974,6977,1),new P.ptr(6979,6980,1),new P.ptr(7042,7073,31),new P.ptr(7078,7079,1),new P.ptr(7082,7143,61),new P.ptr(7146,7148,1),new P.ptr(7150,7154,4),new P.ptr(7155,7204,49),new P.ptr(7205,7211,1),new P.ptr(7220,7221,1),new P.ptr(7393,7410,17),new P.ptr(7411,7415,4),new P.ptr(12334,12335,1),new P.ptr(43043,43044,1),new P.ptr(43047,43136,89),new P.ptr(43137,43188,51),new P.ptr(43189,43203,1),new P.ptr(43346,43347,1),new P.ptr(43395,43444,49),new P.ptr(43445,43450,5),new P.ptr(43451,43453,2),new P.ptr(43454,43456,1),new P.ptr(43567,43568,1),new P.ptr(43571,43572,1),new P.ptr(43597,43643,46),new P.ptr(43645,43755,110),new P.ptr(43758,43759,1),new P.ptr(43765,44003,238),new P.ptr(44004,44006,2),new P.ptr(44007,44009,2),new P.ptr(44010,44012,2)]),new IZ([new Q.ptr(69632,69634,2),new Q.ptr(69762,69808,46),new Q.ptr(69809,69810,1),new Q.ptr(69815,69816,1),new Q.ptr(69932,70018,86),new Q.ptr(70067,70069,1),new Q.ptr(70079,70080,1),new Q.ptr(70188,70190,1),new Q.ptr(70194,70195,1),new Q.ptr(70197,70368,171),new Q.ptr(70369,70370,1),new Q.ptr(70402,70403,1),new Q.ptr(70462,70463,1),new Q.ptr(70465,70468,1),new Q.ptr(70471,70472,1),new Q.ptr(70475,70477,1),new Q.ptr(70487,70498,11),new Q.ptr(70499,70709,210),new Q.ptr(70710,70711,1),new Q.ptr(70720,70721,1),new Q.ptr(70725,70832,107),new Q.ptr(70833,70834,1),new Q.ptr(70841,70843,2),new Q.ptr(70844,70846,1),new Q.ptr(70849,71087,238),new Q.ptr(71088,71089,1),new Q.ptr(71096,71099,1),new Q.ptr(71102,71216,114),new Q.ptr(71217,71218,1),new Q.ptr(71227,71228,1),new Q.ptr(71230,71340,110),new Q.ptr(71342,71343,1),new Q.ptr(71350,71456,106),new Q.ptr(71457,71462,5),new Q.ptr(72199,72200,1),new Q.ptr(72249,72279,30),new Q.ptr(72280,72343,63),new Q.ptr(72751,72766,15),new Q.ptr(72873,72881,8),new Q.ptr(72884,94033,21149),new Q.ptr(94034,94078,1),new Q.ptr(119141,119142,1),new Q.ptr(119149,119154,1)]),0);AU=new O.ptr(new IY([new P.ptr(1160,1161,1),new P.ptr(6846,8413,1567),new P.ptr(8414,8416,1),new P.ptr(8418,8420,1),new P.ptr(42608,42610,1)]),IZ.nil,0);AV=new O.ptr(new IY([new P.ptr(768,879,1),new P.ptr(1155,1159,1),new P.ptr(1425,1469,1),new P.ptr(1471,1473,2),new P.ptr(1474,1476,2),new P.ptr(1477,1479,2),new P.ptr(1552,1562,1),new P.ptr(1611,1631,1),new P.ptr(1648,1750,102),new P.ptr(1751,1756,1),new P.ptr(1759,1764,1),new P.ptr(1767,1768,1),new P.ptr(1770,1773,1),new P.ptr(1809,1840,31),new P.ptr(1841,1866,1),new P.ptr(1958,1968,1),new P.ptr(2027,2035,1),new P.ptr(2070,2073,1),new P.ptr(2075,2083,1),new P.ptr(2085,2087,1),new P.ptr(2089,2093,1),new P.ptr(2137,2139,1),new P.ptr(2260,2273,1),new P.ptr(2275,2306,1),new P.ptr(2362,2364,2),new P.ptr(2369,2376,1),new P.ptr(2381,2385,4),new P.ptr(2386,2391,1),new P.ptr(2402,2403,1),new P.ptr(2433,2492,59),new P.ptr(2497,2500,1),new P.ptr(2509,2530,21),new P.ptr(2531,2561,30),new P.ptr(2562,2620,58),new P.ptr(2625,2626,1),new P.ptr(2631,2632,1),new P.ptr(2635,2637,1),new P.ptr(2641,2672,31),new P.ptr(2673,2677,4),new P.ptr(2689,2690,1),new P.ptr(2748,2753,5),new P.ptr(2754,2757,1),new P.ptr(2759,2760,1),new P.ptr(2765,2786,21),new P.ptr(2787,2810,23),new P.ptr(2811,2815,1),new P.ptr(2817,2876,59),new P.ptr(2879,2881,2),new P.ptr(2882,2884,1),new P.ptr(2893,2902,9),new P.ptr(2914,2915,1),new P.ptr(2946,3008,62),new P.ptr(3021,3072,51),new P.ptr(3134,3136,1),new P.ptr(3142,3144,1),new P.ptr(3146,3149,1),new P.ptr(3157,3158,1),new P.ptr(3170,3171,1),new P.ptr(3201,3260,59),new P.ptr(3263,3270,7),new P.ptr(3276,3277,1),new P.ptr(3298,3299,1),new P.ptr(3328,3329,1),new P.ptr(3387,3388,1),new P.ptr(3393,3396,1),new P.ptr(3405,3426,21),new P.ptr(3427,3530,103),new P.ptr(3538,3540,1),new P.ptr(3542,3633,91),new P.ptr(3636,3642,1),new P.ptr(3655,3662,1),new P.ptr(3761,3764,3),new P.ptr(3765,3769,1),new P.ptr(3771,3772,1),new P.ptr(3784,3789,1),new P.ptr(3864,3865,1),new P.ptr(3893,3897,2),new P.ptr(3953,3966,1),new P.ptr(3968,3972,1),new P.ptr(3974,3975,1),new P.ptr(3981,3991,1),new P.ptr(3993,4028,1),new P.ptr(4038,4141,103),new P.ptr(4142,4144,1),new P.ptr(4146,4151,1),new P.ptr(4153,4154,1),new P.ptr(4157,4158,1),new P.ptr(4184,4185,1),new P.ptr(4190,4192,1),new P.ptr(4209,4212,1),new P.ptr(4226,4229,3),new P.ptr(4230,4237,7),new P.ptr(4253,4957,704),new P.ptr(4958,4959,1),new P.ptr(5906,5908,1),new P.ptr(5938,5940,1),new P.ptr(5970,5971,1),new P.ptr(6002,6003,1),new P.ptr(6068,6069,1),new P.ptr(6071,6077,1),new P.ptr(6086,6089,3),new P.ptr(6090,6099,1),new P.ptr(6109,6155,46),new P.ptr(6156,6157,1),new P.ptr(6277,6278,1),new P.ptr(6313,6432,119),new P.ptr(6433,6434,1),new P.ptr(6439,6440,1),new P.ptr(6450,6457,7),new P.ptr(6458,6459,1),new P.ptr(6679,6680,1),new P.ptr(6683,6742,59),new P.ptr(6744,6750,1),new P.ptr(6752,6754,2),new P.ptr(6757,6764,1),new P.ptr(6771,6780,1),new P.ptr(6783,6832,49),new P.ptr(6833,6845,1),new P.ptr(6912,6915,1),new P.ptr(6964,6966,2),new P.ptr(6967,6970,1),new P.ptr(6972,6978,6),new P.ptr(7019,7027,1),new P.ptr(7040,7041,1),new P.ptr(7074,7077,1),new P.ptr(7080,7081,1),new P.ptr(7083,7085,1),new P.ptr(7142,7144,2),new P.ptr(7145,7149,4),new P.ptr(7151,7153,1),new P.ptr(7212,7219,1),new P.ptr(7222,7223,1),new P.ptr(7376,7378,1),new P.ptr(7380,7392,1),new P.ptr(7394,7400,1),new P.ptr(7405,7412,7),new P.ptr(7416,7417,1),new P.ptr(7616,7673,1),new P.ptr(7675,7679,1),new P.ptr(8400,8412,1),new P.ptr(8417,8421,4),new P.ptr(8422,8432,1),new P.ptr(11503,11505,1),new P.ptr(11647,11744,97),new P.ptr(11745,11775,1),new P.ptr(12330,12333,1),new P.ptr(12441,12442,1),new P.ptr(42607,42612,5),new P.ptr(42613,42621,1),new P.ptr(42654,42655,1),new P.ptr(42736,42737,1),new P.ptr(43010,43014,4),new P.ptr(43019,43045,26),new P.ptr(43046,43204,158),new P.ptr(43205,43232,27),new P.ptr(43233,43249,1),new P.ptr(43302,43309,1),new P.ptr(43335,43345,1),new P.ptr(43392,43394,1),new P.ptr(43443,43446,3),new P.ptr(43447,43449,1),new P.ptr(43452,43493,41),new P.ptr(43561,43566,1),new P.ptr(43569,43570,1),new P.ptr(43573,43574,1),new P.ptr(43587,43596,9),new P.ptr(43644,43696,52),new P.ptr(43698,43700,1),new P.ptr(43703,43704,1),new P.ptr(43710,43711,1),new P.ptr(43713,43756,43),new P.ptr(43757,43766,9),new P.ptr(44005,44008,3),new P.ptr(44013,64286,20273),new P.ptr(65024,65039,1),new P.ptr(65056,65071,1)]),new IZ([new Q.ptr(66045,66272,227),new Q.ptr(66422,66426,1),new Q.ptr(68097,68099,1),new Q.ptr(68101,68102,1),new Q.ptr(68108,68111,1),new Q.ptr(68152,68154,1),new Q.ptr(68159,68325,166),new Q.ptr(68326,69633,1307),new Q.ptr(69688,69702,1),new Q.ptr(69759,69761,1),new Q.ptr(69811,69814,1),new Q.ptr(69817,69818,1),new Q.ptr(69888,69890,1),new Q.ptr(69927,69931,1),new Q.ptr(69933,69940,1),new Q.ptr(70003,70016,13),new Q.ptr(70017,70070,53),new Q.ptr(70071,70078,1),new Q.ptr(70090,70092,1),new Q.ptr(70191,70193,1),new Q.ptr(70196,70198,2),new Q.ptr(70199,70206,7),new Q.ptr(70367,70371,4),new Q.ptr(70372,70378,1),new Q.ptr(70400,70401,1),new Q.ptr(70460,70464,4),new Q.ptr(70502,70508,1),new Q.ptr(70512,70516,1),new Q.ptr(70712,70719,1),new Q.ptr(70722,70724,1),new Q.ptr(70726,70835,109),new Q.ptr(70836,70840,1),new Q.ptr(70842,70847,5),new Q.ptr(70848,70850,2),new Q.ptr(70851,71090,239),new Q.ptr(71091,71093,1),new Q.ptr(71100,71101,1),new Q.ptr(71103,71104,1),new Q.ptr(71132,71133,1),new Q.ptr(71219,71226,1),new Q.ptr(71229,71231,2),new Q.ptr(71232,71339,107),new Q.ptr(71341,71344,3),new Q.ptr(71345,71349,1),new Q.ptr(71351,71453,102),new Q.ptr(71454,71455,1),new Q.ptr(71458,71461,1),new Q.ptr(71463,71467,1),new Q.ptr(72193,72198,1),new Q.ptr(72201,72202,1),new Q.ptr(72243,72248,1),new Q.ptr(72251,72254,1),new Q.ptr(72263,72273,10),new Q.ptr(72274,72278,1),new Q.ptr(72281,72283,1),new Q.ptr(72330,72342,1),new Q.ptr(72344,72345,1),new Q.ptr(72752,72758,1),new Q.ptr(72760,72765,1),new Q.ptr(72767,72850,83),new Q.ptr(72851,72871,1),new Q.ptr(72874,72880,1),new Q.ptr(72882,72883,1),new Q.ptr(72885,72886,1),new Q.ptr(73009,73014,1),new Q.ptr(73018,73020,2),new Q.ptr(73021,73023,2),new Q.ptr(73024,73029,1),new Q.ptr(73031,92912,19881),new Q.ptr(92913,92916,1),new Q.ptr(92976,92982,1),new Q.ptr(94095,94098,1),new Q.ptr(113821,113822,1),new Q.ptr(119143,119145,1),new Q.ptr(119163,119170,1),new Q.ptr(119173,119179,1),new Q.ptr(119210,119213,1),new Q.ptr(119362,119364,1),new Q.ptr(121344,121398,1),new Q.ptr(121403,121452,1),new Q.ptr(121461,121476,15),new Q.ptr(121499,121503,1),new Q.ptr(121505,121519,1),new Q.ptr(122880,122886,1),new Q.ptr(122888,122904,1),new Q.ptr(122907,122913,1),new Q.ptr(122915,122916,1),new Q.ptr(122918,122922,1),new Q.ptr(125136,125142,1),new Q.ptr(125252,125258,1),new Q.ptr(917760,917999,1)]),0);AW=new O.ptr(new IY([new P.ptr(48,57,1),new P.ptr(178,179,1),new P.ptr(185,188,3),new P.ptr(189,190,1),new P.ptr(1632,1641,1),new P.ptr(1776,1785,1),new P.ptr(1984,1993,1),new P.ptr(2406,2415,1),new P.ptr(2534,2543,1),new P.ptr(2548,2553,1),new P.ptr(2662,2671,1),new P.ptr(2790,2799,1),new P.ptr(2918,2927,1),new P.ptr(2930,2935,1),new P.ptr(3046,3058,1),new P.ptr(3174,3183,1),new P.ptr(3192,3198,1),new P.ptr(3302,3311,1),new P.ptr(3416,3422,1),new P.ptr(3430,3448,1),new P.ptr(3558,3567,1),new P.ptr(3664,3673,1),new P.ptr(3792,3801,1),new P.ptr(3872,3891,1),new P.ptr(4160,4169,1),new P.ptr(4240,4249,1),new P.ptr(4969,4988,1),new P.ptr(5870,5872,1),new P.ptr(6112,6121,1),new P.ptr(6128,6137,1),new P.ptr(6160,6169,1),new P.ptr(6470,6479,1),new P.ptr(6608,6618,1),new P.ptr(6784,6793,1),new P.ptr(6800,6809,1),new P.ptr(6992,7001,1),new P.ptr(7088,7097,1),new P.ptr(7232,7241,1),new P.ptr(7248,7257,1),new P.ptr(8304,8308,4),new P.ptr(8309,8313,1),new P.ptr(8320,8329,1),new P.ptr(8528,8578,1),new P.ptr(8581,8585,1),new P.ptr(9312,9371,1),new P.ptr(9450,9471,1),new P.ptr(10102,10131,1),new P.ptr(11517,12295,778),new P.ptr(12321,12329,1),new P.ptr(12344,12346,1),new P.ptr(12690,12693,1),new P.ptr(12832,12841,1),new P.ptr(12872,12879,1),new P.ptr(12881,12895,1),new P.ptr(12928,12937,1),new P.ptr(12977,12991,1),new P.ptr(42528,42537,1),new P.ptr(42726,42735,1),new P.ptr(43056,43061,1),new P.ptr(43216,43225,1),new P.ptr(43264,43273,1),new P.ptr(43472,43481,1),new P.ptr(43504,43513,1),new P.ptr(43600,43609,1),new P.ptr(44016,44025,1),new P.ptr(65296,65305,1)]),new IZ([new Q.ptr(65799,65843,1),new Q.ptr(65856,65912,1),new Q.ptr(65930,65931,1),new Q.ptr(66273,66299,1),new Q.ptr(66336,66339,1),new Q.ptr(66369,66378,9),new Q.ptr(66513,66517,1),new Q.ptr(66720,66729,1),new Q.ptr(67672,67679,1),new Q.ptr(67705,67711,1),new Q.ptr(67751,67759,1),new Q.ptr(67835,67839,1),new Q.ptr(67862,67867,1),new Q.ptr(68028,68029,1),new Q.ptr(68032,68047,1),new Q.ptr(68050,68095,1),new Q.ptr(68160,68167,1),new Q.ptr(68221,68222,1),new Q.ptr(68253,68255,1),new Q.ptr(68331,68335,1),new Q.ptr(68440,68447,1),new Q.ptr(68472,68479,1),new Q.ptr(68521,68527,1),new Q.ptr(68858,68863,1),new Q.ptr(69216,69246,1),new Q.ptr(69714,69743,1),new Q.ptr(69872,69881,1),new Q.ptr(69942,69951,1),new Q.ptr(70096,70105,1),new Q.ptr(70113,70132,1),new Q.ptr(70384,70393,1),new Q.ptr(70736,70745,1),new Q.ptr(70864,70873,1),new Q.ptr(71248,71257,1),new Q.ptr(71360,71369,1),new Q.ptr(71472,71483,1),new Q.ptr(71904,71922,1),new Q.ptr(72784,72812,1),new Q.ptr(73040,73049,1),new Q.ptr(74752,74862,1),new Q.ptr(92768,92777,1),new Q.ptr(93008,93017,1),new Q.ptr(93019,93025,1),new Q.ptr(119648,119665,1),new Q.ptr(120782,120831,1),new Q.ptr(125127,125135,1),new Q.ptr(125264,125273,1),new Q.ptr(127232,127244,1)]),4);AX=new O.ptr(new IY([new P.ptr(48,57,1),new P.ptr(1632,1641,1),new P.ptr(1776,1785,1),new P.ptr(1984,1993,1),new P.ptr(2406,2415,1),new P.ptr(2534,2543,1),new P.ptr(2662,2671,1),new P.ptr(2790,2799,1),new P.ptr(2918,2927,1),new P.ptr(3046,3055,1),new P.ptr(3174,3183,1),new P.ptr(3302,3311,1),new P.ptr(3430,3439,1),new P.ptr(3558,3567,1),new P.ptr(3664,3673,1),new P.ptr(3792,3801,1),new P.ptr(3872,3881,1),new P.ptr(4160,4169,1),new P.ptr(4240,4249,1),new P.ptr(6112,6121,1),new P.ptr(6160,6169,1),new P.ptr(6470,6479,1),new P.ptr(6608,6617,1),new P.ptr(6784,6793,1),new P.ptr(6800,6809,1),new P.ptr(6992,7001,1),new P.ptr(7088,7097,1),new P.ptr(7232,7241,1),new P.ptr(7248,7257,1),new P.ptr(42528,42537,1),new P.ptr(43216,43225,1),new P.ptr(43264,43273,1),new P.ptr(43472,43481,1),new P.ptr(43504,43513,1),new P.ptr(43600,43609,1),new P.ptr(44016,44025,1),new P.ptr(65296,65305,1)]),new IZ([new Q.ptr(66720,66729,1),new Q.ptr(69734,69743,1),new Q.ptr(69872,69881,1),new Q.ptr(69942,69951,1),new Q.ptr(70096,70105,1),new Q.ptr(70384,70393,1),new Q.ptr(70736,70745,1),new Q.ptr(70864,70873,1),new Q.ptr(71248,71257,1),new Q.ptr(71360,71369,1),new Q.ptr(71472,71481,1),new Q.ptr(71904,71913,1),new Q.ptr(72784,72793,1),new Q.ptr(73040,73049,1),new Q.ptr(92768,92777,1),new Q.ptr(93008,93017,1),new Q.ptr(120782,120831,1),new Q.ptr(125264,125273,1)]),1);AY=new O.ptr(new IY([new P.ptr(5870,5872,1),new P.ptr(8544,8578,1),new P.ptr(8581,8584,1),new P.ptr(12295,12321,26),new P.ptr(12322,12329,1),new P.ptr(12344,12346,1),new P.ptr(42726,42735,1)]),new IZ([new Q.ptr(65856,65908,1),new Q.ptr(66369,66378,9),new Q.ptr(66513,66517,1),new Q.ptr(74752,74862,1)]),0);AZ=new O.ptr(new IY([new P.ptr(178,179,1),new P.ptr(185,188,3),new P.ptr(189,190,1),new P.ptr(2548,2553,1),new P.ptr(2930,2935,1),new P.ptr(3056,3058,1),new P.ptr(3192,3198,1),new P.ptr(3416,3422,1),new P.ptr(3440,3448,1),new P.ptr(3882,3891,1),new P.ptr(4969,4988,1),new P.ptr(6128,6137,1),new P.ptr(6618,8304,1686),new P.ptr(8308,8313,1),new P.ptr(8320,8329,1),new P.ptr(8528,8543,1),new P.ptr(8585,9312,727),new P.ptr(9313,9371,1),new P.ptr(9450,9471,1),new P.ptr(10102,10131,1),new P.ptr(11517,12690,1173),new P.ptr(12691,12693,1),new P.ptr(12832,12841,1),new P.ptr(12872,12879,1),new P.ptr(12881,12895,1),new P.ptr(12928,12937,1),new P.ptr(12977,12991,1),new P.ptr(43056,43061,1)]),new IZ([new Q.ptr(65799,65843,1),new Q.ptr(65909,65912,1),new Q.ptr(65930,65931,1),new Q.ptr(66273,66299,1),new Q.ptr(66336,66339,1),new Q.ptr(67672,67679,1),new Q.ptr(67705,67711,1),new Q.ptr(67751,67759,1),new Q.ptr(67835,67839,1),new Q.ptr(67862,67867,1),new Q.ptr(68028,68029,1),new Q.ptr(68032,68047,1),new Q.ptr(68050,68095,1),new Q.ptr(68160,68167,1),new Q.ptr(68221,68222,1),new Q.ptr(68253,68255,1),new Q.ptr(68331,68335,1),new Q.ptr(68440,68447,1),new Q.ptr(68472,68479,1),new Q.ptr(68521,68527,1),new Q.ptr(68858,68863,1),new Q.ptr(69216,69246,1),new Q.ptr(69714,69733,1),new Q.ptr(70113,70132,1),new Q.ptr(71482,71483,1),new Q.ptr(71914,71922,1),new Q.ptr(72794,72812,1),new Q.ptr(93019,93025,1),new Q.ptr(119648,119665,1),new Q.ptr(125127,125135,1),new Q.ptr(127232,127244,1)]),3);BA=new O.ptr(new IY([new P.ptr(33,35,1),new P.ptr(37,42,1),new P.ptr(44,47,1),new P.ptr(58,59,1),new P.ptr(63,64,1),new P.ptr(91,93,1),new P.ptr(95,123,28),new P.ptr(125,161,36),new P.ptr(167,171,4),new P.ptr(182,183,1),new P.ptr(187,191,4),new P.ptr(894,903,9),new P.ptr(1370,1375,1),new P.ptr(1417,1418,1),new P.ptr(1470,1472,2),new P.ptr(1475,1478,3),new P.ptr(1523,1524,1),new P.ptr(1545,1546,1),new P.ptr(1548,1549,1),new P.ptr(1563,1566,3),new P.ptr(1567,1642,75),new P.ptr(1643,1645,1),new P.ptr(1748,1792,44),new P.ptr(1793,1805,1),new P.ptr(2039,2041,1),new P.ptr(2096,2110,1),new P.ptr(2142,2404,262),new P.ptr(2405,2416,11),new P.ptr(2557,2800,243),new P.ptr(3572,3663,91),new P.ptr(3674,3675,1),new P.ptr(3844,3858,1),new P.ptr(3860,3898,38),new P.ptr(3899,3901,1),new P.ptr(3973,4048,75),new P.ptr(4049,4052,1),new P.ptr(4057,4058,1),new P.ptr(4170,4175,1),new P.ptr(4347,4960,613),new P.ptr(4961,4968,1),new P.ptr(5120,5741,621),new P.ptr(5742,5787,45),new P.ptr(5788,5867,79),new P.ptr(5868,5869,1),new P.ptr(5941,5942,1),new P.ptr(6100,6102,1),new P.ptr(6104,6106,1),new P.ptr(6144,6154,1),new P.ptr(6468,6469,1),new P.ptr(6686,6687,1),new P.ptr(6816,6822,1),new P.ptr(6824,6829,1),new P.ptr(7002,7008,1),new P.ptr(7164,7167,1),new P.ptr(7227,7231,1),new P.ptr(7294,7295,1),new P.ptr(7360,7367,1),new P.ptr(7379,8208,829),new P.ptr(8209,8231,1),new P.ptr(8240,8259,1),new P.ptr(8261,8273,1),new P.ptr(8275,8286,1),new P.ptr(8317,8318,1),new P.ptr(8333,8334,1),new P.ptr(8968,8971,1),new P.ptr(9001,9002,1),new P.ptr(10088,10101,1),new P.ptr(10181,10182,1),new P.ptr(10214,10223,1),new P.ptr(10627,10648,1),new P.ptr(10712,10715,1),new P.ptr(10748,10749,1),new P.ptr(11513,11516,1),new P.ptr(11518,11519,1),new P.ptr(11632,11776,144),new P.ptr(11777,11822,1),new P.ptr(11824,11849,1),new P.ptr(12289,12291,1),new P.ptr(12296,12305,1),new P.ptr(12308,12319,1),new P.ptr(12336,12349,13),new P.ptr(12448,12539,91),new P.ptr(42238,42239,1),new P.ptr(42509,42511,1),new P.ptr(42611,42622,11),new P.ptr(42738,42743,1),new P.ptr(43124,43127,1),new P.ptr(43214,43215,1),new P.ptr(43256,43258,1),new P.ptr(43260,43310,50),new P.ptr(43311,43359,48),new P.ptr(43457,43469,1),new P.ptr(43486,43487,1),new P.ptr(43612,43615,1),new P.ptr(43742,43743,1),new P.ptr(43760,43761,1),new P.ptr(44011,64830,20819),new P.ptr(64831,65040,209),new P.ptr(65041,65049,1),new P.ptr(65072,65106,1),new P.ptr(65108,65121,1),new P.ptr(65123,65128,5),new P.ptr(65130,65131,1),new P.ptr(65281,65283,1),new P.ptr(65285,65290,1),new P.ptr(65292,65295,1),new P.ptr(65306,65307,1),new P.ptr(65311,65312,1),new P.ptr(65339,65341,1),new P.ptr(65343,65371,28),new P.ptr(65373,65375,2),new P.ptr(65376,65381,1)]),new IZ([new Q.ptr(65792,65794,1),new Q.ptr(66463,66512,49),new Q.ptr(66927,67671,744),new Q.ptr(67871,67903,32),new Q.ptr(68176,68184,1),new Q.ptr(68223,68336,113),new Q.ptr(68337,68342,1),new Q.ptr(68409,68415,1),new Q.ptr(68505,68508,1),new Q.ptr(69703,69709,1),new Q.ptr(69819,69820,1),new Q.ptr(69822,69825,1),new Q.ptr(69952,69955,1),new Q.ptr(70004,70005,1),new Q.ptr(70085,70089,1),new Q.ptr(70093,70107,14),new Q.ptr(70109,70111,1),new Q.ptr(70200,70205,1),new Q.ptr(70313,70731,418),new Q.ptr(70732,70735,1),new Q.ptr(70747,70749,2),new Q.ptr(70854,71105,251),new Q.ptr(71106,71127,1),new Q.ptr(71233,71235,1),new Q.ptr(71264,71276,1),new Q.ptr(71484,71486,1),new Q.ptr(72255,72262,1),new Q.ptr(72346,72348,1),new Q.ptr(72350,72354,1),new Q.ptr(72769,72773,1),new Q.ptr(72816,72817,1),new Q.ptr(74864,74868,1),new Q.ptr(92782,92783,1),new Q.ptr(92917,92983,66),new Q.ptr(92984,92987,1),new Q.ptr(92996,113823,20827),new Q.ptr(121479,121483,1),new Q.ptr(125278,125279,1)]),11);BB=new O.ptr(new IY([new P.ptr(95,8255,8160),new P.ptr(8256,8276,20),new P.ptr(65075,65076,1),new P.ptr(65101,65103,1),new P.ptr(65343,65343,1)]),IZ.nil,0);BC=new O.ptr(new IY([new P.ptr(45,1418,1373),new P.ptr(1470,5120,3650),new P.ptr(6150,8208,2058),new P.ptr(8209,8213,1),new P.ptr(11799,11802,3),new P.ptr(11834,11835,1),new P.ptr(11840,12316,476),new P.ptr(12336,12448,112),new P.ptr(65073,65074,1),new P.ptr(65112,65123,11),new P.ptr(65293,65293,1)]),IZ.nil,0);BD=new O.ptr(new IY([new P.ptr(41,93,52),new P.ptr(125,3899,3774),new P.ptr(3901,5788,1887),new P.ptr(8262,8318,56),new P.ptr(8334,8969,635),new P.ptr(8971,9002,31),new P.ptr(10089,10101,2),new P.ptr(10182,10215,33),new P.ptr(10217,10223,2),new P.ptr(10628,10648,2),new P.ptr(10713,10715,2),new P.ptr(10749,11811,1062),new P.ptr(11813,11817,2),new P.ptr(12297,12305,2),new P.ptr(12309,12315,2),new P.ptr(12318,12319,1),new P.ptr(64830,65048,218),new P.ptr(65078,65092,2),new P.ptr(65096,65114,18),new P.ptr(65116,65118,2),new P.ptr(65289,65341,52),new P.ptr(65373,65379,3)]),IZ.nil,1);BE=new O.ptr(new IY([new P.ptr(187,8217,8030),new P.ptr(8221,8250,29),new P.ptr(11779,11781,2),new P.ptr(11786,11789,3),new P.ptr(11805,11809,4)]),IZ.nil,0);BF=new O.ptr(new IY([new P.ptr(171,8216,8045),new P.ptr(8219,8220,1),new P.ptr(8223,8249,26),new P.ptr(11778,11780,2),new P.ptr(11785,11788,3),new P.ptr(11804,11808,4)]),IZ.nil,0);BG=new O.ptr(new IY([new P.ptr(33,35,1),new P.ptr(37,39,1),new P.ptr(42,46,2),new P.ptr(47,58,11),new P.ptr(59,63,4),new P.ptr(64,92,28),new P.ptr(161,167,6),new P.ptr(182,183,1),new P.ptr(191,894,703),new P.ptr(903,1370,467),new P.ptr(1371,1375,1),new P.ptr(1417,1472,55),new P.ptr(1475,1478,3),new P.ptr(1523,1524,1),new P.ptr(1545,1546,1),new P.ptr(1548,1549,1),new P.ptr(1563,1566,3),new P.ptr(1567,1642,75),new P.ptr(1643,1645,1),new P.ptr(1748,1792,44),new P.ptr(1793,1805,1),new P.ptr(2039,2041,1),new P.ptr(2096,2110,1),new P.ptr(2142,2404,262),new P.ptr(2405,2416,11),new P.ptr(2557,2800,243),new P.ptr(3572,3663,91),new P.ptr(3674,3675,1),new P.ptr(3844,3858,1),new P.ptr(3860,3973,113),new P.ptr(4048,4052,1),new P.ptr(4057,4058,1),new P.ptr(4170,4175,1),new P.ptr(4347,4960,613),new P.ptr(4961,4968,1),new P.ptr(5741,5742,1),new P.ptr(5867,5869,1),new P.ptr(5941,5942,1),new P.ptr(6100,6102,1),new P.ptr(6104,6106,1),new P.ptr(6144,6149,1),new P.ptr(6151,6154,1),new P.ptr(6468,6469,1),new P.ptr(6686,6687,1),new P.ptr(6816,6822,1),new P.ptr(6824,6829,1),new P.ptr(7002,7008,1),new P.ptr(7164,7167,1),new P.ptr(7227,7231,1),new P.ptr(7294,7295,1),new P.ptr(7360,7367,1),new P.ptr(7379,8214,835),new P.ptr(8215,8224,9),new P.ptr(8225,8231,1),new P.ptr(8240,8248,1),new P.ptr(8251,8254,1),new P.ptr(8257,8259,1),new P.ptr(8263,8273,1),new P.ptr(8275,8277,2),new P.ptr(8278,8286,1),new P.ptr(11513,11516,1),new P.ptr(11518,11519,1),new P.ptr(11632,11776,144),new P.ptr(11777,11782,5),new P.ptr(11783,11784,1),new P.ptr(11787,11790,3),new P.ptr(11791,11798,1),new P.ptr(11800,11801,1),new P.ptr(11803,11806,3),new P.ptr(11807,11818,11),new P.ptr(11819,11822,1),new P.ptr(11824,11833,1),new P.ptr(11836,11839,1),new P.ptr(11841,11843,2),new P.ptr(11844,11849,1),new P.ptr(12289,12291,1),new P.ptr(12349,12539,190),new P.ptr(42238,42239,1),new P.ptr(42509,42511,1),new P.ptr(42611,42622,11),new P.ptr(42738,42743,1),new P.ptr(43124,43127,1),new P.ptr(43214,43215,1),new P.ptr(43256,43258,1),new P.ptr(43260,43310,50),new P.ptr(43311,43359,48),new P.ptr(43457,43469,1),new P.ptr(43486,43487,1),new P.ptr(43612,43615,1),new P.ptr(43742,43743,1),new P.ptr(43760,43761,1),new P.ptr(44011,65040,21029),new P.ptr(65041,65046,1),new P.ptr(65049,65072,23),new P.ptr(65093,65094,1),new P.ptr(65097,65100,1),new P.ptr(65104,65106,1),new P.ptr(65108,65111,1),new P.ptr(65119,65121,1),new P.ptr(65128,65130,2),new P.ptr(65131,65281,150),new P.ptr(65282,65283,1),new P.ptr(65285,65287,1),new P.ptr(65290,65294,2),new P.ptr(65295,65306,11),new P.ptr(65307,65311,4),new P.ptr(65312,65340,28),new P.ptr(65377,65380,3),new P.ptr(65381,65381,1)]),new IZ([new Q.ptr(65792,65792,1),new Q.ptr(65793,65794,1),new Q.ptr(66463,66512,49),new Q.ptr(66927,67671,744),new Q.ptr(67871,67903,32),new Q.ptr(68176,68184,1),new Q.ptr(68223,68336,113),new Q.ptr(68337,68342,1),new Q.ptr(68409,68415,1),new Q.ptr(68505,68508,1),new Q.ptr(69703,69709,1),new Q.ptr(69819,69820,1),new Q.ptr(69822,69825,1),new Q.ptr(69952,69955,1),new Q.ptr(70004,70005,1),new Q.ptr(70085,70089,1),new Q.ptr(70093,70107,14),new Q.ptr(70109,70111,1),new Q.ptr(70200,70205,1),new Q.ptr(70313,70731,418),new Q.ptr(70732,70735,1),new Q.ptr(70747,70749,2),new Q.ptr(70854,71105,251),new Q.ptr(71106,71127,1),new Q.ptr(71233,71235,1),new Q.ptr(71264,71276,1),new Q.ptr(71484,71486,1),new Q.ptr(72255,72262,1),new Q.ptr(72346,72348,1),new Q.ptr(72350,72354,1),new Q.ptr(72769,72773,1),new Q.ptr(72816,72817,1),new Q.ptr(74864,74868,1),new Q.ptr(92782,92783,1),new Q.ptr(92917,92983,66),new Q.ptr(92984,92987,1),new Q.ptr(92996,113823,20827),new Q.ptr(121479,121483,1),new Q.ptr(125278,125279,1)]),8);BH=new O.ptr(new IY([new P.ptr(40,91,51),new P.ptr(123,3898,3775),new P.ptr(3900,5787,1887),new P.ptr(8218,8222,4),new P.ptr(8261,8317,56),new P.ptr(8333,8968,635),new P.ptr(8970,9001,31),new P.ptr(10088,10100,2),new P.ptr(10181,10214,33),new P.ptr(10216,10222,2),new P.ptr(10627,10647,2),new P.ptr(10712,10714,2),new P.ptr(10748,11810,1062),new P.ptr(11812,11816,2),new P.ptr(11842,12296,454),new P.ptr(12298,12304,2),new P.ptr(12308,12314,2),new P.ptr(12317,64831,52514),new P.ptr(65047,65077,30),new P.ptr(65079,65091,2),new P.ptr(65095,65113,18),new P.ptr(65115,65117,2),new P.ptr(65288,65339,51),new P.ptr(65371,65375,4),new P.ptr(65378,65378,1)]),IZ.nil,1);BI=new O.ptr(new IY([new P.ptr(36,43,7),new P.ptr(60,62,1),new P.ptr(94,96,2),new P.ptr(124,126,2),new P.ptr(162,166,1),new P.ptr(168,169,1),new P.ptr(172,174,2),new P.ptr(175,177,1),new P.ptr(180,184,4),new P.ptr(215,247,32),new P.ptr(706,709,1),new P.ptr(722,735,1),new P.ptr(741,747,1),new P.ptr(749,751,2),new P.ptr(752,767,1),new P.ptr(885,900,15),new P.ptr(901,1014,113),new P.ptr(1154,1421,267),new P.ptr(1422,1423,1),new P.ptr(1542,1544,1),new P.ptr(1547,1550,3),new P.ptr(1551,1758,207),new P.ptr(1769,1789,20),new P.ptr(1790,2038,248),new P.ptr(2546,2547,1),new P.ptr(2554,2555,1),new P.ptr(2801,2928,127),new P.ptr(3059,3066,1),new P.ptr(3199,3407,208),new P.ptr(3449,3647,198),new P.ptr(3841,3843,1),new P.ptr(3859,3861,2),new P.ptr(3862,3863,1),new P.ptr(3866,3871,1),new P.ptr(3892,3896,2),new P.ptr(4030,4037,1),new P.ptr(4039,4044,1),new P.ptr(4046,4047,1),new P.ptr(4053,4056,1),new P.ptr(4254,4255,1),new P.ptr(5008,5017,1),new P.ptr(6107,6464,357),new P.ptr(6622,6655,1),new P.ptr(7009,7018,1),new P.ptr(7028,7036,1),new P.ptr(8125,8127,2),new P.ptr(8128,8129,1),new P.ptr(8141,8143,1),new P.ptr(8157,8159,1),new P.ptr(8173,8175,1),new P.ptr(8189,8190,1),new P.ptr(8260,8274,14),new P.ptr(8314,8316,1),new P.ptr(8330,8332,1),new P.ptr(8352,8383,1),new P.ptr(8448,8449,1),new P.ptr(8451,8454,1),new P.ptr(8456,8457,1),new P.ptr(8468,8470,2),new P.ptr(8471,8472,1),new P.ptr(8478,8483,1),new P.ptr(8485,8489,2),new P.ptr(8494,8506,12),new P.ptr(8507,8512,5),new P.ptr(8513,8516,1),new P.ptr(8522,8525,1),new P.ptr(8527,8586,59),new P.ptr(8587,8592,5),new P.ptr(8593,8967,1),new P.ptr(8972,9000,1),new P.ptr(9003,9254,1),new P.ptr(9280,9290,1),new P.ptr(9372,9449,1),new P.ptr(9472,10087,1),new P.ptr(10132,10180,1),new P.ptr(10183,10213,1),new P.ptr(10224,10626,1),new P.ptr(10649,10711,1),new P.ptr(10716,10747,1),new P.ptr(10750,11123,1),new P.ptr(11126,11157,1),new P.ptr(11160,11193,1),new P.ptr(11197,11208,1),new P.ptr(11210,11218,1),new P.ptr(11244,11247,1),new P.ptr(11493,11498,1),new P.ptr(11904,11929,1),new P.ptr(11931,12019,1),new P.ptr(12032,12245,1),new P.ptr(12272,12283,1),new P.ptr(12292,12306,14),new P.ptr(12307,12320,13),new P.ptr(12342,12343,1),new P.ptr(12350,12351,1),new P.ptr(12443,12444,1),new P.ptr(12688,12689,1),new P.ptr(12694,12703,1),new P.ptr(12736,12771,1),new P.ptr(12800,12830,1),new P.ptr(12842,12871,1),new P.ptr(12880,12896,16),new P.ptr(12897,12927,1),new P.ptr(12938,12976,1),new P.ptr(12992,13054,1),new P.ptr(13056,13311,1),new P.ptr(19904,19967,1),new P.ptr(42128,42182,1),new P.ptr(42752,42774,1),new P.ptr(42784,42785,1),new P.ptr(42889,42890,1),new P.ptr(43048,43051,1),new P.ptr(43062,43065,1),new P.ptr(43639,43641,1),new P.ptr(43867,64297,20430),new P.ptr(64434,64449,1),new P.ptr(65020,65021,1),new P.ptr(65122,65124,2),new P.ptr(65125,65126,1),new P.ptr(65129,65284,155),new P.ptr(65291,65308,17),new P.ptr(65309,65310,1),new P.ptr(65342,65344,2),new P.ptr(65372,65374,2),new P.ptr(65504,65510,1),new P.ptr(65512,65518,1),new P.ptr(65532,65533,1)]),new IZ([new Q.ptr(65847,65855,1),new Q.ptr(65913,65929,1),new Q.ptr(65932,65934,1),new Q.ptr(65936,65947,1),new Q.ptr(65952,66000,48),new Q.ptr(66001,66044,1),new Q.ptr(67703,67704,1),new Q.ptr(68296,71487,3191),new Q.ptr(92988,92991,1),new Q.ptr(92997,113820,20823),new Q.ptr(118784,119029,1),new Q.ptr(119040,119078,1),new Q.ptr(119081,119140,1),new Q.ptr(119146,119148,1),new Q.ptr(119171,119172,1),new Q.ptr(119180,119209,1),new Q.ptr(119214,119272,1),new Q.ptr(119296,119361,1),new Q.ptr(119365,119552,187),new Q.ptr(119553,119638,1),new Q.ptr(120513,120539,26),new Q.ptr(120571,120597,26),new Q.ptr(120629,120655,26),new Q.ptr(120687,120713,26),new Q.ptr(120745,120771,26),new Q.ptr(120832,121343,1),new Q.ptr(121399,121402,1),new Q.ptr(121453,121460,1),new Q.ptr(121462,121475,1),new Q.ptr(121477,121478,1),new Q.ptr(126704,126705,1),new Q.ptr(126976,127019,1),new Q.ptr(127024,127123,1),new Q.ptr(127136,127150,1),new Q.ptr(127153,127167,1),new Q.ptr(127169,127183,1),new Q.ptr(127185,127221,1),new Q.ptr(127248,127278,1),new Q.ptr(127280,127339,1),new Q.ptr(127344,127404,1),new Q.ptr(127462,127490,1),new Q.ptr(127504,127547,1),new Q.ptr(127552,127560,1),new Q.ptr(127568,127569,1),new Q.ptr(127584,127589,1),new Q.ptr(127744,128724,1),new Q.ptr(128736,128748,1),new Q.ptr(128752,128760,1),new Q.ptr(128768,128883,1),new Q.ptr(128896,128980,1),new Q.ptr(129024,129035,1),new Q.ptr(129040,129095,1),new Q.ptr(129104,129113,1),new Q.ptr(129120,129159,1),new Q.ptr(129168,129197,1),new Q.ptr(129280,129291,1),new Q.ptr(129296,129342,1),new Q.ptr(129344,129356,1),new Q.ptr(129360,129387,1),new Q.ptr(129408,129431,1),new Q.ptr(129472,129488,16),new Q.ptr(129489,129510,1)]),10);BJ=new O.ptr(new IY([new P.ptr(36,162,126),new P.ptr(163,165,1),new P.ptr(1423,1547,124),new P.ptr(2546,2547,1),new P.ptr(2555,2801,246),new P.ptr(3065,3647,582),new P.ptr(6107,8352,2245),new P.ptr(8353,8383,1),new P.ptr(43064,65020,21956),new P.ptr(65129,65284,155),new P.ptr(65504,65505,1),new P.ptr(65509,65510,1)]),IZ.nil,2);BK=new O.ptr(new IY([new P.ptr(94,96,2),new P.ptr(168,175,7),new P.ptr(180,184,4),new P.ptr(706,709,1),new P.ptr(722,735,1),new P.ptr(741,747,1),new P.ptr(749,751,2),new P.ptr(752,767,1),new P.ptr(885,900,15),new P.ptr(901,8125,7224),new P.ptr(8127,8129,1),new P.ptr(8141,8143,1),new P.ptr(8157,8159,1),new P.ptr(8173,8175,1),new P.ptr(8189,8190,1),new P.ptr(12443,12444,1),new P.ptr(42752,42774,1),new P.ptr(42784,42785,1),new P.ptr(42889,42890,1),new P.ptr(43867,64434,20567),new P.ptr(64435,64449,1),new P.ptr(65342,65344,2),new P.ptr(65507,65507,1)]),new IZ([new Q.ptr(127995,127995,1),new Q.ptr(127996,127999,1)]),3);BL=new O.ptr(new IY([new P.ptr(43,60,17),new P.ptr(61,62,1),new P.ptr(124,126,2),new P.ptr(172,177,5),new P.ptr(215,247,32),new P.ptr(1014,1542,528),new P.ptr(1543,1544,1),new P.ptr(8260,8274,14),new P.ptr(8314,8316,1),new P.ptr(8330,8332,1),new P.ptr(8472,8512,40),new P.ptr(8513,8516,1),new P.ptr(8523,8592,69),new P.ptr(8593,8596,1),new P.ptr(8602,8603,1),new P.ptr(8608,8614,3),new P.ptr(8622,8654,32),new P.ptr(8655,8658,3),new P.ptr(8660,8692,32),new P.ptr(8693,8959,1),new P.ptr(8992,8993,1),new P.ptr(9084,9115,31),new P.ptr(9116,9139,1),new P.ptr(9180,9185,1),new P.ptr(9655,9665,10),new P.ptr(9720,9727,1),new P.ptr(9839,10176,337),new P.ptr(10177,10180,1),new P.ptr(10183,10213,1),new P.ptr(10224,10239,1),new P.ptr(10496,10626,1),new P.ptr(10649,10711,1),new P.ptr(10716,10747,1),new P.ptr(10750,11007,1),new P.ptr(11056,11076,1),new P.ptr(11079,11084,1),new P.ptr(64297,65122,825),new P.ptr(65124,65126,1),new P.ptr(65291,65308,17),new P.ptr(65309,65310,1),new P.ptr(65372,65374,2),new P.ptr(65506,65513,7),new P.ptr(65514,65516,1)]),new IZ([new Q.ptr(120513,120539,26),new Q.ptr(120571,120597,26),new Q.ptr(120629,120655,26),new Q.ptr(120687,120713,26),new Q.ptr(120745,120771,26),new Q.ptr(126704,126705,1)]),5);BM=new O.ptr(new IY([new P.ptr(166,169,3),new P.ptr(174,176,2),new P.ptr(1154,1421,267),new P.ptr(1422,1550,128),new P.ptr(1551,1758,207),new P.ptr(1769,1789,20),new P.ptr(1790,2038,248),new P.ptr(2554,2928,374),new P.ptr(3059,3064,1),new P.ptr(3066,3199,133),new P.ptr(3407,3449,42),new P.ptr(3841,3843,1),new P.ptr(3859,3861,2),new P.ptr(3862,3863,1),new P.ptr(3866,3871,1),new P.ptr(3892,3896,2),new P.ptr(4030,4037,1),new P.ptr(4039,4044,1),new P.ptr(4046,4047,1),new P.ptr(4053,4056,1),new P.ptr(4254,4255,1),new P.ptr(5008,5017,1),new P.ptr(6464,6622,158),new P.ptr(6623,6655,1),new P.ptr(7009,7018,1),new P.ptr(7028,7036,1),new P.ptr(8448,8449,1),new P.ptr(8451,8454,1),new P.ptr(8456,8457,1),new P.ptr(8468,8470,2),new P.ptr(8471,8478,7),new P.ptr(8479,8483,1),new P.ptr(8485,8489,2),new P.ptr(8494,8506,12),new P.ptr(8507,8522,15),new P.ptr(8524,8525,1),new P.ptr(8527,8586,59),new P.ptr(8587,8597,10),new P.ptr(8598,8601,1),new P.ptr(8604,8607,1),new P.ptr(8609,8610,1),new P.ptr(8612,8613,1),new P.ptr(8615,8621,1),new P.ptr(8623,8653,1),new P.ptr(8656,8657,1),new P.ptr(8659,8661,2),new P.ptr(8662,8691,1),new P.ptr(8960,8967,1),new P.ptr(8972,8991,1),new P.ptr(8994,9000,1),new P.ptr(9003,9083,1),new P.ptr(9085,9114,1),new P.ptr(9140,9179,1),new P.ptr(9186,9254,1),new P.ptr(9280,9290,1),new P.ptr(9372,9449,1),new P.ptr(9472,9654,1),new P.ptr(9656,9664,1),new P.ptr(9666,9719,1),new P.ptr(9728,9838,1),new P.ptr(9840,10087,1),new P.ptr(10132,10175,1),new P.ptr(10240,10495,1),new P.ptr(11008,11055,1),new P.ptr(11077,11078,1),new P.ptr(11085,11123,1),new P.ptr(11126,11157,1),new P.ptr(11160,11193,1),new P.ptr(11197,11208,1),new P.ptr(11210,11218,1),new P.ptr(11244,11247,1),new P.ptr(11493,11498,1),new P.ptr(11904,11929,1),new P.ptr(11931,12019,1),new P.ptr(12032,12245,1),new P.ptr(12272,12283,1),new P.ptr(12292,12306,14),new P.ptr(12307,12320,13),new P.ptr(12342,12343,1),new P.ptr(12350,12351,1),new P.ptr(12688,12689,1),new P.ptr(12694,12703,1),new P.ptr(12736,12771,1),new P.ptr(12800,12830,1),new P.ptr(12842,12871,1),new P.ptr(12880,12896,16),new P.ptr(12897,12927,1),new P.ptr(12938,12976,1),new P.ptr(12992,13054,1),new P.ptr(13056,13311,1),new P.ptr(19904,19967,1),new P.ptr(42128,42182,1),new P.ptr(43048,43051,1),new P.ptr(43062,43063,1),new P.ptr(43065,43639,574),new P.ptr(43640,43641,1),new P.ptr(65021,65508,487),new P.ptr(65512,65517,5),new P.ptr(65518,65532,14),new P.ptr(65533,65533,1)]),new IZ([new Q.ptr(65847,65847,1),new Q.ptr(65848,65855,1),new Q.ptr(65913,65929,1),new Q.ptr(65932,65934,1),new Q.ptr(65936,65947,1),new Q.ptr(65952,66000,48),new Q.ptr(66001,66044,1),new Q.ptr(67703,67704,1),new Q.ptr(68296,71487,3191),new Q.ptr(92988,92991,1),new Q.ptr(92997,113820,20823),new Q.ptr(118784,119029,1),new Q.ptr(119040,119078,1),new Q.ptr(119081,119140,1),new Q.ptr(119146,119148,1),new Q.ptr(119171,119172,1),new Q.ptr(119180,119209,1),new Q.ptr(119214,119272,1),new Q.ptr(119296,119361,1),new Q.ptr(119365,119552,187),new Q.ptr(119553,119638,1),new Q.ptr(120832,121343,1),new Q.ptr(121399,121402,1),new Q.ptr(121453,121460,1),new Q.ptr(121462,121475,1),new Q.ptr(121477,121478,1),new Q.ptr(126976,127019,1),new Q.ptr(127024,127123,1),new Q.ptr(127136,127150,1),new Q.ptr(127153,127167,1),new Q.ptr(127169,127183,1),new Q.ptr(127185,127221,1),new Q.ptr(127248,127278,1),new Q.ptr(127280,127339,1),new Q.ptr(127344,127404,1),new Q.ptr(127462,127490,1),new Q.ptr(127504,127547,1),new Q.ptr(127552,127560,1),new Q.ptr(127568,127569,1),new Q.ptr(127584,127589,1),new Q.ptr(127744,127994,1),new Q.ptr(128000,128724,1),new Q.ptr(128736,128748,1),new Q.ptr(128752,128760,1),new Q.ptr(128768,128883,1),new Q.ptr(128896,128980,1),new Q.ptr(129024,129035,1),new Q.ptr(129040,129095,1),new Q.ptr(129104,129113,1),new Q.ptr(129120,129159,1),new Q.ptr(129168,129197,1),new Q.ptr(129280,129291,1),new Q.ptr(129296,129342,1),new Q.ptr(129344,129356,1),new Q.ptr(129360,129387,1),new Q.ptr(129408,129431,1),new Q.ptr(129472,129488,16),new Q.ptr(129489,129510,1)]),2);BN=new O.ptr(new IY([new P.ptr(32,160,128),new P.ptr(5760,8192,2432),new P.ptr(8193,8202,1),new P.ptr(8232,8233,1),new P.ptr(8239,8287,48),new P.ptr(12288,12288,1)]),IZ.nil,1);BO=new O.ptr(new IY([new P.ptr(8232,8232,1)]),IZ.nil,0);BP=new O.ptr(new IY([new P.ptr(8233,8233,1)]),IZ.nil,0);BQ=new O.ptr(new IY([new P.ptr(32,160,128),new P.ptr(5760,8192,2432),new P.ptr(8193,8202,1),new P.ptr(8239,8287,48),new P.ptr(12288,12288,1)]),IZ.nil,1);$pkg.Cc=AI;$pkg.Cf=AJ;$pkg.Co=AK;$pkg.Cs=AL;$pkg.Digit=AX;$pkg.Nd=AX;$pkg.Letter=AM;$pkg.L=AM;$pkg.Lm=AO;$pkg.Lo=AP;$pkg.Ll=AN;$pkg.M=AS;$pkg.Mc=AT;$pkg.Me=AU;$pkg.Mn=AV;$pkg.Nl=AY;$pkg.No=AZ;$pkg.N=AW;$pkg.C=AH;$pkg.Pc=BB;$pkg.Pd=BC;$pkg.Pe=BD;$pkg.Pf=BE;$pkg.Pi=BF;$pkg.Po=BG;$pkg.Ps=BH;$pkg.P=BA;$pkg.Sc=BJ;$pkg.Sk=BK;$pkg.Sm=BL;$pkg.So=BM;$pkg.Z=BN;$pkg.S=BI;$pkg.PrintRanges=new JB([$pkg.L,$pkg.M,$pkg.N,$pkg.P,$pkg.S]);$pkg.Lt=AQ;$pkg.Lu=AR;$pkg.Zl=BO;$pkg.Zp=BP;$pkg.Zs=BQ;$pkg.Categories=$makeMap($String.keyFor,[{k:\"C\",v:$pkg.C},{k:\"Cc\",v:$pkg.Cc},{k:\"Cf\",v:$pkg.Cf},{k:\"Co\",v:$pkg.Co},{k:\"Cs\",v:$pkg.Cs},{k:\"L\",v:$pkg.L},{k:\"Ll\",v:$pkg.Ll},{k:\"Lm\",v:$pkg.Lm},{k:\"Lo\",v:$pkg.Lo},{k:\"Lt\",v:$pkg.Lt},{k:\"Lu\",v:$pkg.Lu},{k:\"M\",v:$pkg.M},{k:\"Mc\",v:$pkg.Mc},{k:\"Me\",v:$pkg.Me},{k:\"Mn\",v:$pkg.Mn},{k:\"N\",v:$pkg.N},{k:\"Nd\",v:$pkg.Nd},{k:\"Nl\",v:$pkg.Nl},{k:\"No\",v:$pkg.No},{k:\"P\",v:$pkg.P},{k:\"Pc\",v:$pkg.Pc},{k:\"Pd\",v:$pkg.Pd},{k:\"Pe\",v:$pkg.Pe},{k:\"Pf\",v:$pkg.Pf},{k:\"Pi\",v:$pkg.Pi},{k:\"Po\",v:$pkg.Po},{k:\"Ps\",v:$pkg.Ps},{k:\"S\",v:$pkg.S},{k:\"Sc\",v:$pkg.Sc},{k:\"Sk\",v:$pkg.Sk},{k:\"Sm\",v:$pkg.Sm},{k:\"So\",v:$pkg.So},{k:\"Z\",v:$pkg.Z},{k:\"Zl\",v:$pkg.Zl},{k:\"Zp\",v:$pkg.Zp},{k:\"Zs\",v:$pkg.Zs}]);BR=new O.ptr(new IY([]),new IZ([new Q.ptr(125184,125258,1),new Q.ptr(125264,125273,1),new Q.ptr(125278,125279,1)]),0);BS=new O.ptr(new IY([]),new IZ([new Q.ptr(71424,71449,1),new Q.ptr(71453,71467,1),new Q.ptr(71472,71487,1)]),0);BT=new O.ptr(new IY([]),new IZ([new Q.ptr(82944,83526,1)]),0);BU=new O.ptr(new IY([new P.ptr(1536,1540,1),new P.ptr(1542,1547,1),new P.ptr(1549,1562,1),new P.ptr(1564,1564,1),new P.ptr(1566,1566,1),new P.ptr(1568,1599,1),new P.ptr(1601,1610,1),new P.ptr(1622,1647,1),new P.ptr(1649,1756,1),new P.ptr(1758,1791,1),new P.ptr(1872,1919,1),new P.ptr(2208,2228,1),new P.ptr(2230,2237,1),new P.ptr(2260,2273,1),new P.ptr(2275,2303,1),new P.ptr(64336,64449,1),new P.ptr(64467,64829,1),new P.ptr(64848,64911,1),new P.ptr(64914,64967,1),new P.ptr(65008,65021,1),new P.ptr(65136,65140,1),new P.ptr(65142,65276,1)]),new IZ([new Q.ptr(69216,69246,1),new Q.ptr(126464,126467,1),new Q.ptr(126469,126495,1),new Q.ptr(126497,126498,1),new Q.ptr(126500,126500,1),new Q.ptr(126503,126503,1),new Q.ptr(126505,126514,1),new Q.ptr(126516,126519,1),new Q.ptr(126521,126521,1),new Q.ptr(126523,126523,1),new Q.ptr(126530,126530,1),new Q.ptr(126535,126535,1),new Q.ptr(126537,126537,1),new Q.ptr(126539,126539,1),new Q.ptr(126541,126543,1),new Q.ptr(126545,126546,1),new Q.ptr(126548,126548,1),new Q.ptr(126551,126551,1),new Q.ptr(126553,126553,1),new Q.ptr(126555,126555,1),new Q.ptr(126557,126557,1),new Q.ptr(126559,126559,1),new Q.ptr(126561,126562,1),new Q.ptr(126564,126564,1),new Q.ptr(126567,126570,1),new Q.ptr(126572,126578,1),new Q.ptr(126580,126583,1),new Q.ptr(126585,126588,1),new Q.ptr(126590,126590,1),new Q.ptr(126592,126601,1),new Q.ptr(126603,126619,1),new Q.ptr(126625,126627,1),new Q.ptr(126629,126633,1),new Q.ptr(126635,126651,1),new Q.ptr(126704,126705,1)]),0);BV=new O.ptr(new IY([new P.ptr(1329,1366,1),new P.ptr(1369,1375,1),new P.ptr(1377,1415,1),new P.ptr(1418,1418,1),new P.ptr(1421,1423,1),new P.ptr(64275,64279,1)]),IZ.nil,0);BW=new O.ptr(new IY([]),new IZ([new Q.ptr(68352,68405,1),new Q.ptr(68409,68415,1)]),0);BX=new O.ptr(new IY([new P.ptr(6912,6987,1),new P.ptr(6992,7036,1)]),IZ.nil,0);BY=new O.ptr(new IY([new P.ptr(42656,42743,1)]),new IZ([new Q.ptr(92160,92728,1)]),0);BZ=new O.ptr(new IY([]),new IZ([new Q.ptr(92880,92909,1),new Q.ptr(92912,92917,1)]),0);CA=new O.ptr(new IY([new P.ptr(7104,7155,1),new P.ptr(7164,7167,1)]),IZ.nil,0);CB=new O.ptr(new IY([new P.ptr(2432,2435,1),new P.ptr(2437,2444,1),new P.ptr(2447,2448,1),new P.ptr(2451,2472,1),new P.ptr(2474,2480,1),new P.ptr(2482,2482,1),new P.ptr(2486,2489,1),new P.ptr(2492,2500,1),new P.ptr(2503,2504,1),new P.ptr(2507,2510,1),new P.ptr(2519,2519,1),new P.ptr(2524,2525,1),new P.ptr(2527,2531,1),new P.ptr(2534,2557,1)]),IZ.nil,0);CC=new O.ptr(new IY([]),new IZ([new Q.ptr(72704,72712,1),new Q.ptr(72714,72758,1),new Q.ptr(72760,72773,1),new Q.ptr(72784,72812,1)]),0);CD=new O.ptr(new IY([new P.ptr(746,747,1),new P.ptr(12549,12590,1),new P.ptr(12704,12730,1)]),IZ.nil,0);CE=new O.ptr(new IY([]),new IZ([new Q.ptr(69632,69709,1),new Q.ptr(69714,69743,1),new Q.ptr(69759,69759,1)]),0);CF=new O.ptr(new IY([new P.ptr(10240,10495,1)]),IZ.nil,0);CG=new O.ptr(new IY([new P.ptr(6656,6683,1),new P.ptr(6686,6687,1)]),IZ.nil,0);CH=new O.ptr(new IY([new P.ptr(5952,5971,1)]),IZ.nil,0);CI=new O.ptr(new IY([new P.ptr(5120,5759,1),new P.ptr(6320,6389,1)]),IZ.nil,0);CJ=new O.ptr(new IY([]),new IZ([new Q.ptr(66208,66256,1)]),0);CK=new O.ptr(new IY([]),new IZ([new Q.ptr(66864,66915,1),new Q.ptr(66927,66927,1)]),0);CL=new O.ptr(new IY([]),new IZ([new Q.ptr(69888,69940,1),new Q.ptr(69942,69955,1)]),0);CM=new O.ptr(new IY([new P.ptr(43520,43574,1),new P.ptr(43584,43597,1),new P.ptr(43600,43609,1),new P.ptr(43612,43615,1)]),IZ.nil,0);CN=new O.ptr(new IY([new P.ptr(5024,5109,1),new P.ptr(5112,5117,1),new P.ptr(43888,43967,1)]),IZ.nil,0);CO=new O.ptr(new IY([new P.ptr(0,64,1),new P.ptr(91,96,1),new P.ptr(123,169,1),new P.ptr(171,185,1),new P.ptr(187,191,1),new P.ptr(215,215,1),new P.ptr(247,247,1),new P.ptr(697,735,1),new P.ptr(741,745,1),new P.ptr(748,767,1),new P.ptr(884,884,1),new P.ptr(894,894,1),new P.ptr(901,901,1),new P.ptr(903,903,1),new P.ptr(1417,1417,1),new P.ptr(1541,1541,1),new P.ptr(1548,1548,1),new P.ptr(1563,1563,1),new P.ptr(1567,1567,1),new P.ptr(1600,1600,1),new P.ptr(1757,1757,1),new P.ptr(2274,2274,1),new P.ptr(2404,2405,1),new P.ptr(3647,3647,1),new P.ptr(4053,4056,1),new P.ptr(4347,4347,1),new P.ptr(5867,5869,1),new P.ptr(5941,5942,1),new P.ptr(6146,6147,1),new P.ptr(6149,6149,1),new P.ptr(7379,7379,1),new P.ptr(7393,7393,1),new P.ptr(7401,7404,1),new P.ptr(7406,7411,1),new P.ptr(7413,7415,1),new P.ptr(8192,8203,1),new P.ptr(8206,8292,1),new P.ptr(8294,8304,1),new P.ptr(8308,8318,1),new P.ptr(8320,8334,1),new P.ptr(8352,8383,1),new P.ptr(8448,8485,1),new P.ptr(8487,8489,1),new P.ptr(8492,8497,1),new P.ptr(8499,8525,1),new P.ptr(8527,8543,1),new P.ptr(8585,8587,1),new P.ptr(8592,9254,1),new P.ptr(9280,9290,1),new P.ptr(9312,10239,1),new P.ptr(10496,11123,1),new P.ptr(11126,11157,1),new P.ptr(11160,11193,1),new P.ptr(11197,11208,1),new P.ptr(11210,11218,1),new P.ptr(11244,11247,1),new P.ptr(11776,11849,1),new P.ptr(12272,12283,1),new P.ptr(12288,12292,1),new P.ptr(12294,12294,1),new P.ptr(12296,12320,1),new P.ptr(12336,12343,1),new P.ptr(12348,12351,1),new P.ptr(12443,12444,1),new P.ptr(12448,12448,1),new P.ptr(12539,12540,1),new P.ptr(12688,12703,1),new P.ptr(12736,12771,1),new P.ptr(12832,12895,1),new P.ptr(12927,13007,1),new P.ptr(13144,13311,1),new P.ptr(19904,19967,1),new P.ptr(42752,42785,1),new P.ptr(42888,42890,1),new P.ptr(43056,43065,1),new P.ptr(43310,43310,1),new P.ptr(43471,43471,1),new P.ptr(43867,43867,1),new P.ptr(64830,64831,1),new P.ptr(65040,65049,1),new P.ptr(65072,65106,1),new P.ptr(65108,65126,1),new P.ptr(65128,65131,1),new P.ptr(65279,65279,1),new P.ptr(65281,65312,1),new P.ptr(65339,65344,1),new P.ptr(65371,65381,1),new P.ptr(65392,65392,1),new P.ptr(65438,65439,1),new P.ptr(65504,65510,1),new P.ptr(65512,65518,1),new P.ptr(65529,65533,1)]),new IZ([new Q.ptr(65792,65794,1),new Q.ptr(65799,65843,1),new Q.ptr(65847,65855,1),new Q.ptr(65936,65947,1),new Q.ptr(66000,66044,1),new Q.ptr(66273,66299,1),new Q.ptr(113824,113827,1),new Q.ptr(118784,119029,1),new Q.ptr(119040,119078,1),new Q.ptr(119081,119142,1),new Q.ptr(119146,119162,1),new Q.ptr(119171,119172,1),new Q.ptr(119180,119209,1),new Q.ptr(119214,119272,1),new Q.ptr(119552,119638,1),new Q.ptr(119648,119665,1),new Q.ptr(119808,119892,1),new Q.ptr(119894,119964,1),new Q.ptr(119966,119967,1),new Q.ptr(119970,119970,1),new Q.ptr(119973,119974,1),new Q.ptr(119977,119980,1),new Q.ptr(119982,119993,1),new Q.ptr(119995,119995,1),new Q.ptr(119997,120003,1),new Q.ptr(120005,120069,1),new Q.ptr(120071,120074,1),new Q.ptr(120077,120084,1),new Q.ptr(120086,120092,1),new Q.ptr(120094,120121,1),new Q.ptr(120123,120126,1),new Q.ptr(120128,120132,1),new Q.ptr(120134,120134,1),new Q.ptr(120138,120144,1),new Q.ptr(120146,120485,1),new Q.ptr(120488,120779,1),new Q.ptr(120782,120831,1),new Q.ptr(126976,127019,1),new Q.ptr(127024,127123,1),new Q.ptr(127136,127150,1),new Q.ptr(127153,127167,1),new Q.ptr(127169,127183,1),new Q.ptr(127185,127221,1),new Q.ptr(127232,127244,1),new Q.ptr(127248,127278,1),new Q.ptr(127280,127339,1),new Q.ptr(127344,127404,1),new Q.ptr(127462,127487,1),new Q.ptr(127489,127490,1),new Q.ptr(127504,127547,1),new Q.ptr(127552,127560,1),new Q.ptr(127568,127569,1),new Q.ptr(127584,127589,1),new Q.ptr(127744,128724,1),new Q.ptr(128736,128748,1),new Q.ptr(128752,128760,1),new Q.ptr(128768,128883,1),new Q.ptr(128896,128980,1),new Q.ptr(129024,129035,1),new Q.ptr(129040,129095,1),new Q.ptr(129104,129113,1),new Q.ptr(129120,129159,1),new Q.ptr(129168,129197,1),new Q.ptr(129280,129291,1),new Q.ptr(129296,129342,1),new Q.ptr(129344,129356,1),new Q.ptr(129360,129387,1),new Q.ptr(129408,129431,1),new Q.ptr(129472,129472,1),new Q.ptr(129488,129510,1),new Q.ptr(917505,917505,1),new Q.ptr(917536,917631,1)]),7);CP=new O.ptr(new IY([new P.ptr(994,1007,1),new P.ptr(11392,11507,1),new P.ptr(11513,11519,1)]),IZ.nil,0);CQ=new O.ptr(new IY([]),new IZ([new Q.ptr(73728,74649,1),new Q.ptr(74752,74862,1),new Q.ptr(74864,74868,1),new Q.ptr(74880,75075,1)]),0);CR=new O.ptr(new IY([]),new IZ([new Q.ptr(67584,67589,1),new Q.ptr(67592,67592,1),new Q.ptr(67594,67637,1),new Q.ptr(67639,67640,1),new Q.ptr(67644,67644,1),new Q.ptr(67647,67647,1)]),0);CS=new O.ptr(new IY([new P.ptr(1024,1156,1),new P.ptr(1159,1327,1),new P.ptr(7296,7304,1),new P.ptr(7467,7467,1),new P.ptr(7544,7544,1),new P.ptr(11744,11775,1),new P.ptr(42560,42655,1),new P.ptr(65070,65071,1)]),IZ.nil,0);CT=new O.ptr(new IY([]),new IZ([new Q.ptr(66560,66639,1)]),0);CU=new O.ptr(new IY([new P.ptr(2304,2384,1),new P.ptr(2387,2403,1),new P.ptr(2406,2431,1),new P.ptr(43232,43261,1)]),IZ.nil,0);CV=new O.ptr(new IY([]),new IZ([new Q.ptr(113664,113770,1),new Q.ptr(113776,113788,1),new Q.ptr(113792,113800,1),new Q.ptr(113808,113817,1),new Q.ptr(113820,113823,1)]),0);CW=new O.ptr(new IY([]),new IZ([new Q.ptr(77824,78894,1)]),0);CX=new O.ptr(new IY([]),new IZ([new Q.ptr(66816,66855,1)]),0);CY=new O.ptr(new IY([new P.ptr(4608,4680,1),new P.ptr(4682,4685,1),new P.ptr(4688,4694,1),new P.ptr(4696,4696,1),new P.ptr(4698,4701,1),new P.ptr(4704,4744,1),new P.ptr(4746,4749,1),new P.ptr(4752,4784,1),new P.ptr(4786,4789,1),new P.ptr(4792,4798,1),new P.ptr(4800,4800,1),new P.ptr(4802,4805,1),new P.ptr(4808,4822,1),new P.ptr(4824,4880,1),new P.ptr(4882,4885,1),new P.ptr(4888,4954,1),new P.ptr(4957,4988,1),new P.ptr(4992,5017,1),new P.ptr(11648,11670,1),new P.ptr(11680,11686,1),new P.ptr(11688,11694,1),new P.ptr(11696,11702,1),new P.ptr(11704,11710,1),new P.ptr(11712,11718,1),new P.ptr(11720,11726,1),new P.ptr(11728,11734,1),new P.ptr(11736,11742,1),new P.ptr(43777,43782,1),new P.ptr(43785,43790,1),new P.ptr(43793,43798,1),new P.ptr(43808,43814,1),new P.ptr(43816,43822,1)]),IZ.nil,0);CZ=new O.ptr(new IY([new P.ptr(4256,4293,1),new P.ptr(4295,4295,1),new P.ptr(4301,4301,1),new P.ptr(4304,4346,1),new P.ptr(4348,4351,1),new P.ptr(11520,11557,1),new P.ptr(11559,11559,1),new P.ptr(11565,11565,1)]),IZ.nil,0);DA=new O.ptr(new IY([new P.ptr(11264,11310,1),new P.ptr(11312,11358,1)]),new IZ([new Q.ptr(122880,122886,1),new Q.ptr(122888,122904,1),new Q.ptr(122907,122913,1),new Q.ptr(122915,122916,1),new Q.ptr(122918,122922,1)]),0);DB=new O.ptr(new IY([]),new IZ([new Q.ptr(66352,66378,1)]),0);DC=new O.ptr(new IY([]),new IZ([new Q.ptr(70400,70403,1),new Q.ptr(70405,70412,1),new Q.ptr(70415,70416,1),new Q.ptr(70419,70440,1),new Q.ptr(70442,70448,1),new Q.ptr(70450,70451,1),new Q.ptr(70453,70457,1),new Q.ptr(70460,70468,1),new Q.ptr(70471,70472,1),new Q.ptr(70475,70477,1),new Q.ptr(70480,70480,1),new Q.ptr(70487,70487,1),new Q.ptr(70493,70499,1),new Q.ptr(70502,70508,1),new Q.ptr(70512,70516,1)]),0);DD=new O.ptr(new IY([new P.ptr(880,883,1),new P.ptr(885,887,1),new P.ptr(890,893,1),new P.ptr(895,895,1),new P.ptr(900,900,1),new P.ptr(902,902,1),new P.ptr(904,906,1),new P.ptr(908,908,1),new P.ptr(910,929,1),new P.ptr(931,993,1),new P.ptr(1008,1023,1),new P.ptr(7462,7466,1),new P.ptr(7517,7521,1),new P.ptr(7526,7530,1),new P.ptr(7615,7615,1),new P.ptr(7936,7957,1),new P.ptr(7960,7965,1),new P.ptr(7968,8005,1),new P.ptr(8008,8013,1),new P.ptr(8016,8023,1),new P.ptr(8025,8025,1),new P.ptr(8027,8027,1),new P.ptr(8029,8029,1),new P.ptr(8031,8061,1),new P.ptr(8064,8116,1),new P.ptr(8118,8132,1),new P.ptr(8134,8147,1),new P.ptr(8150,8155,1),new P.ptr(8157,8175,1),new P.ptr(8178,8180,1),new P.ptr(8182,8190,1),new P.ptr(8486,8486,1),new P.ptr(43877,43877,1)]),new IZ([new Q.ptr(65856,65934,1),new Q.ptr(65952,65952,1),new Q.ptr(119296,119365,1)]),0);DE=new O.ptr(new IY([new P.ptr(2689,2691,1),new P.ptr(2693,2701,1),new P.ptr(2703,2705,1),new P.ptr(2707,2728,1),new P.ptr(2730,2736,1),new P.ptr(2738,2739,1),new P.ptr(2741,2745,1),new P.ptr(2748,2757,1),new P.ptr(2759,2761,1),new P.ptr(2763,2765,1),new P.ptr(2768,2768,1),new P.ptr(2784,2787,1),new P.ptr(2790,2801,1),new P.ptr(2809,2815,1)]),IZ.nil,0);DF=new O.ptr(new IY([new P.ptr(2561,2563,1),new P.ptr(2565,2570,1),new P.ptr(2575,2576,1),new P.ptr(2579,2600,1),new P.ptr(2602,2608,1),new P.ptr(2610,2611,1),new P.ptr(2613,2614,1),new P.ptr(2616,2617,1),new P.ptr(2620,2620,1),new P.ptr(2622,2626,1),new P.ptr(2631,2632,1),new P.ptr(2635,2637,1),new P.ptr(2641,2641,1),new P.ptr(2649,2652,1),new P.ptr(2654,2654,1),new P.ptr(2662,2677,1)]),IZ.nil,0);DG=new O.ptr(new IY([new P.ptr(11904,11929,1),new P.ptr(11931,12019,1),new P.ptr(12032,12245,1),new P.ptr(12293,12293,1),new P.ptr(12295,12295,1),new P.ptr(12321,12329,1),new P.ptr(12344,12347,1),new P.ptr(13312,19893,1),new P.ptr(19968,40938,1),new P.ptr(63744,64109,1),new P.ptr(64112,64217,1)]),new IZ([new Q.ptr(131072,173782,1),new Q.ptr(173824,177972,1),new Q.ptr(177984,178205,1),new Q.ptr(178208,183969,1),new Q.ptr(183984,191456,1),new Q.ptr(194560,195101,1)]),0);DH=new O.ptr(new IY([new P.ptr(4352,4607,1),new P.ptr(12334,12335,1),new P.ptr(12593,12686,1),new P.ptr(12800,12830,1),new P.ptr(12896,12926,1),new P.ptr(43360,43388,1),new P.ptr(44032,55203,1),new P.ptr(55216,55238,1),new P.ptr(55243,55291,1),new P.ptr(65440,65470,1),new P.ptr(65474,65479,1),new P.ptr(65482,65487,1),new P.ptr(65490,65495,1),new P.ptr(65498,65500,1)]),IZ.nil,0);DI=new O.ptr(new IY([new P.ptr(5920,5940,1)]),IZ.nil,0);DJ=new O.ptr(new IY([]),new IZ([new Q.ptr(67808,67826,1),new Q.ptr(67828,67829,1),new Q.ptr(67835,67839,1)]),0);DK=new O.ptr(new IY([new P.ptr(1425,1479,1),new P.ptr(1488,1514,1),new P.ptr(1520,1524,1),new P.ptr(64285,64310,1),new P.ptr(64312,64316,1),new P.ptr(64318,64318,1),new P.ptr(64320,64321,1),new P.ptr(64323,64324,1),new P.ptr(64326,64335,1)]),IZ.nil,0);DL=new O.ptr(new IY([new P.ptr(12353,12438,1),new P.ptr(12445,12447,1)]),new IZ([new Q.ptr(110593,110878,1),new Q.ptr(127488,127488,1)]),0);DM=new O.ptr(new IY([]),new IZ([new Q.ptr(67648,67669,1),new Q.ptr(67671,67679,1)]),0);DN=new O.ptr(new IY([new P.ptr(768,879,1),new P.ptr(1157,1158,1),new P.ptr(1611,1621,1),new P.ptr(1648,1648,1),new P.ptr(2385,2386,1),new P.ptr(6832,6846,1),new P.ptr(7376,7378,1),new P.ptr(7380,7392,1),new P.ptr(7394,7400,1),new P.ptr(7405,7405,1),new P.ptr(7412,7412,1),new P.ptr(7416,7417,1),new P.ptr(7616,7673,1),new P.ptr(7675,7679,1),new P.ptr(8204,8205,1),new P.ptr(8400,8432,1),new P.ptr(12330,12333,1),new P.ptr(12441,12442,1),new P.ptr(65024,65039,1),new P.ptr(65056,65069,1)]),new IZ([new Q.ptr(66045,66045,1),new Q.ptr(66272,66272,1),new Q.ptr(119143,119145,1),new Q.ptr(119163,119170,1),new Q.ptr(119173,119179,1),new Q.ptr(119210,119213,1),new Q.ptr(917760,917999,1)]),0);DO=new O.ptr(new IY([]),new IZ([new Q.ptr(68448,68466,1),new Q.ptr(68472,68479,1)]),0);DP=new O.ptr(new IY([]),new IZ([new Q.ptr(68416,68437,1),new Q.ptr(68440,68447,1)]),0);DQ=new O.ptr(new IY([new P.ptr(43392,43469,1),new P.ptr(43472,43481,1),new P.ptr(43486,43487,1)]),IZ.nil,0);DR=new O.ptr(new IY([]),new IZ([new Q.ptr(69760,69825,1)]),0);DS=new O.ptr(new IY([new P.ptr(3200,3203,1),new P.ptr(3205,3212,1),new P.ptr(3214,3216,1),new P.ptr(3218,3240,1),new P.ptr(3242,3251,1),new P.ptr(3253,3257,1),new P.ptr(3260,3268,1),new P.ptr(3270,3272,1),new P.ptr(3274,3277,1),new P.ptr(3285,3286,1),new P.ptr(3294,3294,1),new P.ptr(3296,3299,1),new P.ptr(3302,3311,1),new P.ptr(3313,3314,1)]),IZ.nil,0);DT=new O.ptr(new IY([new P.ptr(12449,12538,1),new P.ptr(12541,12543,1),new P.ptr(12784,12799,1),new P.ptr(13008,13054,1),new P.ptr(13056,13143,1),new P.ptr(65382,65391,1),new P.ptr(65393,65437,1)]),new IZ([new Q.ptr(110592,110592,1)]),0);DU=new O.ptr(new IY([new P.ptr(43264,43309,1),new P.ptr(43311,43311,1)]),IZ.nil,0);DV=new O.ptr(new IY([]),new IZ([new Q.ptr(68096,68099,1),new Q.ptr(68101,68102,1),new Q.ptr(68108,68115,1),new Q.ptr(68117,68119,1),new Q.ptr(68121,68147,1),new Q.ptr(68152,68154,1),new Q.ptr(68159,68167,1),new Q.ptr(68176,68184,1)]),0);DW=new O.ptr(new IY([new P.ptr(6016,6109,1),new P.ptr(6112,6121,1),new P.ptr(6128,6137,1),new P.ptr(6624,6655,1)]),IZ.nil,0);DX=new O.ptr(new IY([]),new IZ([new Q.ptr(70144,70161,1),new Q.ptr(70163,70206,1)]),0);DY=new O.ptr(new IY([]),new IZ([new Q.ptr(70320,70378,1),new Q.ptr(70384,70393,1)]),0);DZ=new O.ptr(new IY([new P.ptr(3713,3714,1),new P.ptr(3716,3716,1),new P.ptr(3719,3720,1),new P.ptr(3722,3722,1),new P.ptr(3725,3725,1),new P.ptr(3732,3735,1),new P.ptr(3737,3743,1),new P.ptr(3745,3747,1),new P.ptr(3749,3749,1),new P.ptr(3751,3751,1),new P.ptr(3754,3755,1),new P.ptr(3757,3769,1),new P.ptr(3771,3773,1),new P.ptr(3776,3780,1),new P.ptr(3782,3782,1),new P.ptr(3784,3789,1),new P.ptr(3792,3801,1),new P.ptr(3804,3807,1)]),IZ.nil,0);EA=new O.ptr(new IY([new P.ptr(65,90,1),new P.ptr(97,122,1),new P.ptr(170,170,1),new P.ptr(186,186,1),new P.ptr(192,214,1),new P.ptr(216,246,1),new P.ptr(248,696,1),new P.ptr(736,740,1),new P.ptr(7424,7461,1),new P.ptr(7468,7516,1),new P.ptr(7522,7525,1),new P.ptr(7531,7543,1),new P.ptr(7545,7614,1),new P.ptr(7680,7935,1),new P.ptr(8305,8305,1),new P.ptr(8319,8319,1),new P.ptr(8336,8348,1),new P.ptr(8490,8491,1),new P.ptr(8498,8498,1),new P.ptr(8526,8526,1),new P.ptr(8544,8584,1),new P.ptr(11360,11391,1),new P.ptr(42786,42887,1),new P.ptr(42891,42926,1),new P.ptr(42928,42935,1),new P.ptr(42999,43007,1),new P.ptr(43824,43866,1),new P.ptr(43868,43876,1),new P.ptr(64256,64262,1),new P.ptr(65313,65338,1),new P.ptr(65345,65370,1)]),IZ.nil,6);EB=new O.ptr(new IY([new P.ptr(7168,7223,1),new P.ptr(7227,7241,1),new P.ptr(7245,7247,1)]),IZ.nil,0);EC=new O.ptr(new IY([new P.ptr(6400,6430,1),new P.ptr(6432,6443,1),new P.ptr(6448,6459,1),new P.ptr(6464,6464,1),new P.ptr(6468,6479,1)]),IZ.nil,0);ED=new O.ptr(new IY([]),new IZ([new Q.ptr(67072,67382,1),new Q.ptr(67392,67413,1),new Q.ptr(67424,67431,1)]),0);EE=new O.ptr(new IY([]),new IZ([new Q.ptr(65536,65547,1),new Q.ptr(65549,65574,1),new Q.ptr(65576,65594,1),new Q.ptr(65596,65597,1),new Q.ptr(65599,65613,1),new Q.ptr(65616,65629,1),new Q.ptr(65664,65786,1)]),0);EF=new O.ptr(new IY([new P.ptr(42192,42239,1)]),IZ.nil,0);EG=new O.ptr(new IY([]),new IZ([new Q.ptr(66176,66204,1)]),0);EH=new O.ptr(new IY([]),new IZ([new Q.ptr(67872,67897,1),new Q.ptr(67903,67903,1)]),0);EI=new O.ptr(new IY([]),new IZ([new Q.ptr(69968,70006,1)]),0);EJ=new O.ptr(new IY([new P.ptr(3328,3331,1),new P.ptr(3333,3340,1),new P.ptr(3342,3344,1),new P.ptr(3346,3396,1),new P.ptr(3398,3400,1),new P.ptr(3402,3407,1),new P.ptr(3412,3427,1),new P.ptr(3430,3455,1)]),IZ.nil,0);EK=new O.ptr(new IY([new P.ptr(2112,2139,1),new P.ptr(2142,2142,1)]),IZ.nil,0);EL=new O.ptr(new IY([]),new IZ([new Q.ptr(68288,68326,1),new Q.ptr(68331,68342,1)]),0);EM=new O.ptr(new IY([]),new IZ([new Q.ptr(72816,72847,1),new Q.ptr(72850,72871,1),new Q.ptr(72873,72886,1)]),0);EN=new O.ptr(new IY([]),new IZ([new Q.ptr(72960,72966,1),new Q.ptr(72968,72969,1),new Q.ptr(72971,73014,1),new Q.ptr(73018,73018,1),new Q.ptr(73020,73021,1),new Q.ptr(73023,73031,1),new Q.ptr(73040,73049,1)]),0);EO=new O.ptr(new IY([new P.ptr(43744,43766,1),new P.ptr(43968,44013,1),new P.ptr(44016,44025,1)]),IZ.nil,0);EP=new O.ptr(new IY([]),new IZ([new Q.ptr(124928,125124,1),new Q.ptr(125127,125142,1)]),0);EQ=new O.ptr(new IY([]),new IZ([new Q.ptr(68000,68023,1),new Q.ptr(68028,68047,1),new Q.ptr(68050,68095,1)]),0);ER=new O.ptr(new IY([]),new IZ([new Q.ptr(67968,67999,1)]),0);ES=new O.ptr(new IY([]),new IZ([new Q.ptr(93952,94020,1),new Q.ptr(94032,94078,1),new Q.ptr(94095,94111,1)]),0);ET=new O.ptr(new IY([]),new IZ([new Q.ptr(71168,71236,1),new Q.ptr(71248,71257,1)]),0);EU=new O.ptr(new IY([new P.ptr(6144,6145,1),new P.ptr(6148,6148,1),new P.ptr(6150,6158,1),new P.ptr(6160,6169,1),new P.ptr(6176,6263,1),new P.ptr(6272,6314,1)]),new IZ([new Q.ptr(71264,71276,1)]),0);EV=new O.ptr(new IY([]),new IZ([new Q.ptr(92736,92766,1),new Q.ptr(92768,92777,1),new Q.ptr(92782,92783,1)]),0);EW=new O.ptr(new IY([]),new IZ([new Q.ptr(70272,70278,1),new Q.ptr(70280,70280,1),new Q.ptr(70282,70285,1),new Q.ptr(70287,70301,1),new Q.ptr(70303,70313,1)]),0);EX=new O.ptr(new IY([new P.ptr(4096,4255,1),new P.ptr(43488,43518,1),new P.ptr(43616,43647,1)]),IZ.nil,0);EY=new O.ptr(new IY([]),new IZ([new Q.ptr(67712,67742,1),new Q.ptr(67751,67759,1)]),0);EZ=new O.ptr(new IY([new P.ptr(6528,6571,1),new P.ptr(6576,6601,1),new P.ptr(6608,6618,1),new P.ptr(6622,6623,1)]),IZ.nil,0);FA=new O.ptr(new IY([]),new IZ([new Q.ptr(70656,70745,1),new Q.ptr(70747,70747,1),new Q.ptr(70749,70749,1)]),0);FB=new O.ptr(new IY([new P.ptr(1984,2042,1)]),IZ.nil,0);FC=new O.ptr(new IY([]),new IZ([new Q.ptr(94177,94177,1),new Q.ptr(110960,111355,1)]),0);FD=new O.ptr(new IY([new P.ptr(5760,5788,1)]),IZ.nil,0);FE=new O.ptr(new IY([new P.ptr(7248,7295,1)]),IZ.nil,0);FF=new O.ptr(new IY([]),new IZ([new Q.ptr(68736,68786,1),new Q.ptr(68800,68850,1),new Q.ptr(68858,68863,1)]),0);FG=new O.ptr(new IY([]),new IZ([new Q.ptr(66304,66339,1),new Q.ptr(66349,66351,1)]),0);FH=new O.ptr(new IY([]),new IZ([new Q.ptr(68224,68255,1)]),0);FI=new O.ptr(new IY([]),new IZ([new Q.ptr(66384,66426,1)]),0);FJ=new O.ptr(new IY([]),new IZ([new Q.ptr(66464,66499,1),new Q.ptr(66504,66517,1)]),0);FK=new O.ptr(new IY([]),new IZ([new Q.ptr(68192,68223,1)]),0);FL=new O.ptr(new IY([]),new IZ([new Q.ptr(68608,68680,1)]),0);FM=new O.ptr(new IY([new P.ptr(2817,2819,1),new P.ptr(2821,2828,1),new P.ptr(2831,2832,1),new P.ptr(2835,2856,1),new P.ptr(2858,2864,1),new P.ptr(2866,2867,1),new P.ptr(2869,2873,1),new P.ptr(2876,2884,1),new P.ptr(2887,2888,1),new P.ptr(2891,2893,1),new P.ptr(2902,2903,1),new P.ptr(2908,2909,1),new P.ptr(2911,2915,1),new P.ptr(2918,2935,1)]),IZ.nil,0);FN=new O.ptr(new IY([]),new IZ([new Q.ptr(66736,66771,1),new Q.ptr(66776,66811,1)]),0);FO=new O.ptr(new IY([]),new IZ([new Q.ptr(66688,66717,1),new Q.ptr(66720,66729,1)]),0);FP=new O.ptr(new IY([]),new IZ([new Q.ptr(92928,92997,1),new Q.ptr(93008,93017,1),new Q.ptr(93019,93025,1),new Q.ptr(93027,93047,1),new Q.ptr(93053,93071,1)]),0);FQ=new O.ptr(new IY([]),new IZ([new Q.ptr(67680,67711,1)]),0);FR=new O.ptr(new IY([]),new IZ([new Q.ptr(72384,72440,1)]),0);FS=new O.ptr(new IY([new P.ptr(43072,43127,1)]),IZ.nil,0);FT=new O.ptr(new IY([]),new IZ([new Q.ptr(67840,67867,1),new Q.ptr(67871,67871,1)]),0);FU=new O.ptr(new IY([]),new IZ([new Q.ptr(68480,68497,1),new Q.ptr(68505,68508,1),new Q.ptr(68521,68527,1)]),0);FV=new O.ptr(new IY([new P.ptr(43312,43347,1),new P.ptr(43359,43359,1)]),IZ.nil,0);FW=new O.ptr(new IY([new P.ptr(5792,5866,1),new P.ptr(5870,5880,1)]),IZ.nil,0);FX=new O.ptr(new IY([new P.ptr(2048,2093,1),new P.ptr(2096,2110,1)]),IZ.nil,0);FY=new O.ptr(new IY([new P.ptr(43136,43205,1),new P.ptr(43214,43225,1)]),IZ.nil,0);FZ=new O.ptr(new IY([]),new IZ([new Q.ptr(70016,70093,1),new Q.ptr(70096,70111,1)]),0);GA=new O.ptr(new IY([]),new IZ([new Q.ptr(66640,66687,1)]),0);GB=new O.ptr(new IY([]),new IZ([new Q.ptr(71040,71093,1),new Q.ptr(71096,71133,1)]),0);GC=new O.ptr(new IY([]),new IZ([new Q.ptr(120832,121483,1),new Q.ptr(121499,121503,1),new Q.ptr(121505,121519,1)]),0);GD=new O.ptr(new IY([new P.ptr(3458,3459,1),new P.ptr(3461,3478,1),new P.ptr(3482,3505,1),new P.ptr(3507,3515,1),new P.ptr(3517,3517,1),new P.ptr(3520,3526,1),new P.ptr(3530,3530,1),new P.ptr(3535,3540,1),new P.ptr(3542,3542,1),new P.ptr(3544,3551,1),new P.ptr(3558,3567,1),new P.ptr(3570,3572,1)]),new IZ([new Q.ptr(70113,70132,1)]),0);GE=new O.ptr(new IY([]),new IZ([new Q.ptr(69840,69864,1),new Q.ptr(69872,69881,1)]),0);GF=new O.ptr(new IY([]),new IZ([new Q.ptr(72272,72323,1),new Q.ptr(72326,72348,1),new Q.ptr(72350,72354,1)]),0);GG=new O.ptr(new IY([new P.ptr(7040,7103,1),new P.ptr(7360,7367,1)]),IZ.nil,0);GH=new O.ptr(new IY([new P.ptr(43008,43051,1)]),IZ.nil,0);GI=new O.ptr(new IY([new P.ptr(1792,1805,1),new P.ptr(1807,1866,1),new P.ptr(1869,1871,1),new P.ptr(2144,2154,1)]),IZ.nil,0);GJ=new O.ptr(new IY([new P.ptr(5888,5900,1),new P.ptr(5902,5908,1)]),IZ.nil,0);GK=new O.ptr(new IY([new P.ptr(5984,5996,1),new P.ptr(5998,6000,1),new P.ptr(6002,6003,1)]),IZ.nil,0);GL=new O.ptr(new IY([new P.ptr(6480,6509,1),new P.ptr(6512,6516,1)]),IZ.nil,0);GM=new O.ptr(new IY([new P.ptr(6688,6750,1),new P.ptr(6752,6780,1),new P.ptr(6783,6793,1),new P.ptr(6800,6809,1),new P.ptr(6816,6829,1)]),IZ.nil,0);GN=new O.ptr(new IY([new P.ptr(43648,43714,1),new P.ptr(43739,43743,1)]),IZ.nil,0);GO=new O.ptr(new IY([]),new IZ([new Q.ptr(71296,71351,1),new Q.ptr(71360,71369,1)]),0);GP=new O.ptr(new IY([new P.ptr(2946,2947,1),new P.ptr(2949,2954,1),new P.ptr(2958,2960,1),new P.ptr(2962,2965,1),new P.ptr(2969,2970,1),new P.ptr(2972,2972,1),new P.ptr(2974,2975,1),new P.ptr(2979,2980,1),new P.ptr(2984,2986,1),new P.ptr(2990,3001,1),new P.ptr(3006,3010,1),new P.ptr(3014,3016,1),new P.ptr(3018,3021,1),new P.ptr(3024,3024,1),new P.ptr(3031,3031,1),new P.ptr(3046,3066,1)]),IZ.nil,0);GQ=new O.ptr(new IY([]),new IZ([new Q.ptr(94176,94176,1),new Q.ptr(94208,100332,1),new Q.ptr(100352,101106,1)]),0);GR=new O.ptr(new IY([new P.ptr(3072,3075,1),new P.ptr(3077,3084,1),new P.ptr(3086,3088,1),new P.ptr(3090,3112,1),new P.ptr(3114,3129,1),new P.ptr(3133,3140,1),new P.ptr(3142,3144,1),new P.ptr(3146,3149,1),new P.ptr(3157,3158,1),new P.ptr(3160,3162,1),new P.ptr(3168,3171,1),new P.ptr(3174,3183,1),new P.ptr(3192,3199,1)]),IZ.nil,0);GS=new O.ptr(new IY([new P.ptr(1920,1969,1)]),IZ.nil,0);GT=new O.ptr(new IY([new P.ptr(3585,3642,1),new P.ptr(3648,3675,1)]),IZ.nil,0);GU=new O.ptr(new IY([new P.ptr(3840,3911,1),new P.ptr(3913,3948,1),new P.ptr(3953,3991,1),new P.ptr(3993,4028,1),new P.ptr(4030,4044,1),new P.ptr(4046,4052,1),new P.ptr(4057,4058,1)]),IZ.nil,0);GV=new O.ptr(new IY([new P.ptr(11568,11623,1),new P.ptr(11631,11632,1),new P.ptr(11647,11647,1)]),IZ.nil,0);GW=new O.ptr(new IY([]),new IZ([new Q.ptr(70784,70855,1),new Q.ptr(70864,70873,1)]),0);GX=new O.ptr(new IY([]),new IZ([new Q.ptr(66432,66461,1),new Q.ptr(66463,66463,1)]),0);GY=new O.ptr(new IY([new P.ptr(42240,42539,1)]),IZ.nil,0);GZ=new O.ptr(new IY([]),new IZ([new Q.ptr(71840,71922,1),new Q.ptr(71935,71935,1)]),0);HA=new O.ptr(new IY([new P.ptr(40960,42124,1),new P.ptr(42128,42182,1)]),IZ.nil,0);HB=new O.ptr(new IY([]),new IZ([new Q.ptr(72192,72263,1)]),0);$pkg.Adlam=BR;$pkg.Ahom=BS;$pkg.Anatolian_Hieroglyphs=BT;$pkg.Arabic=BU;$pkg.Armenian=BV;$pkg.Avestan=BW;$pkg.Balinese=BX;$pkg.Bamum=BY;$pkg.Bassa_Vah=BZ;$pkg.Batak=CA;$pkg.Bengali=CB;$pkg.Bhaiksuki=CC;$pkg.Bopomofo=CD;$pkg.Brahmi=CE;$pkg.Braille=CF;$pkg.Buginese=CG;$pkg.Buhid=CH;$pkg.Canadian_Aboriginal=CI;$pkg.Carian=CJ;$pkg.Caucasian_Albanian=CK;$pkg.Chakma=CL;$pkg.Cham=CM;$pkg.Cherokee=CN;$pkg.Common=CO;$pkg.Coptic=CP;$pkg.Cuneiform=CQ;$pkg.Cypriot=CR;$pkg.Cyrillic=CS;$pkg.Deseret=CT;$pkg.Devanagari=CU;$pkg.Duployan=CV;$pkg.Egyptian_Hieroglyphs=CW;$pkg.Elbasan=CX;$pkg.Ethiopic=CY;$pkg.Georgian=CZ;$pkg.Glagolitic=DA;$pkg.Gothic=DB;$pkg.Grantha=DC;$pkg.Greek=DD;$pkg.Gujarati=DE;$pkg.Gurmukhi=DF;$pkg.Han=DG;$pkg.Hangul=DH;$pkg.Hanunoo=DI;$pkg.Hatran=DJ;$pkg.Hebrew=DK;$pkg.Hiragana=DL;$pkg.Imperial_Aramaic=DM;$pkg.Inherited=DN;$pkg.Inscriptional_Pahlavi=DO;$pkg.Inscriptional_Parthian=DP;$pkg.Javanese=DQ;$pkg.Kaithi=DR;$pkg.Kannada=DS;$pkg.Katakana=DT;$pkg.Kayah_Li=DU;$pkg.Kharoshthi=DV;$pkg.Khmer=DW;$pkg.Khojki=DX;$pkg.Khudawadi=DY;$pkg.Lao=DZ;$pkg.Latin=EA;$pkg.Lepcha=EB;$pkg.Limbu=EC;$pkg.Linear_A=ED;$pkg.Linear_B=EE;$pkg.Lisu=EF;$pkg.Lycian=EG;$pkg.Lydian=EH;$pkg.Mahajani=EI;$pkg.Malayalam=EJ;$pkg.Mandaic=EK;$pkg.Manichaean=EL;$pkg.Marchen=EM;$pkg.Masaram_Gondi=EN;$pkg.Meetei_Mayek=EO;$pkg.Mende_Kikakui=EP;$pkg.Meroitic_Cursive=EQ;$pkg.Meroitic_Hieroglyphs=ER;$pkg.Miao=ES;$pkg.Modi=ET;$pkg.Mongolian=EU;$pkg.Mro=EV;$pkg.Multani=EW;$pkg.Myanmar=EX;$pkg.Nabataean=EY;$pkg.New_Tai_Lue=EZ;$pkg.Newa=FA;$pkg.Nko=FB;$pkg.Nushu=FC;$pkg.Ogham=FD;$pkg.Ol_Chiki=FE;$pkg.Old_Hungarian=FF;$pkg.Old_Italic=FG;$pkg.Old_North_Arabian=FH;$pkg.Old_Permic=FI;$pkg.Old_Persian=FJ;$pkg.Old_South_Arabian=FK;$pkg.Old_Turkic=FL;$pkg.Oriya=FM;$pkg.Osage=FN;$pkg.Osmanya=FO;$pkg.Pahawh_Hmong=FP;$pkg.Palmyrene=FQ;$pkg.Pau_Cin_Hau=FR;$pkg.Phags_Pa=FS;$pkg.Phoenician=FT;$pkg.Psalter_Pahlavi=FU;$pkg.Rejang=FV;$pkg.Runic=FW;$pkg.Samaritan=FX;$pkg.Saurashtra=FY;$pkg.Sharada=FZ;$pkg.Shavian=GA;$pkg.Siddham=GB;$pkg.SignWriting=GC;$pkg.Sinhala=GD;$pkg.Sora_Sompeng=GE;$pkg.Soyombo=GF;$pkg.Sundanese=GG;$pkg.Syloti_Nagri=GH;$pkg.Syriac=GI;$pkg.Tagalog=GJ;$pkg.Tagbanwa=GK;$pkg.Tai_Le=GL;$pkg.Tai_Tham=GM;$pkg.Tai_Viet=GN;$pkg.Takri=GO;$pkg.Tamil=GP;$pkg.Tangut=GQ;$pkg.Telugu=GR;$pkg.Thaana=GS;$pkg.Thai=GT;$pkg.Tibetan=GU;$pkg.Tifinagh=GV;$pkg.Tirhuta=GW;$pkg.Ugaritic=GX;$pkg.Vai=GY;$pkg.Warang_Citi=GZ;$pkg.Yi=HA;$pkg.Zanabazar_Square=HB;$pkg.Scripts=$makeMap($String.keyFor,[{k:\"Adlam\",v:$pkg.Adlam},{k:\"Ahom\",v:$pkg.Ahom},{k:\"Anatolian_Hieroglyphs\",v:$pkg.Anatolian_Hieroglyphs},{k:\"Arabic\",v:$pkg.Arabic},{k:\"Armenian\",v:$pkg.Armenian},{k:\"Avestan\",v:$pkg.Avestan},{k:\"Balinese\",v:$pkg.Balinese},{k:\"Bamum\",v:$pkg.Bamum},{k:\"Bassa_Vah\",v:$pkg.Bassa_Vah},{k:\"Batak\",v:$pkg.Batak},{k:\"Bengali\",v:$pkg.Bengali},{k:\"Bhaiksuki\",v:$pkg.Bhaiksuki},{k:\"Bopomofo\",v:$pkg.Bopomofo},{k:\"Brahmi\",v:$pkg.Brahmi},{k:\"Braille\",v:$pkg.Braille},{k:\"Buginese\",v:$pkg.Buginese},{k:\"Buhid\",v:$pkg.Buhid},{k:\"Canadian_Aboriginal\",v:$pkg.Canadian_Aboriginal},{k:\"Carian\",v:$pkg.Carian},{k:\"Caucasian_Albanian\",v:$pkg.Caucasian_Albanian},{k:\"Chakma\",v:$pkg.Chakma},{k:\"Cham\",v:$pkg.Cham},{k:\"Cherokee\",v:$pkg.Cherokee},{k:\"Common\",v:$pkg.Common},{k:\"Coptic\",v:$pkg.Coptic},{k:\"Cuneiform\",v:$pkg.Cuneiform},{k:\"Cypriot\",v:$pkg.Cypriot},{k:\"Cyrillic\",v:$pkg.Cyrillic},{k:\"Deseret\",v:$pkg.Deseret},{k:\"Devanagari\",v:$pkg.Devanagari},{k:\"Duployan\",v:$pkg.Duployan},{k:\"Egyptian_Hieroglyphs\",v:$pkg.Egyptian_Hieroglyphs},{k:\"Elbasan\",v:$pkg.Elbasan},{k:\"Ethiopic\",v:$pkg.Ethiopic},{k:\"Georgian\",v:$pkg.Georgian},{k:\"Glagolitic\",v:$pkg.Glagolitic},{k:\"Gothic\",v:$pkg.Gothic},{k:\"Grantha\",v:$pkg.Grantha},{k:\"Greek\",v:$pkg.Greek},{k:\"Gujarati\",v:$pkg.Gujarati},{k:\"Gurmukhi\",v:$pkg.Gurmukhi},{k:\"Han\",v:$pkg.Han},{k:\"Hangul\",v:$pkg.Hangul},{k:\"Hanunoo\",v:$pkg.Hanunoo},{k:\"Hatran\",v:$pkg.Hatran},{k:\"Hebrew\",v:$pkg.Hebrew},{k:\"Hiragana\",v:$pkg.Hiragana},{k:\"Imperial_Aramaic\",v:$pkg.Imperial_Aramaic},{k:\"Inherited\",v:$pkg.Inherited},{k:\"Inscriptional_Pahlavi\",v:$pkg.Inscriptional_Pahlavi},{k:\"Inscriptional_Parthian\",v:$pkg.Inscriptional_Parthian},{k:\"Javanese\",v:$pkg.Javanese},{k:\"Kaithi\",v:$pkg.Kaithi},{k:\"Kannada\",v:$pkg.Kannada},{k:\"Katakana\",v:$pkg.Katakana},{k:\"Kayah_Li\",v:$pkg.Kayah_Li},{k:\"Kharoshthi\",v:$pkg.Kharoshthi},{k:\"Khmer\",v:$pkg.Khmer},{k:\"Khojki\",v:$pkg.Khojki},{k:\"Khudawadi\",v:$pkg.Khudawadi},{k:\"Lao\",v:$pkg.Lao},{k:\"Latin\",v:$pkg.Latin},{k:\"Lepcha\",v:$pkg.Lepcha},{k:\"Limbu\",v:$pkg.Limbu},{k:\"Linear_A\",v:$pkg.Linear_A},{k:\"Linear_B\",v:$pkg.Linear_B},{k:\"Lisu\",v:$pkg.Lisu},{k:\"Lycian\",v:$pkg.Lycian},{k:\"Lydian\",v:$pkg.Lydian},{k:\"Mahajani\",v:$pkg.Mahajani},{k:\"Malayalam\",v:$pkg.Malayalam},{k:\"Mandaic\",v:$pkg.Mandaic},{k:\"Manichaean\",v:$pkg.Manichaean},{k:\"Marchen\",v:$pkg.Marchen},{k:\"Masaram_Gondi\",v:$pkg.Masaram_Gondi},{k:\"Meetei_Mayek\",v:$pkg.Meetei_Mayek},{k:\"Mende_Kikakui\",v:$pkg.Mende_Kikakui},{k:\"Meroitic_Cursive\",v:$pkg.Meroitic_Cursive},{k:\"Meroitic_Hieroglyphs\",v:$pkg.Meroitic_Hieroglyphs},{k:\"Miao\",v:$pkg.Miao},{k:\"Modi\",v:$pkg.Modi},{k:\"Mongolian\",v:$pkg.Mongolian},{k:\"Mro\",v:$pkg.Mro},{k:\"Multani\",v:$pkg.Multani},{k:\"Myanmar\",v:$pkg.Myanmar},{k:\"Nabataean\",v:$pkg.Nabataean},{k:\"New_Tai_Lue\",v:$pkg.New_Tai_Lue},{k:\"Newa\",v:$pkg.Newa},{k:\"Nko\",v:$pkg.Nko},{k:\"Nushu\",v:$pkg.Nushu},{k:\"Ogham\",v:$pkg.Ogham},{k:\"Ol_Chiki\",v:$pkg.Ol_Chiki},{k:\"Old_Hungarian\",v:$pkg.Old_Hungarian},{k:\"Old_Italic\",v:$pkg.Old_Italic},{k:\"Old_North_Arabian\",v:$pkg.Old_North_Arabian},{k:\"Old_Permic\",v:$pkg.Old_Permic},{k:\"Old_Persian\",v:$pkg.Old_Persian},{k:\"Old_South_Arabian\",v:$pkg.Old_South_Arabian},{k:\"Old_Turkic\",v:$pkg.Old_Turkic},{k:\"Oriya\",v:$pkg.Oriya},{k:\"Osage\",v:$pkg.Osage},{k:\"Osmanya\",v:$pkg.Osmanya},{k:\"Pahawh_Hmong\",v:$pkg.Pahawh_Hmong},{k:\"Palmyrene\",v:$pkg.Palmyrene},{k:\"Pau_Cin_Hau\",v:$pkg.Pau_Cin_Hau},{k:\"Phags_Pa\",v:$pkg.Phags_Pa},{k:\"Phoenician\",v:$pkg.Phoenician},{k:\"Psalter_Pahlavi\",v:$pkg.Psalter_Pahlavi},{k:\"Rejang\",v:$pkg.Rejang},{k:\"Runic\",v:$pkg.Runic},{k:\"Samaritan\",v:$pkg.Samaritan},{k:\"Saurashtra\",v:$pkg.Saurashtra},{k:\"Sharada\",v:$pkg.Sharada},{k:\"Shavian\",v:$pkg.Shavian},{k:\"Siddham\",v:$pkg.Siddham},{k:\"SignWriting\",v:$pkg.SignWriting},{k:\"Sinhala\",v:$pkg.Sinhala},{k:\"Sora_Sompeng\",v:$pkg.Sora_Sompeng},{k:\"Soyombo\",v:$pkg.Soyombo},{k:\"Sundanese\",v:$pkg.Sundanese},{k:\"Syloti_Nagri\",v:$pkg.Syloti_Nagri},{k:\"Syriac\",v:$pkg.Syriac},{k:\"Tagalog\",v:$pkg.Tagalog},{k:\"Tagbanwa\",v:$pkg.Tagbanwa},{k:\"Tai_Le\",v:$pkg.Tai_Le},{k:\"Tai_Tham\",v:$pkg.Tai_Tham},{k:\"Tai_Viet\",v:$pkg.Tai_Viet},{k:\"Takri\",v:$pkg.Takri},{k:\"Tamil\",v:$pkg.Tamil},{k:\"Tangut\",v:$pkg.Tangut},{k:\"Telugu\",v:$pkg.Telugu},{k:\"Thaana\",v:$pkg.Thaana},{k:\"Thai\",v:$pkg.Thai},{k:\"Tibetan\",v:$pkg.Tibetan},{k:\"Tifinagh\",v:$pkg.Tifinagh},{k:\"Tirhuta\",v:$pkg.Tirhuta},{k:\"Ugaritic\",v:$pkg.Ugaritic},{k:\"Vai\",v:$pkg.Vai},{k:\"Warang_Citi\",v:$pkg.Warang_Citi},{k:\"Yi\",v:$pkg.Yi},{k:\"Zanabazar_Square\",v:$pkg.Zanabazar_Square}]);IK=new JC([new R.ptr(65,90,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(97,122,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(181,181,$toNativeArray($kindInt32,[743,0,743])),new R.ptr(192,214,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(216,222,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(224,246,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(248,254,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(255,255,$toNativeArray($kindInt32,[121,0,121])),new R.ptr(256,303,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(304,304,$toNativeArray($kindInt32,[0,-199,0])),new R.ptr(305,305,$toNativeArray($kindInt32,[-232,0,-232])),new R.ptr(306,311,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(313,328,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(330,375,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(376,376,$toNativeArray($kindInt32,[0,-121,0])),new R.ptr(377,382,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(383,383,$toNativeArray($kindInt32,[-300,0,-300])),new R.ptr(384,384,$toNativeArray($kindInt32,[195,0,195])),new R.ptr(385,385,$toNativeArray($kindInt32,[0,210,0])),new R.ptr(386,389,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(390,390,$toNativeArray($kindInt32,[0,206,0])),new R.ptr(391,392,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(393,394,$toNativeArray($kindInt32,[0,205,0])),new R.ptr(395,396,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(398,398,$toNativeArray($kindInt32,[0,79,0])),new R.ptr(399,399,$toNativeArray($kindInt32,[0,202,0])),new R.ptr(400,400,$toNativeArray($kindInt32,[0,203,0])),new R.ptr(401,402,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(403,403,$toNativeArray($kindInt32,[0,205,0])),new R.ptr(404,404,$toNativeArray($kindInt32,[0,207,0])),new R.ptr(405,405,$toNativeArray($kindInt32,[97,0,97])),new R.ptr(406,406,$toNativeArray($kindInt32,[0,211,0])),new R.ptr(407,407,$toNativeArray($kindInt32,[0,209,0])),new R.ptr(408,409,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(410,410,$toNativeArray($kindInt32,[163,0,163])),new R.ptr(412,412,$toNativeArray($kindInt32,[0,211,0])),new R.ptr(413,413,$toNativeArray($kindInt32,[0,213,0])),new R.ptr(414,414,$toNativeArray($kindInt32,[130,0,130])),new R.ptr(415,415,$toNativeArray($kindInt32,[0,214,0])),new R.ptr(416,421,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(422,422,$toNativeArray($kindInt32,[0,218,0])),new R.ptr(423,424,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(425,425,$toNativeArray($kindInt32,[0,218,0])),new R.ptr(428,429,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(430,430,$toNativeArray($kindInt32,[0,218,0])),new R.ptr(431,432,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(433,434,$toNativeArray($kindInt32,[0,217,0])),new R.ptr(435,438,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(439,439,$toNativeArray($kindInt32,[0,219,0])),new R.ptr(440,441,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(444,445,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(447,447,$toNativeArray($kindInt32,[56,0,56])),new R.ptr(452,452,$toNativeArray($kindInt32,[0,2,1])),new R.ptr(453,453,$toNativeArray($kindInt32,[-1,1,0])),new R.ptr(454,454,$toNativeArray($kindInt32,[-2,0,-1])),new R.ptr(455,455,$toNativeArray($kindInt32,[0,2,1])),new R.ptr(456,456,$toNativeArray($kindInt32,[-1,1,0])),new R.ptr(457,457,$toNativeArray($kindInt32,[-2,0,-1])),new R.ptr(458,458,$toNativeArray($kindInt32,[0,2,1])),new R.ptr(459,459,$toNativeArray($kindInt32,[-1,1,0])),new R.ptr(460,460,$toNativeArray($kindInt32,[-2,0,-1])),new R.ptr(461,476,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(477,477,$toNativeArray($kindInt32,[-79,0,-79])),new R.ptr(478,495,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(497,497,$toNativeArray($kindInt32,[0,2,1])),new R.ptr(498,498,$toNativeArray($kindInt32,[-1,1,0])),new R.ptr(499,499,$toNativeArray($kindInt32,[-2,0,-1])),new R.ptr(500,501,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(502,502,$toNativeArray($kindInt32,[0,-97,0])),new R.ptr(503,503,$toNativeArray($kindInt32,[0,-56,0])),new R.ptr(504,543,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(544,544,$toNativeArray($kindInt32,[0,-130,0])),new R.ptr(546,563,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(570,570,$toNativeArray($kindInt32,[0,10795,0])),new R.ptr(571,572,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(573,573,$toNativeArray($kindInt32,[0,-163,0])),new R.ptr(574,574,$toNativeArray($kindInt32,[0,10792,0])),new R.ptr(575,576,$toNativeArray($kindInt32,[10815,0,10815])),new R.ptr(577,578,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(579,579,$toNativeArray($kindInt32,[0,-195,0])),new R.ptr(580,580,$toNativeArray($kindInt32,[0,69,0])),new R.ptr(581,581,$toNativeArray($kindInt32,[0,71,0])),new R.ptr(582,591,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(592,592,$toNativeArray($kindInt32,[10783,0,10783])),new R.ptr(593,593,$toNativeArray($kindInt32,[10780,0,10780])),new R.ptr(594,594,$toNativeArray($kindInt32,[10782,0,10782])),new R.ptr(595,595,$toNativeArray($kindInt32,[-210,0,-210])),new R.ptr(596,596,$toNativeArray($kindInt32,[-206,0,-206])),new R.ptr(598,599,$toNativeArray($kindInt32,[-205,0,-205])),new R.ptr(601,601,$toNativeArray($kindInt32,[-202,0,-202])),new R.ptr(603,603,$toNativeArray($kindInt32,[-203,0,-203])),new R.ptr(604,604,$toNativeArray($kindInt32,[42319,0,42319])),new R.ptr(608,608,$toNativeArray($kindInt32,[-205,0,-205])),new R.ptr(609,609,$toNativeArray($kindInt32,[42315,0,42315])),new R.ptr(611,611,$toNativeArray($kindInt32,[-207,0,-207])),new R.ptr(613,613,$toNativeArray($kindInt32,[42280,0,42280])),new R.ptr(614,614,$toNativeArray($kindInt32,[42308,0,42308])),new R.ptr(616,616,$toNativeArray($kindInt32,[-209,0,-209])),new R.ptr(617,617,$toNativeArray($kindInt32,[-211,0,-211])),new R.ptr(618,618,$toNativeArray($kindInt32,[42308,0,42308])),new R.ptr(619,619,$toNativeArray($kindInt32,[10743,0,10743])),new R.ptr(620,620,$toNativeArray($kindInt32,[42305,0,42305])),new R.ptr(623,623,$toNativeArray($kindInt32,[-211,0,-211])),new R.ptr(625,625,$toNativeArray($kindInt32,[10749,0,10749])),new R.ptr(626,626,$toNativeArray($kindInt32,[-213,0,-213])),new R.ptr(629,629,$toNativeArray($kindInt32,[-214,0,-214])),new R.ptr(637,637,$toNativeArray($kindInt32,[10727,0,10727])),new R.ptr(640,640,$toNativeArray($kindInt32,[-218,0,-218])),new R.ptr(643,643,$toNativeArray($kindInt32,[-218,0,-218])),new R.ptr(647,647,$toNativeArray($kindInt32,[42282,0,42282])),new R.ptr(648,648,$toNativeArray($kindInt32,[-218,0,-218])),new R.ptr(649,649,$toNativeArray($kindInt32,[-69,0,-69])),new R.ptr(650,651,$toNativeArray($kindInt32,[-217,0,-217])),new R.ptr(652,652,$toNativeArray($kindInt32,[-71,0,-71])),new R.ptr(658,658,$toNativeArray($kindInt32,[-219,0,-219])),new R.ptr(669,669,$toNativeArray($kindInt32,[42261,0,42261])),new R.ptr(670,670,$toNativeArray($kindInt32,[42258,0,42258])),new R.ptr(837,837,$toNativeArray($kindInt32,[84,0,84])),new R.ptr(880,883,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(886,887,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(891,893,$toNativeArray($kindInt32,[130,0,130])),new R.ptr(895,895,$toNativeArray($kindInt32,[0,116,0])),new R.ptr(902,902,$toNativeArray($kindInt32,[0,38,0])),new R.ptr(904,906,$toNativeArray($kindInt32,[0,37,0])),new R.ptr(908,908,$toNativeArray($kindInt32,[0,64,0])),new R.ptr(910,911,$toNativeArray($kindInt32,[0,63,0])),new R.ptr(913,929,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(931,939,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(940,940,$toNativeArray($kindInt32,[-38,0,-38])),new R.ptr(941,943,$toNativeArray($kindInt32,[-37,0,-37])),new R.ptr(945,961,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(962,962,$toNativeArray($kindInt32,[-31,0,-31])),new R.ptr(963,971,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(972,972,$toNativeArray($kindInt32,[-64,0,-64])),new R.ptr(973,974,$toNativeArray($kindInt32,[-63,0,-63])),new R.ptr(975,975,$toNativeArray($kindInt32,[0,8,0])),new R.ptr(976,976,$toNativeArray($kindInt32,[-62,0,-62])),new R.ptr(977,977,$toNativeArray($kindInt32,[-57,0,-57])),new R.ptr(981,981,$toNativeArray($kindInt32,[-47,0,-47])),new R.ptr(982,982,$toNativeArray($kindInt32,[-54,0,-54])),new R.ptr(983,983,$toNativeArray($kindInt32,[-8,0,-8])),new R.ptr(984,1007,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1008,1008,$toNativeArray($kindInt32,[-86,0,-86])),new R.ptr(1009,1009,$toNativeArray($kindInt32,[-80,0,-80])),new R.ptr(1010,1010,$toNativeArray($kindInt32,[7,0,7])),new R.ptr(1011,1011,$toNativeArray($kindInt32,[-116,0,-116])),new R.ptr(1012,1012,$toNativeArray($kindInt32,[0,-60,0])),new R.ptr(1013,1013,$toNativeArray($kindInt32,[-96,0,-96])),new R.ptr(1015,1016,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1017,1017,$toNativeArray($kindInt32,[0,-7,0])),new R.ptr(1018,1019,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1021,1023,$toNativeArray($kindInt32,[0,-130,0])),new R.ptr(1024,1039,$toNativeArray($kindInt32,[0,80,0])),new R.ptr(1040,1071,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(1072,1103,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(1104,1119,$toNativeArray($kindInt32,[-80,0,-80])),new R.ptr(1120,1153,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1162,1215,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1216,1216,$toNativeArray($kindInt32,[0,15,0])),new R.ptr(1217,1230,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1231,1231,$toNativeArray($kindInt32,[-15,0,-15])),new R.ptr(1232,1327,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(1329,1366,$toNativeArray($kindInt32,[0,48,0])),new R.ptr(1377,1414,$toNativeArray($kindInt32,[-48,0,-48])),new R.ptr(4256,4293,$toNativeArray($kindInt32,[0,7264,0])),new R.ptr(4295,4295,$toNativeArray($kindInt32,[0,7264,0])),new R.ptr(4301,4301,$toNativeArray($kindInt32,[0,7264,0])),new R.ptr(5024,5103,$toNativeArray($kindInt32,[0,38864,0])),new R.ptr(5104,5109,$toNativeArray($kindInt32,[0,8,0])),new R.ptr(5112,5117,$toNativeArray($kindInt32,[-8,0,-8])),new R.ptr(7296,7296,$toNativeArray($kindInt32,[-6254,0,-6254])),new R.ptr(7297,7297,$toNativeArray($kindInt32,[-6253,0,-6253])),new R.ptr(7298,7298,$toNativeArray($kindInt32,[-6244,0,-6244])),new R.ptr(7299,7300,$toNativeArray($kindInt32,[-6242,0,-6242])),new R.ptr(7301,7301,$toNativeArray($kindInt32,[-6243,0,-6243])),new R.ptr(7302,7302,$toNativeArray($kindInt32,[-6236,0,-6236])),new R.ptr(7303,7303,$toNativeArray($kindInt32,[-6181,0,-6181])),new R.ptr(7304,7304,$toNativeArray($kindInt32,[35266,0,35266])),new R.ptr(7545,7545,$toNativeArray($kindInt32,[35332,0,35332])),new R.ptr(7549,7549,$toNativeArray($kindInt32,[3814,0,3814])),new R.ptr(7680,7829,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(7835,7835,$toNativeArray($kindInt32,[-59,0,-59])),new R.ptr(7838,7838,$toNativeArray($kindInt32,[0,-7615,0])),new R.ptr(7840,7935,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(7936,7943,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(7944,7951,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(7952,7957,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(7960,7965,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(7968,7975,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(7976,7983,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(7984,7991,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(7992,7999,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8000,8005,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8008,8013,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8017,8017,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8019,8019,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8021,8021,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8023,8023,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8025,8025,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8027,8027,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8029,8029,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8031,8031,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8032,8039,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8040,8047,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8048,8049,$toNativeArray($kindInt32,[74,0,74])),new R.ptr(8050,8053,$toNativeArray($kindInt32,[86,0,86])),new R.ptr(8054,8055,$toNativeArray($kindInt32,[100,0,100])),new R.ptr(8056,8057,$toNativeArray($kindInt32,[128,0,128])),new R.ptr(8058,8059,$toNativeArray($kindInt32,[112,0,112])),new R.ptr(8060,8061,$toNativeArray($kindInt32,[126,0,126])),new R.ptr(8064,8071,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8072,8079,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8080,8087,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8088,8095,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8096,8103,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8104,8111,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8112,8113,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8115,8115,$toNativeArray($kindInt32,[9,0,9])),new R.ptr(8120,8121,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8122,8123,$toNativeArray($kindInt32,[0,-74,0])),new R.ptr(8124,8124,$toNativeArray($kindInt32,[0,-9,0])),new R.ptr(8126,8126,$toNativeArray($kindInt32,[-7205,0,-7205])),new R.ptr(8131,8131,$toNativeArray($kindInt32,[9,0,9])),new R.ptr(8136,8139,$toNativeArray($kindInt32,[0,-86,0])),new R.ptr(8140,8140,$toNativeArray($kindInt32,[0,-9,0])),new R.ptr(8144,8145,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8152,8153,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8154,8155,$toNativeArray($kindInt32,[0,-100,0])),new R.ptr(8160,8161,$toNativeArray($kindInt32,[8,0,8])),new R.ptr(8165,8165,$toNativeArray($kindInt32,[7,0,7])),new R.ptr(8168,8169,$toNativeArray($kindInt32,[0,-8,0])),new R.ptr(8170,8171,$toNativeArray($kindInt32,[0,-112,0])),new R.ptr(8172,8172,$toNativeArray($kindInt32,[0,-7,0])),new R.ptr(8179,8179,$toNativeArray($kindInt32,[9,0,9])),new R.ptr(8184,8185,$toNativeArray($kindInt32,[0,-128,0])),new R.ptr(8186,8187,$toNativeArray($kindInt32,[0,-126,0])),new R.ptr(8188,8188,$toNativeArray($kindInt32,[0,-9,0])),new R.ptr(8486,8486,$toNativeArray($kindInt32,[0,-7517,0])),new R.ptr(8490,8490,$toNativeArray($kindInt32,[0,-8383,0])),new R.ptr(8491,8491,$toNativeArray($kindInt32,[0,-8262,0])),new R.ptr(8498,8498,$toNativeArray($kindInt32,[0,28,0])),new R.ptr(8526,8526,$toNativeArray($kindInt32,[-28,0,-28])),new R.ptr(8544,8559,$toNativeArray($kindInt32,[0,16,0])),new R.ptr(8560,8575,$toNativeArray($kindInt32,[-16,0,-16])),new R.ptr(8579,8580,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(9398,9423,$toNativeArray($kindInt32,[0,26,0])),new R.ptr(9424,9449,$toNativeArray($kindInt32,[-26,0,-26])),new R.ptr(11264,11310,$toNativeArray($kindInt32,[0,48,0])),new R.ptr(11312,11358,$toNativeArray($kindInt32,[-48,0,-48])),new R.ptr(11360,11361,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11362,11362,$toNativeArray($kindInt32,[0,-10743,0])),new R.ptr(11363,11363,$toNativeArray($kindInt32,[0,-3814,0])),new R.ptr(11364,11364,$toNativeArray($kindInt32,[0,-10727,0])),new R.ptr(11365,11365,$toNativeArray($kindInt32,[-10795,0,-10795])),new R.ptr(11366,11366,$toNativeArray($kindInt32,[-10792,0,-10792])),new R.ptr(11367,11372,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11373,11373,$toNativeArray($kindInt32,[0,-10780,0])),new R.ptr(11374,11374,$toNativeArray($kindInt32,[0,-10749,0])),new R.ptr(11375,11375,$toNativeArray($kindInt32,[0,-10783,0])),new R.ptr(11376,11376,$toNativeArray($kindInt32,[0,-10782,0])),new R.ptr(11378,11379,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11381,11382,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11390,11391,$toNativeArray($kindInt32,[0,-10815,0])),new R.ptr(11392,11491,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11499,11502,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11506,11507,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(11520,11557,$toNativeArray($kindInt32,[-7264,0,-7264])),new R.ptr(11559,11559,$toNativeArray($kindInt32,[-7264,0,-7264])),new R.ptr(11565,11565,$toNativeArray($kindInt32,[-7264,0,-7264])),new R.ptr(42560,42605,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42624,42651,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42786,42799,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42802,42863,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42873,42876,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42877,42877,$toNativeArray($kindInt32,[0,-35332,0])),new R.ptr(42878,42887,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42891,42892,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42893,42893,$toNativeArray($kindInt32,[0,-42280,0])),new R.ptr(42896,42899,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42902,42921,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(42922,42922,$toNativeArray($kindInt32,[0,-42308,0])),new R.ptr(42923,42923,$toNativeArray($kindInt32,[0,-42319,0])),new R.ptr(42924,42924,$toNativeArray($kindInt32,[0,-42315,0])),new R.ptr(42925,42925,$toNativeArray($kindInt32,[0,-42305,0])),new R.ptr(42926,42926,$toNativeArray($kindInt32,[0,-42308,0])),new R.ptr(42928,42928,$toNativeArray($kindInt32,[0,-42258,0])),new R.ptr(42929,42929,$toNativeArray($kindInt32,[0,-42282,0])),new R.ptr(42930,42930,$toNativeArray($kindInt32,[0,-42261,0])),new R.ptr(42931,42931,$toNativeArray($kindInt32,[0,928,0])),new R.ptr(42932,42935,$toNativeArray($kindInt32,[1114112,1114112,1114112])),new R.ptr(43859,43859,$toNativeArray($kindInt32,[-928,0,-928])),new R.ptr(43888,43967,$toNativeArray($kindInt32,[-38864,0,-38864])),new R.ptr(65313,65338,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(65345,65370,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(66560,66599,$toNativeArray($kindInt32,[0,40,0])),new R.ptr(66600,66639,$toNativeArray($kindInt32,[-40,0,-40])),new R.ptr(66736,66771,$toNativeArray($kindInt32,[0,40,0])),new R.ptr(66776,66811,$toNativeArray($kindInt32,[-40,0,-40])),new R.ptr(68736,68786,$toNativeArray($kindInt32,[0,64,0])),new R.ptr(68800,68850,$toNativeArray($kindInt32,[-64,0,-64])),new R.ptr(71840,71871,$toNativeArray($kindInt32,[0,32,0])),new R.ptr(71872,71903,$toNativeArray($kindInt32,[-32,0,-32])),new R.ptr(125184,125217,$toNativeArray($kindInt32,[0,34,0])),new R.ptr(125218,125251,$toNativeArray($kindInt32,[-34,0,-34]))]);$pkg.CaseRanges=IK;IL=$toNativeArray($kindUint8,[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,144,130,130,130,136,130,130,130,130,130,130,136,130,130,130,130,132,132,132,132,132,132,132,132,132,132,130,130,136,136,136,130,130,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,130,130,130,136,130,136,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,130,136,130,136,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,16,130,136,136,136,136,136,130,136,136,224,130,136,0,136,136,136,136,132,132,136,192,130,130,136,132,224,130,132,132,132,130,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,136,160,160,160,160,160,160,160,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,136,192,192,192,192,192,192,192,192]);IM=$toNativeArray($kindUint16,[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,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,96,65,66,67,68,69,70,71,72,73,74,8490,76,77,78,79,80,81,82,383,84,85,86,87,88,89,90,123,124,125,126,127]);IN=new JD([new AF.ptr(75,107),new AF.ptr(83,115),new AF.ptr(107,8490),new AF.ptr(115,383),new AF.ptr(181,924),new AF.ptr(197,229),new AF.ptr(223,7838),new AF.ptr(229,8491),new AF.ptr(304,304),new AF.ptr(305,305),new AF.ptr(383,83),new AF.ptr(452,453),new AF.ptr(453,454),new AF.ptr(454,452),new AF.ptr(455,456),new AF.ptr(456,457),new AF.ptr(457,455),new AF.ptr(458,459),new AF.ptr(459,460),new AF.ptr(460,458),new AF.ptr(497,498),new AF.ptr(498,499),new AF.ptr(499,497),new AF.ptr(837,921),new AF.ptr(914,946),new AF.ptr(917,949),new AF.ptr(920,952),new AF.ptr(921,953),new AF.ptr(922,954),new AF.ptr(924,956),new AF.ptr(928,960),new AF.ptr(929,961),new AF.ptr(931,962),new AF.ptr(934,966),new AF.ptr(937,969),new AF.ptr(946,976),new AF.ptr(949,1013),new AF.ptr(952,977),new AF.ptr(953,8126),new AF.ptr(954,1008),new AF.ptr(956,181),new AF.ptr(960,982),new AF.ptr(961,1009),new AF.ptr(962,963),new AF.ptr(963,931),new AF.ptr(966,981),new AF.ptr(969,8486),new AF.ptr(976,914),new AF.ptr(977,1012),new AF.ptr(981,934),new AF.ptr(982,928),new AF.ptr(1008,922),new AF.ptr(1009,929),new AF.ptr(1012,920),new AF.ptr(1013,917),new AF.ptr(1042,1074),new AF.ptr(1044,1076),new AF.ptr(1054,1086),new AF.ptr(1057,1089),new AF.ptr(1058,1090),new AF.ptr(1066,1098),new AF.ptr(1074,7296),new AF.ptr(1076,7297),new AF.ptr(1086,7298),new AF.ptr(1089,7299),new AF.ptr(1090,7300),new AF.ptr(1098,7302),new AF.ptr(1122,1123),new AF.ptr(1123,7303),new AF.ptr(7296,1042),new AF.ptr(7297,1044),new AF.ptr(7298,1054),new AF.ptr(7299,1057),new AF.ptr(7300,7301),new AF.ptr(7301,1058),new AF.ptr(7302,1066),new AF.ptr(7303,1122),new AF.ptr(7304,42570),new AF.ptr(7776,7777),new AF.ptr(7777,7835),new AF.ptr(7835,7776),new AF.ptr(7838,223),new AF.ptr(8126,837),new AF.ptr(8486,937),new AF.ptr(8490,75),new AF.ptr(8491,197),new AF.ptr(42570,42571),new AF.ptr(42571,7304)]);IO=new O.ptr(new IY([new P.ptr(837,837,1)]),IZ.nil,0);IP=new O.ptr(new IY([new P.ptr(65,90,1),new P.ptr(192,214,1),new P.ptr(216,222,1),new P.ptr(256,302,2),new P.ptr(306,310,2),new P.ptr(313,327,2),new P.ptr(330,376,2),new P.ptr(377,381,2),new P.ptr(385,386,1),new P.ptr(388,390,2),new P.ptr(391,393,2),new P.ptr(394,395,1),new P.ptr(398,401,1),new P.ptr(403,404,1),new P.ptr(406,408,1),new P.ptr(412,413,1),new P.ptr(415,416,1),new P.ptr(418,422,2),new P.ptr(423,425,2),new P.ptr(428,430,2),new P.ptr(431,433,2),new P.ptr(434,435,1),new P.ptr(437,439,2),new P.ptr(440,444,4),new P.ptr(452,453,1),new P.ptr(455,456,1),new P.ptr(458,459,1),new P.ptr(461,475,2),new P.ptr(478,494,2),new P.ptr(497,498,1),new P.ptr(500,502,2),new P.ptr(503,504,1),new P.ptr(506,562,2),new P.ptr(570,571,1),new P.ptr(573,574,1),new P.ptr(577,579,2),new P.ptr(580,582,1),new P.ptr(584,590,2),new P.ptr(837,880,43),new P.ptr(882,886,4),new P.ptr(895,902,7),new P.ptr(904,906,1),new P.ptr(908,910,2),new P.ptr(911,913,2),new P.ptr(914,929,1),new P.ptr(931,939,1),new P.ptr(975,984,9),new P.ptr(986,1006,2),new P.ptr(1012,1015,3),new P.ptr(1017,1018,1),new P.ptr(1021,1071,1),new P.ptr(1120,1152,2),new P.ptr(1162,1216,2),new P.ptr(1217,1229,2),new P.ptr(1232,1326,2),new P.ptr(1329,1366,1),new P.ptr(4256,4293,1),new P.ptr(4295,4301,6),new P.ptr(5024,5109,1),new P.ptr(7680,7828,2),new P.ptr(7838,7934,2),new P.ptr(7944,7951,1),new P.ptr(7960,7965,1),new P.ptr(7976,7983,1),new P.ptr(7992,7999,1),new P.ptr(8008,8013,1),new P.ptr(8025,8031,2),new P.ptr(8040,8047,1),new P.ptr(8072,8079,1),new P.ptr(8088,8095,1),new P.ptr(8104,8111,1),new P.ptr(8120,8124,1),new P.ptr(8136,8140,1),new P.ptr(8152,8155,1),new P.ptr(8168,8172,1),new P.ptr(8184,8188,1),new P.ptr(8486,8490,4),new P.ptr(8491,8498,7),new P.ptr(8579,11264,2685),new P.ptr(11265,11310,1),new P.ptr(11360,11362,2),new P.ptr(11363,11364,1),new P.ptr(11367,11373,2),new P.ptr(11374,11376,1),new P.ptr(11378,11381,3),new P.ptr(11390,11392,1),new P.ptr(11394,11490,2),new P.ptr(11499,11501,2),new P.ptr(11506,42560,31054),new P.ptr(42562,42604,2),new P.ptr(42624,42650,2),new P.ptr(42786,42798,2),new P.ptr(42802,42862,2),new P.ptr(42873,42877,2),new P.ptr(42878,42886,2),new P.ptr(42891,42893,2),new P.ptr(42896,42898,2),new P.ptr(42902,42922,2),new P.ptr(42923,42926,1),new P.ptr(42928,42932,1),new P.ptr(42934,65313,22379),new P.ptr(65314,65338,1)]),new IZ([new Q.ptr(66560,66599,1),new Q.ptr(66736,66771,1),new Q.ptr(68736,68786,1),new Q.ptr(71840,71871,1),new Q.ptr(125184,125217,1)]),3);IQ=new O.ptr(new IY([new P.ptr(452,454,2),new P.ptr(455,457,2),new P.ptr(458,460,2),new P.ptr(497,499,2),new P.ptr(8064,8071,1),new P.ptr(8080,8087,1),new P.ptr(8096,8103,1),new P.ptr(8115,8131,16),new P.ptr(8179,8179,1)]),IZ.nil,0);IR=new O.ptr(new IY([new P.ptr(97,122,1),new P.ptr(181,223,42),new P.ptr(224,246,1),new P.ptr(248,255,1),new P.ptr(257,303,2),new P.ptr(307,311,2),new P.ptr(314,328,2),new P.ptr(331,375,2),new P.ptr(378,382,2),new P.ptr(383,384,1),new P.ptr(387,389,2),new P.ptr(392,396,4),new P.ptr(402,405,3),new P.ptr(409,410,1),new P.ptr(414,417,3),new P.ptr(419,421,2),new P.ptr(424,429,5),new P.ptr(432,436,4),new P.ptr(438,441,3),new P.ptr(445,447,2),new P.ptr(453,454,1),new P.ptr(456,457,1),new P.ptr(459,460,1),new P.ptr(462,476,2),new P.ptr(477,495,2),new P.ptr(498,499,1),new P.ptr(501,505,4),new P.ptr(507,543,2),new P.ptr(547,563,2),new P.ptr(572,575,3),new P.ptr(576,578,2),new P.ptr(583,591,2),new P.ptr(592,596,1),new P.ptr(598,599,1),new P.ptr(601,603,2),new P.ptr(604,608,4),new P.ptr(609,613,2),new P.ptr(614,616,2),new P.ptr(617,620,1),new P.ptr(623,625,2),new P.ptr(626,629,3),new P.ptr(637,643,3),new P.ptr(647,652,1),new P.ptr(658,669,11),new P.ptr(670,837,167),new P.ptr(881,883,2),new P.ptr(887,891,4),new P.ptr(892,893,1),new P.ptr(940,943,1),new P.ptr(945,974,1),new P.ptr(976,977,1),new P.ptr(981,983,1),new P.ptr(985,1007,2),new P.ptr(1008,1011,1),new P.ptr(1013,1019,3),new P.ptr(1072,1119,1),new P.ptr(1121,1153,2),new P.ptr(1163,1215,2),new P.ptr(1218,1230,2),new P.ptr(1231,1327,2),new P.ptr(1377,1414,1),new P.ptr(5112,5117,1),new P.ptr(7296,7304,1),new P.ptr(7545,7549,4),new P.ptr(7681,7829,2),new P.ptr(7835,7841,6),new P.ptr(7843,7935,2),new P.ptr(7936,7943,1),new P.ptr(7952,7957,1),new P.ptr(7968,7975,1),new P.ptr(7984,7991,1),new P.ptr(8000,8005,1),new P.ptr(8017,8023,2),new P.ptr(8032,8039,1),new P.ptr(8048,8061,1),new P.ptr(8112,8113,1),new P.ptr(8126,8144,18),new P.ptr(8145,8160,15),new P.ptr(8161,8165,4),new P.ptr(8526,8580,54),new P.ptr(11312,11358,1),new P.ptr(11361,11365,4),new P.ptr(11366,11372,2),new P.ptr(11379,11382,3),new P.ptr(11393,11491,2),new P.ptr(11500,11502,2),new P.ptr(11507,11520,13),new P.ptr(11521,11557,1),new P.ptr(11559,11565,6),new P.ptr(42561,42605,2),new P.ptr(42625,42651,2),new P.ptr(42787,42799,2),new P.ptr(42803,42863,2),new P.ptr(42874,42876,2),new P.ptr(42879,42887,2),new P.ptr(42892,42897,5),new P.ptr(42899,42903,4),new P.ptr(42905,42921,2),new P.ptr(42933,42935,2),new P.ptr(43859,43888,29),new P.ptr(43889,43967,1),new P.ptr(65345,65370,1)]),new IZ([new Q.ptr(66600,66639,1),new Q.ptr(66776,66811,1),new Q.ptr(68800,68850,1),new Q.ptr(71872,71903,1),new Q.ptr(125218,125251,1)]),4);IS=new O.ptr(new IY([new P.ptr(921,953,32),new P.ptr(8126,8126,1)]),IZ.nil,0);IT=new O.ptr(new IY([new P.ptr(921,953,32),new P.ptr(8126,8126,1)]),IZ.nil,0);$pkg.FoldCategory=$makeMap($String.keyFor,[{k:\"L\",v:IO},{k:\"Ll\",v:IP},{k:\"Lt\",v:IQ},{k:\"Lu\",v:IR},{k:\"M\",v:IS},{k:\"Mn\",v:IT}]);IU=new O.ptr(new IY([new P.ptr(924,956,32)]),IZ.nil,0);IV=new O.ptr(new IY([new P.ptr(181,837,656)]),IZ.nil,0);IW=new O.ptr(new IY([new P.ptr(921,953,32),new P.ptr(8126,8126,1)]),IZ.nil,0);$pkg.FoldScript=$makeMap($String.keyFor,[{k:\"Common\",v:IU},{k:\"Greek\",v:IV},{k:\"Inherited\",v:IW}]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"reflect\"]=(function(){var $pkg={},$init,A,C,H,D,B,E,F,G,N,P,Q,R,AW,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CS,DB,DC,DD,DG,DH,DI,EY,EZ,FC,FM,HQ,HR,HS,HV,HW,HX,HY,HZ,IA,IB,IC,ID,IE,IF,IG,IH,II,IJ,IK,IL,IM,IP,IQ,IR,IS,IT,IU,JC,JE,JG,JH,JI,JJ,JQ,JR,JS,I,O,S,U,W,BJ,BK,BO,CT,FL,J,K,L,M,T,V,X,Y,Z,AA,AB,AC,AD,AE,AH,AJ,AK,AL,AM,AO,AS,AT,AU,AV,AX,AY,AZ,BA,BB,BC,BE,BF,BG,BH,BI,BL,BM,BN,BP,BQ,DK,DM,DN,DO,DP,EQ,EV,FN,FO,GG,GH,GJ,GK,GL,GM,GN,GO,GP,GQ,GR,GS,GT,GU,GV,GW,GX,GY,GZ,HA,HB,HC,HD,HE;A=$packages[\"errors\"];C=$packages[\"github.com/gopherjs/gopherjs/js\"];H=$packages[\"math\"];D=$packages[\"runtime\"];B=$packages[\"strconv\"];E=$packages[\"sync\"];F=$packages[\"unicode\"];G=$packages[\"unicode/utf8\"];N=$pkg.uncommonType=$newType(0,$kindStruct,\"reflect.uncommonType\",true,\"reflect\",false,function(pkgPath_,mcount_,xcount_,moff_,_methods_){this.$val=this;if(arguments.length===0){this.pkgPath=0;this.mcount=0;this.xcount=0;this.moff=0;this._methods=IB.nil;return;}this.pkgPath=pkgPath_;this.mcount=mcount_;this.xcount=xcount_;this.moff=moff_;this._methods=_methods_;});P=$pkg.funcType=$newType(0,$kindStruct,\"reflect.funcType\",true,\"reflect\",false,function(rtype_,inCount_,outCount_,_in_,_out_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.inCount=0;this.outCount=0;this._in=HS.nil;this._out=HS.nil;return;}this.rtype=rtype_;this.inCount=inCount_;this.outCount=outCount_;this._in=_in_;this._out=_out_;});Q=$pkg.name=$newType(0,$kindStruct,\"reflect.name\",true,\"reflect\",false,function(bytes_){this.$val=this;if(arguments.length===0){this.bytes=IA.nil;return;}this.bytes=bytes_;});R=$pkg.nameData=$newType(0,$kindStruct,\"reflect.nameData\",true,\"reflect\",false,function(name_,tag_,exported_){this.$val=this;if(arguments.length===0){this.name=\"\";this.tag=\"\";this.exported=false;return;}this.name=name_;this.tag=tag_;this.exported=exported_;});AW=$pkg.mapIter=$newType(0,$kindStruct,\"reflect.mapIter\",true,\"reflect\",false,function(t_,m_,keys_,i_,last_){this.$val=this;if(arguments.length===0){this.t=$ifaceNil;this.m=null;this.keys=null;this.i=0;this.last=null;return;}this.t=t_;this.m=m_;this.keys=keys_;this.i=i_;this.last=last_;});CB=$pkg.Type=$newType(8,$kindInterface,\"reflect.Type\",true,\"reflect\",true,null);CC=$pkg.Kind=$newType(4,$kindUint,\"reflect.Kind\",true,\"reflect\",true,null);CD=$pkg.tflag=$newType(1,$kindUint8,\"reflect.tflag\",true,\"reflect\",false,null);CE=$pkg.rtype=$newType(0,$kindStruct,\"reflect.rtype\",true,\"reflect\",false,function(size_,ptrdata_,hash_,tflag_,align_,fieldAlign_,kind_,alg_,gcdata_,str_,ptrToThis_){this.$val=this;if(arguments.length===0){this.size=0;this.ptrdata=0;this.hash=0;this.tflag=0;this.align=0;this.fieldAlign=0;this.kind=0;this.alg=HZ.nil;this.gcdata=IA.nil;this.str=0;this.ptrToThis=0;return;}this.size=size_;this.ptrdata=ptrdata_;this.hash=hash_;this.tflag=tflag_;this.align=align_;this.fieldAlign=fieldAlign_;this.kind=kind_;this.alg=alg_;this.gcdata=gcdata_;this.str=str_;this.ptrToThis=ptrToThis_;});CF=$pkg.typeAlg=$newType(0,$kindStruct,\"reflect.typeAlg\",true,\"reflect\",false,function(hash_,equal_){this.$val=this;if(arguments.length===0){this.hash=$throwNilPointerError;this.equal=$throwNilPointerError;return;}this.hash=hash_;this.equal=equal_;});CG=$pkg.method=$newType(0,$kindStruct,\"reflect.method\",true,\"reflect\",false,function(name_,mtyp_,ifn_,tfn_){this.$val=this;if(arguments.length===0){this.name=0;this.mtyp=0;this.ifn=0;this.tfn=0;return;}this.name=name_;this.mtyp=mtyp_;this.ifn=ifn_;this.tfn=tfn_;});CH=$pkg.ChanDir=$newType(4,$kindInt,\"reflect.ChanDir\",true,\"reflect\",true,null);CI=$pkg.arrayType=$newType(0,$kindStruct,\"reflect.arrayType\",true,\"reflect\",false,function(rtype_,elem_,slice_,len_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.elem=HR.nil;this.slice=HR.nil;this.len=0;return;}this.rtype=rtype_;this.elem=elem_;this.slice=slice_;this.len=len_;});CJ=$pkg.chanType=$newType(0,$kindStruct,\"reflect.chanType\",true,\"reflect\",false,function(rtype_,elem_,dir_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.elem=HR.nil;this.dir=0;return;}this.rtype=rtype_;this.elem=elem_;this.dir=dir_;});CK=$pkg.imethod=$newType(0,$kindStruct,\"reflect.imethod\",true,\"reflect\",false,function(name_,typ_){this.$val=this;if(arguments.length===0){this.name=0;this.typ=0;return;}this.name=name_;this.typ=typ_;});CL=$pkg.interfaceType=$newType(0,$kindStruct,\"reflect.interfaceType\",true,\"reflect\",false,function(rtype_,pkgPath_,methods_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.pkgPath=new Q.ptr(IA.nil);this.methods=IC.nil;return;}this.rtype=rtype_;this.pkgPath=pkgPath_;this.methods=methods_;});CM=$pkg.mapType=$newType(0,$kindStruct,\"reflect.mapType\",true,\"reflect\",false,function(rtype_,key_,elem_,bucket_,keysize_,valuesize_,bucketsize_,flags_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.key=HR.nil;this.elem=HR.nil;this.bucket=HR.nil;this.keysize=0;this.valuesize=0;this.bucketsize=0;this.flags=0;return;}this.rtype=rtype_;this.key=key_;this.elem=elem_;this.bucket=bucket_;this.keysize=keysize_;this.valuesize=valuesize_;this.bucketsize=bucketsize_;this.flags=flags_;});CN=$pkg.ptrType=$newType(0,$kindStruct,\"reflect.ptrType\",true,\"reflect\",false,function(rtype_,elem_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.elem=HR.nil;return;}this.rtype=rtype_;this.elem=elem_;});CO=$pkg.sliceType=$newType(0,$kindStruct,\"reflect.sliceType\",true,\"reflect\",false,function(rtype_,elem_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.elem=HR.nil;return;}this.rtype=rtype_;this.elem=elem_;});CP=$pkg.structField=$newType(0,$kindStruct,\"reflect.structField\",true,\"reflect\",false,function(name_,typ_,offsetEmbed_){this.$val=this;if(arguments.length===0){this.name=new Q.ptr(IA.nil);this.typ=HR.nil;this.offsetEmbed=0;return;}this.name=name_;this.typ=typ_;this.offsetEmbed=offsetEmbed_;});CQ=$pkg.structType=$newType(0,$kindStruct,\"reflect.structType\",true,\"reflect\",false,function(rtype_,pkgPath_,fields_){this.$val=this;if(arguments.length===0){this.rtype=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);this.pkgPath=new Q.ptr(IA.nil);this.fields=ID.nil;return;}this.rtype=rtype_;this.pkgPath=pkgPath_;this.fields=fields_;});CS=$pkg.Method=$newType(0,$kindStruct,\"reflect.Method\",true,\"reflect\",true,function(Name_,PkgPath_,Type_,Func_,Index_){this.$val=this;if(arguments.length===0){this.Name=\"\";this.PkgPath=\"\";this.Type=$ifaceNil;this.Func=new EY.ptr(HR.nil,0,0);this.Index=0;return;}this.Name=Name_;this.PkgPath=PkgPath_;this.Type=Type_;this.Func=Func_;this.Index=Index_;});DB=$pkg.nameOff=$newType(4,$kindInt32,\"reflect.nameOff\",true,\"reflect\",false,null);DC=$pkg.typeOff=$newType(4,$kindInt32,\"reflect.typeOff\",true,\"reflect\",false,null);DD=$pkg.textOff=$newType(4,$kindInt32,\"reflect.textOff\",true,\"reflect\",false,null);DG=$pkg.StructField=$newType(0,$kindStruct,\"reflect.StructField\",true,\"reflect\",true,function(Name_,PkgPath_,Type_,Tag_,Offset_,Index_,Anonymous_){this.$val=this;if(arguments.length===0){this.Name=\"\";this.PkgPath=\"\";this.Type=$ifaceNil;this.Tag=\"\";this.Offset=0;this.Index=IR.nil;this.Anonymous=false;return;}this.Name=Name_;this.PkgPath=PkgPath_;this.Type=Type_;this.Tag=Tag_;this.Offset=Offset_;this.Index=Index_;this.Anonymous=Anonymous_;});DH=$pkg.StructTag=$newType(8,$kindString,\"reflect.StructTag\",true,\"reflect\",true,null);DI=$pkg.fieldScan=$newType(0,$kindStruct,\"reflect.fieldScan\",true,\"reflect\",false,function(typ_,index_){this.$val=this;if(arguments.length===0){this.typ=IT.nil;this.index=IR.nil;return;}this.typ=typ_;this.index=index_;});EY=$pkg.Value=$newType(0,$kindStruct,\"reflect.Value\",true,\"reflect\",true,function(typ_,ptr_,flag_){this.$val=this;if(arguments.length===0){this.typ=HR.nil;this.ptr=0;this.flag=0;return;}this.typ=typ_;this.ptr=ptr_;this.flag=flag_;});EZ=$pkg.flag=$newType(4,$kindUintptr,\"reflect.flag\",true,\"reflect\",false,null);FC=$pkg.ValueError=$newType(0,$kindStruct,\"reflect.ValueError\",true,\"reflect\",true,function(Method_,Kind_){this.$val=this;if(arguments.length===0){this.Method=\"\";this.Kind=0;return;}this.Method=Method_;this.Kind=Kind_;});FM=$pkg.MapIter=$newType(0,$kindStruct,\"reflect.MapIter\",true,\"reflect\",true,function(m_,it_){this.$val=this;if(arguments.length===0){this.m=new EY.ptr(HR.nil,0,0);this.it=0;return;}this.m=m_;this.it=it_;});HQ=$sliceType(Q);HR=$ptrType(CE);HS=$sliceType(HR);HV=$sliceType($emptyInterface);HW=$ptrType(C.Object);HX=$funcType([HV],[HW],true);HY=$sliceType($String);HZ=$ptrType(CF);IA=$ptrType($Uint8);IB=$sliceType(CG);IC=$sliceType(CK);ID=$sliceType(CP);IE=$ptrType(N);IF=$ptrType(R);IG=$structType(\"reflect\",[{prop:\"str\",name:\"str\",embedded:false,exported:false,typ:$String,tag:\"\"}]);IH=$sliceType(HW);II=$sliceType(EY);IJ=$ptrType(AW);IK=$ptrType(P);IL=$sliceType(CB);IM=$sliceType(IH);IP=$ptrType(CL);IQ=$ptrType(CK);IR=$sliceType($Int);IS=$sliceType(DI);IT=$ptrType(CQ);IU=$sliceType($Uint8);JC=$ptrType($UnsafePointer);JE=$sliceType($Int32);JG=$funcType([$String],[$Bool],false);JH=$funcType([$UnsafePointer,$Uintptr],[$Uintptr],false);JI=$funcType([$UnsafePointer,$UnsafePointer],[$Bool],false);JJ=$ptrType(CP);JQ=$arrayType($Uintptr,2);JR=$ptrType(FM);JS=$ptrType(FC);J=function(){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=(function(an){var an;});$r=an((ao=new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),new ao.constructor.elem(ao)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((ap=new N.ptr(0,0,0,0,IB.nil),new ap.constructor.elem(ap)));$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((aq=new CG.ptr(0,0,0,0),new aq.constructor.elem(aq)));$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((ar=new CI.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),HR.nil,HR.nil,0),new ar.constructor.elem(ar)));$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((as=new CJ.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),HR.nil,0),new as.constructor.elem(as)));$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((at=new P.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),0,0,HS.nil,HS.nil),new at.constructor.elem(at)));$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((au=new CL.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),new Q.ptr(IA.nil),IC.nil),new au.constructor.elem(au)));$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((av=new CM.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),HR.nil,HR.nil,HR.nil,0,0,0,0),new av.constructor.elem(av)));$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((aw=new CN.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),HR.nil),new aw.constructor.elem(aw)));$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((ax=new CO.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),HR.nil),new ax.constructor.elem(ax)));$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((ay=new CQ.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),new Q.ptr(IA.nil),ID.nil),new ay.constructor.elem(ay)));$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((az=new CK.ptr(0,0),new az.constructor.elem(az)));$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=an((ba=new CP.ptr(new Q.ptr(IA.nil),HR.nil,0),new ba.constructor.elem(ba)));$s=13;case 13:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}I=true;FL=$assertType(AD(new $Uint8(0)),HR);$s=-1;return;}return;}if($f===undefined){$f={$blk:J};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.$s=$s;$f.$r=$r;return $f;};K=function(an){var an;return an.jsType;};L=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz;if(an.reflectType===undefined){ao=new CE.ptr(((($parseInt(an.size)>>0)>>>0)),0,0,0,0,0,((($parseInt(an.kind)>>0)<<24>>>24)),HZ.nil,IA.nil,V($clone(T(Y(an.string),\"\",!!(an.exported)),Q)),0);ao.jsType=an;an.reflectType=ao;ap=$methodSet(an);if(!(($parseInt(ap.length)===0))||!!(an.named)){ao.tflag=(ao.tflag|(1))>>>0;if(!!(an.named)){ao.tflag=(ao.tflag|(4))>>>0;}aq=IB.nil;ar=0;while(true){if(!(ar<$parseInt(ap.length))){break;}as=ap[ar];at=Y(as.pkg)===\"\";if(!at){ar=ar+(1)>>0;continue;}aq=$append(aq,new CG.ptr(V($clone(T(Y(as.name),\"\",at),Q)),X(L(as.typ)),0,0));ar=ar+(1)>>0;}au=((aq.$length<<16>>>16));av=0;while(true){if(!(av<$parseInt(ap.length))){break;}aw=ap[av];ax=Y(aw.pkg)===\"\";if(ax){av=av+(1)>>0;continue;}aq=$append(aq,new CG.ptr(V($clone(T(Y(aw.name),\"\",ax),Q)),X(L(aw.typ)),0,0));av=av+(1)>>0;}ay=new N.ptr(V($clone(T(Y(an.pkg),\"\",false),Q)),(($parseInt(ap.length)<<16>>>16)),au,0,aq);az=ao;(O||$throwRuntimeError(\"assignment to entry in nil map\"))[HR.keyFor(az)]={k:az,v:ay};ay.jsType=an;}ba=ao.Kind();if(ba===(17)){M(ao,new CI.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),L(an.elem),HR.nil,((($parseInt(an.len)>>0)>>>0))));}else if(ba===(18)){bb=3;if(!!(an.sendOnly)){bb=2;}if(!!(an.recvOnly)){bb=1;}M(ao,new CJ.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),L(an.elem),((bb>>>0))));}else if(ba===(19)){bc=an.params;bd=$makeSlice(HS,$parseInt(bc.length));be=bd;bf=0;while(true){if(!(bf<be.$length)){break;}bg=bf;((bg<0||bg>=bd.$length)?($throwRuntimeError(\"index out of range\"),undefined):bd.$array[bd.$offset+bg]=L(bc[bg]));bf++;}bh=an.results;bi=$makeSlice(HS,$parseInt(bh.length));bj=bi;bk=0;while(true){if(!(bk<bj.$length)){break;}bl=bk;((bl<0||bl>=bi.$length)?($throwRuntimeError(\"index out of range\"),undefined):bi.$array[bi.$offset+bl]=L(bh[bl]));bk++;}bm=(($parseInt(bh.length)<<16>>>16));if(!!(an.variadic)){bm=(bm|(32768))>>>0;}M(ao,new P.ptr($clone(ao,CE),(($parseInt(bc.length)<<16>>>16)),bm,bd,bi));}else if(ba===(20)){bn=an.methods;bo=$makeSlice(IC,$parseInt(bn.length));bp=bo;bq=0;while(true){if(!(bq<bp.$length)){break;}br=bq;bs=bn[br];CK.copy(((br<0||br>=bo.$length)?($throwRuntimeError(\"index out of range\"),undefined):bo.$array[bo.$offset+br]),new CK.ptr(V($clone(T(Y(bs.name),\"\",Y(bs.pkg)===\"\"),Q)),X(L(bs.typ))));bq++;}M(ao,new CL.ptr($clone(ao,CE),$clone(T(Y(an.pkg),\"\",false),Q),bo));}else if(ba===(21)){M(ao,new CM.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),L(an.key),L(an.elem),HR.nil,0,0,0,0));}else if(ba===(22)){M(ao,new CN.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),L(an.elem)));}else if(ba===(23)){M(ao,new CO.ptr(new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0),L(an.elem)));}else if(ba===(25)){bt=an.fields;bu=$makeSlice(ID,$parseInt(bt.length));bv=bu;bw=0;while(true){if(!(bw<bv.$length)){break;}bx=bw;by=bt[bx];bz=((bx>>>0))<<1>>>0;if(!!(by.embedded)){bz=(bz|(1))>>>0;}CP.copy(((bx<0||bx>=bu.$length)?($throwRuntimeError(\"index out of range\"),undefined):bu.$array[bu.$offset+bx]),new CP.ptr($clone(T(Y(by.name),Y(by.tag),!!(by.exported)),Q),L(by.typ),bz));bw++;}M(ao,new CQ.ptr($clone(ao,CE),$clone(T(Y(an.pkgPath),\"\",false),Q),bu));}}return((an.reflectType));};M=function(an,ao){var an,ao;an.kindType=ao;ao.rtype=an;};N.ptr.prototype.methods=function(){var an;an=this;return an._methods;};N.prototype.methods=function(){return this.$val.methods();};N.ptr.prototype.exportedMethods=function(){var an;an=this;return $subslice(an._methods,0,an.xcount,an.xcount);};N.prototype.exportedMethods=function(){return this.$val.exportedMethods();};CE.ptr.prototype.uncommon=function(){var an,ao;an=this;return(ao=O[HR.keyFor(an)],ao!==undefined?ao.v:IE.nil);};CE.prototype.uncommon=function(){return this.$val.uncommon();};P.ptr.prototype.in$=function(){var an;an=this;return an._in;};P.prototype.in$=function(){return this.$val.in$();};P.ptr.prototype.out=function(){var an;an=this;return an._out;};P.prototype.out=function(){return this.$val.out();};Q.ptr.prototype.name=function(){var an,ao,ap;an=\"\";ao=this;an=(ap=S[IA.keyFor(ao.bytes)],ap!==undefined?ap.v:IF.nil).name;return an;};Q.prototype.name=function(){return this.$val.name();};Q.ptr.prototype.tag=function(){var an,ao,ap;an=\"\";ao=this;an=(ap=S[IA.keyFor(ao.bytes)],ap!==undefined?ap.v:IF.nil).tag;return an;};Q.prototype.tag=function(){return this.$val.tag();};Q.ptr.prototype.pkgPath=function(){var an;an=this;return\"\";};Q.prototype.pkgPath=function(){return this.$val.pkgPath();};Q.ptr.prototype.isExported=function(){var an,ao;an=this;return(ao=S[IA.keyFor(an.bytes)],ao!==undefined?ao.v:IF.nil).exported;};Q.prototype.isExported=function(){return this.$val.isExported();};T=function(an,ao,ap){var an,ao,ap,aq,ar;aq=$newDataPointer(0,IA);ar=aq;(S||$throwRuntimeError(\"assignment to entry in nil map\"))[IA.keyFor(ar)]={k:ar,v:new R.ptr(an,ao,ap)};return new Q.ptr(aq);};CE.ptr.prototype.nameOff=function(an){var an,ao,ap;ao=this;return(ap=((an>>0)),((ap<0||ap>=U.$length)?($throwRuntimeError(\"index out of range\"),undefined):U.$array[U.$offset+ap]));};CE.prototype.nameOff=function(an){return this.$val.nameOff(an);};V=function(an){var an,ao;ao=U.$length;U=$append(U,an);return((ao>>0));};CE.ptr.prototype.typeOff=function(an){var an,ao,ap;ao=this;return(ap=((an>>0)),((ap<0||ap>=W.$length)?($throwRuntimeError(\"index out of range\"),undefined):W.$array[W.$offset+ap]));};CE.prototype.typeOff=function(an){return this.$val.typeOff(an);};X=function(an){var an,ao;ao=W.$length;W=$append(W,an);return((ao>>0));};Y=function(an){var an,ao;ao=new IG.ptr(\"\");ao.str=an;return ao.str;};Z=function(an){var an;return!!(K(an).wrapped);};AA=function(an,ao,ap){var an,ao,ap,aq,ar,as;aq=K(ap).fields;ar=0;while(true){if(!(ar<$parseInt(aq.length))){break;}as=$internalize(aq[ar].prop,$String);an[$externalize(as,$String)]=ao[$externalize(as,$String)];ar=ar+(1)>>0;}};AB=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=an.common();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;au=an.Kind();$s=6;case 6:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}if(au===17){at=true;$s=5;continue s;}av=an.Kind();$s=7;case 7:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}at=av===25;case 5:if(at){as=true;$s=4;continue s;}aw=an.Kind();$s=8;case 8:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}as=aw===22;case 4:if(as){$s=2;continue;}$s=3;continue;case 2:ax=an.Kind();$s=9;case 9:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}$s=-1;return new EY.ptr(ar,(ao),(ap|((ax>>>0)))>>>0);case 3:ay=an.Kind();$s=10;case 10:if($c){$c=false;ay=ay.$blk();}if(ay&&ay.$blk!==undefined){break s;}$s=-1;return new EY.ptr(ar,($newDataPointer(ao,K(ar.ptrTo()))),(((ap|((ay>>>0)))>>>0)|128)>>>0);}return;}if($f===undefined){$f={$blk:AB};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.$s=$s;$f.$r=$r;return $f;};AC=function(an,ao,ap){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=[an];aq=an[0].Kind();$s=3;case 3:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}if(!((aq===23))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect.MakeSlice of non-slice type\"));case 2:if(ao<0){$panic(new $String(\"reflect.MakeSlice: negative len\"));}if(ap<0){$panic(new $String(\"reflect.MakeSlice: negative cap\"));}if(ao>ap){$panic(new $String(\"reflect.MakeSlice: len > cap\"));}ar=AB(an[0],$makeSlice(K(an[0]),ao,ap,(function(an){return function $b(){var ar,as,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;ar=$f.ar;as=$f.as;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ar=an[0].Elem();$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=K(ar);$s=2;case 2:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}$s=-1;return as.zero();}return;}if($f===undefined){$f={$blk:$b};}$f.ar=ar;$f.as=as;$f.$s=$s;$f.$r=$r;return $f;};})(an)),0);$s=4;case 4:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}$s=-1;return ar;}return;}if($f===undefined){$f={$blk:AC};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};$pkg.MakeSlice=AC;AD=function(an){var an;if(!I){return new CE.ptr(0,0,0,0,0,0,0,HZ.nil,IA.nil,0,0);}if($interfaceIsEqual(an,$ifaceNil)){return $ifaceNil;}return L(an.constructor);};$pkg.TypeOf=AD;AE=function(an){var an,ao,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if($interfaceIsEqual(an,$ifaceNil)){$s=-1;return new EY.ptr(HR.nil,0,0);}ao=AB(L(an.constructor),an.$val,0);$s=1;case 1:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}$s=-1;return ao;}return;}if($f===undefined){$f={$blk:AE};}$f.an=an;$f.ao=ao;$f.$s=$s;$f.$r=$r;return $f;};$pkg.ValueOf=AE;AH=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(!(ap)){aq=false;$s=3;continue s;}if(an.$length===0){ar=true;$s=4;continue s;}at=(as=an.$length-1>>0,((as<0||as>=an.$length)?($throwRuntimeError(\"index out of range\"),undefined):an.$array[an.$offset+as])).Kind();$s=5;case 5:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}ar=!((at===23));case 4:aq=ar;case 3:if(aq){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect.FuncOf: last arg of variadic func must be slice\"));case 2:au=$makeSlice(IH,an.$length);av=an;aw=0;while(true){if(!(aw<av.$length)){break;}ax=aw;ay=((aw<0||aw>=av.$length)?($throwRuntimeError(\"index out of range\"),undefined):av.$array[av.$offset+aw]);((ax<0||ax>=au.$length)?($throwRuntimeError(\"index out of range\"),undefined):au.$array[au.$offset+ax]=K(ay));aw++;}az=$makeSlice(IH,ao.$length);ba=ao;bb=0;while(true){if(!(bb<ba.$length)){break;}bc=bb;bd=((bb<0||bb>=ba.$length)?($throwRuntimeError(\"index out of range\"),undefined):ba.$array[ba.$offset+bb]);((bc<0||bc>=az.$length)?($throwRuntimeError(\"index out of range\"),undefined):az.$array[az.$offset+bc]=K(bd));bb++;}$s=-1;return L($funcType($externalize(au,IH),$externalize(az,IH),$externalize(ap,$Bool)));}return;}if($f===undefined){$f={$blk:AH};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.$s=$s;$f.$r=$r;return $f;};$pkg.FuncOf=AH;CE.ptr.prototype.ptrTo=function(){var an;an=this;return L($ptrType(K(an)));};CE.prototype.ptrTo=function(){return this.$val.ptrTo();};AJ=function(an){var an;return L($sliceType(K(an)));};$pkg.SliceOf=AJ;AK=function(an){var an,ao,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=AB(an,K(an).zero(),0);$s=1;case 1:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}$s=-1;return ao;}return;}if($f===undefined){$f={$blk:AK};}$f.an=an;$f.ao=ao;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Zero=AK;AL=function(an){var an,ao;ao=an.Kind();if(ao===(25)){return(new(K(an).ptr)());}else if(ao===(17)){return(K(an).zero());}else{return($newDataPointer(K(an).zero(),K(an.ptrTo())));}};AM=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=ap.common();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;as=AL(ar);at=ar.Kind();if(at===(3)){(as).$set(((ao.$low<<24>>24)));}else if(at===(4)){(as).$set(((ao.$low<<16>>16)));}else if((at===(2))||(at===(5))){(as).$set(((ao.$low>>0)));}else if(at===(6)){(as).$set((new $Int64(ao.$high,ao.$low)));}else if(at===(8)){(as).$set(((ao.$low<<24>>>24)));}else if(at===(9)){(as).$set(((ao.$low<<16>>>16)));}else if((at===(7))||(at===(10))||(at===(12))){(as).$set(((ao.$low>>>0)));}else if(at===(11)){(as).$set((ao));}$s=-1;return new EY.ptr(ar,as,(((an|128)>>>0)|((ar.Kind()>>>0)))>>>0);}return;}if($f===undefined){$f={$blk:AM};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};AO=function(an,ao,ap){var an,ao,ap;ao.$set(ap.$get());};AS=function(an,ao){var an,ao,ap,aq;ap=ao;if(!(ap.$get===undefined)){ap=ap.$get();}aq=$internalize(K(an.Key()).keyFor(ap),$String);return[ap,aq];};AT=function(an,ao,ap){var an,ao,ap,aq,ar,as;aq=AS(an,ap);ar=aq[1];as=ao[$externalize(ar,$String)];if(as===undefined){return 0;}return($newDataPointer(as.v,K(DK(an.Elem()))));};AU=function(an,ao,ap,aq){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ar=AS(an,ap);as=ar[0];at=ar[1];au=aq.$get();av=an.Elem();aw=av.Kind();$s=3;case 3:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}if(aw===25){$s=1;continue;}$s=2;continue;case 1:ax=K(av).zero();AA(ax,au,av);au=ax;case 2:ay=new($global.Object)();ay.k=as;ay.v=au;ao[$externalize(at,$String)]=ay;$s=-1;return;}return;}if($f===undefined){$f={$blk:AU};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.$s=$s;$f.$r=$r;return $f;};AV=function(an,ao,ap){var an,ao,ap,aq,ar;aq=AS(an,ap);ar=aq[1];delete ao[$externalize(ar,$String)];};AW.ptr.prototype.skipUntilValidKey=function(){var an,ao;an=this;while(true){if(!(an.i<$parseInt(an.keys.length))){break;}ao=an.keys[an.i];if(!(an.m[$externalize($internalize(ao,$String),$String)]===undefined)){break;}an.i=an.i+(1)>>0;}};AW.prototype.skipUntilValidKey=function(){return this.$val.skipUntilValidKey();};AX=function(an,ao){var an,ao;return(new AW.ptr(an,ao,$keys(ao),0,null));};AY=function(an){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=($pointerOfStructConversion(an,IJ));ap=null;if(!(ao.last===null)){ap=ao.last;}else{ao.skipUntilValidKey();if(ao.i===$parseInt(ao.keys.length)){$s=-1;return 0;}aq=ao.keys[ao.i];ap=ao.m[$externalize($internalize(aq,$String),$String)];ao.last=ap;}ar=ao.t.Key();$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=DK(ar);$s=2;case 2:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}at=K(as);$s=3;case 3:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return($newDataPointer(ap.k,at));}return;}if($f===undefined){$f={$blk:AY};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};AZ=function(an){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=($pointerOfStructConversion(an,IJ));ap=null;if(!(ao.last===null)){ap=ao.last;}else{ao.skipUntilValidKey();if(ao.i===$parseInt(ao.keys.length)){$s=-1;return 0;}aq=ao.keys[ao.i];ap=ao.m[$externalize($internalize(aq,$String),$String)];ao.last=ap;}ar=ao.t.Elem();$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=DK(ar);$s=2;case 2:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}at=K(as);$s=3;case 3:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return($newDataPointer(ap.v,at));}return;}if($f===undefined){$f={$blk:AZ};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};BA=function(an){var an,ao;ao=($pointerOfStructConversion(an,IJ));ao.last=null;ao.i=ao.i+(1)>>0;};BB=function(an){var an;return $parseInt($keys(an).length);};BC=function(an,ao){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=$clone(an,EY).object();if(ap===K(an.typ).nil){$s=1;continue;}$s=2;continue;case 1:aq=AB(ao,K(ao).nil,an.flag);$s=3;case 3:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq;case 2:ar=null;as=ao.Kind();$s=5;case 5:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}at=as;au=at;if(au===(23)){$s=6;continue;}if(au===(22)){$s=7;continue;}if(au===(25)){$s=8;continue;}if((au===(17))||(au===(1))||(au===(18))||(au===(19))||(au===(20))||(au===(21))||(au===(24))){$s=9;continue;}$s=10;continue;case 6:av=new(K(ao))(ap.$array);av.$offset=ap.$offset;av.$length=ap.$length;av.$capacity=ap.$capacity;ar=$newDataPointer(av,K(DK(ao)));$s=11;continue;case 7:aw=ao.Elem();$s=14;case 14:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}ax=aw.Kind();$s=15;case 15:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}if(ax===25){$s=12;continue;}$s=13;continue;case 12:ay=ao.Elem();$s=18;case 18:if($c){$c=false;ay=ay.$blk();}if(ay&&ay.$blk!==undefined){break s;}if($interfaceIsEqual(ay,an.typ.Elem())){$s=16;continue;}$s=17;continue;case 16:ar=ap;$s=4;continue;case 17:ar=new(K(ao))();az=ar;ba=ap;bb=ao.Elem();$s=19;case 19:if($c){$c=false;bb=bb.$blk();}if(bb&&bb.$blk!==undefined){break s;}bc=bb;$r=AA(az,ba,bc);$s=20;case 20:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=4;continue;case 13:ar=new(K(ao))(ap.$get,ap.$set);$s=11;continue;case 8:ar=new(K(ao).ptr)();AA(ar,ap,ao);$s=11;continue;case 9:ar=an.ptr;$s=11;continue;case 10:$panic(new FC.ptr(\"reflect.Convert\",at));case 11:case 4:bd=ao.common();$s=21;case 21:if($c){$c=false;bd=bd.$blk();}if(bd&&bd.$blk!==undefined){break s;}be=ao.Kind();$s=22;case 22:if($c){$c=false;be=be.$blk();}if(be&&be.$blk!==undefined){break s;}$s=-1;return new EY.ptr(bd,(ar),(((new EZ(an.flag).ro()|((an.flag&128)>>>0))>>>0)|((be>>>0)))>>>0);}return;}if($f===undefined){$f={$blk:BC};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.$s=$s;$f.$r=$r;return $f;};BE=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az;aq=HR.nil;ar=IK.nil;as=0;at=\"\";if(ao.typ.Kind()===20){au=(ao.typ.kindType);if(ap<0||ap>=au.methods.$length){$panic(new $String(\"reflect: internal error: invalid method index\"));}aw=(av=au.methods,((ap<0||ap>=av.$length)?($throwRuntimeError(\"index out of range\"),undefined):av.$array[av.$offset+ap]));if(!$clone(au.rtype.nameOff(aw.name),Q).isExported()){$panic(new $String(\"reflect: \"+an+\" of unexported method\"));}ar=(au.rtype.typeOff(aw.typ).kindType);at=$clone(au.rtype.nameOff(aw.name),Q).name();}else{ax=ao.typ.exportedMethods();if(((ap>>>0))>=((ax.$length>>>0))){$panic(new $String(\"reflect: internal error: invalid method index\"));}ay=$clone(((ap<0||ap>=ax.$length)?($throwRuntimeError(\"index out of range\"),undefined):ax.$array[ax.$offset+ap]),CG);if(!$clone(ao.typ.nameOff(ay.name),Q).isExported()){$panic(new $String(\"reflect: \"+an+\" of unexported method\"));}ar=(ao.typ.typeOff(ay.mtyp).kindType);at=$internalize($methodSet(K(ao.typ))[ap].prop,$String);}az=$clone(ao,EY).object();if(Z(ao.typ)){az=new(K(ao.typ))(az);}as=(az[$externalize(at,$String)]);return[aq,ar,as];};BF=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(an.flag===0){$panic(new FC.ptr(\"reflect.Value.Interface\",0));}if(ao&&!((((an.flag&96)>>>0)===0))){$panic(new $String(\"reflect.Value.Interface: cannot return value obtained from unexported field or method\"));}if(!((((an.flag&512)>>>0)===0))){$s=1;continue;}$s=2;continue;case 1:ap=BI(\"Interface\",$clone(an,EY));$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}an=ap;case 2:if(Z(an.typ)){$s=-1;return((new(K(an.typ))($clone(an,EY).object())));}$s=-1;return(($clone(an,EY).object()));}return;}if($f===undefined){$f={$blk:BF};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};BG=function(an,ao,ap){var an,ao,ap;ap.$set(ao);};BH=function(){return\"?FIXME?\";};BI=function(an,ao){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=[ap];aq=[aq];if(((ao.flag&512)>>>0)===0){$panic(new $String(\"reflect: internal error: invalid use of makePartialFunc\"));}ar=BE(an,$clone(ao,EY),((ao.flag>>0))>>10>>0);ap[0]=ar[2];aq[0]=$clone(ao,EY).object();if(Z(ao.typ)){aq[0]=new(K(ao.typ))(aq[0]);}as=C.MakeFunc((function(ap,aq){return function(as,at){var as,at;return new $jsObjectPtr(ap[0].apply(aq[0],$externalize(at,IH)));};})(ap,aq));at=$clone(ao,EY).Type().common();$s=1;case 1:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return new EY.ptr(at,(as),(new EZ(ao.flag).ro()|19)>>>0);}return;}if($f===undefined){$f={$blk:BI};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};CE.ptr.prototype.pointers=function(){var an,ao;an=this;ao=an.Kind();if((ao===(22))||(ao===(21))||(ao===(18))||(ao===(19))||(ao===(25))||(ao===(17))){return true;}else{return false;}};CE.prototype.pointers=function(){return this.$val.pointers();};CE.ptr.prototype.Comparable=function(){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;ao=an.Kind();if((ao===(19))||(ao===(23))||(ao===(21))){$s=2;continue;}if(ao===(17)){$s=3;continue;}if(ao===(25)){$s=4;continue;}$s=5;continue;case 2:$s=-1;return false;case 3:ap=an.Elem().Comparable();$s=6;case 6:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;case 4:aq=0;case 7:if(!(aq<an.NumField())){$s=8;continue;}ar=an.Field(aq).Type.Comparable();$s=11;case 11:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}if(!ar){$s=9;continue;}$s=10;continue;case 9:$s=-1;return false;case 10:aq=aq+(1)>>0;$s=7;continue;case 8:case 5:case 1:$s=-1;return true;}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.Comparable};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.Comparable=function(){return this.$val.Comparable();};CE.ptr.prototype.Method=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=[ao];ap=new CS.ptr(\"\",\"\",$ifaceNil,new EY.ptr(HR.nil,0,0),0);aq=this;if(aq.Kind()===20){ar=(aq.kindType);CS.copy(ap,ar.Method(an));$s=-1;return ap;}as=aq.exportedMethods();if(an<0||an>=as.$length){$panic(new $String(\"reflect: Method index out of range\"));}at=$clone(((an<0||an>=as.$length)?($throwRuntimeError(\"index out of range\"),undefined):as.$array[as.$offset+an]),CG);au=$clone(aq.nameOff(at.name),Q);ap.Name=$clone(au,Q).name();av=19;aw=aq.typeOff(at.mtyp);ax=(aw.kindType);ay=$makeSlice(IL,0,(1+ax.in$().$length>>0));ay=$append(ay,aq);az=ax.in$();ba=0;while(true){if(!(ba<az.$length)){break;}bb=((ba<0||ba>=az.$length)?($throwRuntimeError(\"index out of range\"),undefined):az.$array[az.$offset+ba]);ay=$append(ay,bb);ba++;}bc=$makeSlice(IL,0,ax.out().$length);bd=ax.out();be=0;while(true){if(!(be<bd.$length)){break;}bf=((be<0||be>=bd.$length)?($throwRuntimeError(\"index out of range\"),undefined):bd.$array[bd.$offset+be]);bc=$append(bc,bf);be++;}bg=AH(ay,bc,ax.rtype.IsVariadic());$s=1;case 1:if($c){$c=false;bg=bg.$blk();}if(bg&&bg.$blk!==undefined){break s;}bh=bg;ap.Type=bh;ao[0]=$internalize($methodSet(aq.jsType)[an].prop,$String);bi=C.MakeFunc((function(ao){return function(bi,bj){var bi,bj,bk;bk=(0>=bj.$length?($throwRuntimeError(\"index out of range\"),undefined):bj.$array[bj.$offset+0]);return new $jsObjectPtr(bk[$externalize(ao[0],$String)].apply(bk,$externalize($subslice(bj,1),IH)));};})(ao));ap.Func=new EY.ptr($assertType(bh,HR),(bi),av);ap.Index=an;CS.copy(ap,ap);$s=-1;return ap;}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.Method};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.Method=function(an){return this.$val.Method(an);};EY.ptr.prototype.object=function(){var an,ao,ap,aq;an=this;if((an.typ.Kind()===17)||(an.typ.Kind()===25)){return an.ptr;}if(!((((an.flag&128)>>>0)===0))){ao=an.ptr.$get();if(!(ao===$ifaceNil)&&!(ao.constructor===K(an.typ))){switch(0){default:ap=an.typ.Kind();if((ap===(11))||(ap===(6))){ao=new(K(an.typ))(ao.$high,ao.$low);}else if((ap===(15))||(ap===(16))){ao=new(K(an.typ))(ao.$real,ao.$imag);}else if(ap===(23)){if(ao===ao.constructor.nil){ao=K(an.typ).nil;break;}aq=new(K(an.typ))(ao.$array);aq.$offset=ao.$offset;aq.$length=ao.$length;aq.$capacity=ao.$capacity;ao=aq;}}}return ao;}return an.ptr;};EY.prototype.object=function(){return this.$val.object();};EY.ptr.prototype.assignTo=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=this;if(!((((aq.flag&512)>>>0)===0))){$s=1;continue;}$s=2;continue;case 1:ar=BI(an,$clone(aq,EY));$s=3;case 3:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}aq=ar;case 2:as=DN(ao,aq.typ);$s=8;case 8:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}if(as){$s=5;continue;}if(DM(ao,aq.typ)){$s=6;continue;}$s=7;continue;case 5:at=(((aq.flag&384)>>>0)|new EZ(aq.flag).ro())>>>0;at=(at|(((ao.Kind()>>>0))))>>>0;$s=-1;return new EY.ptr(ao,aq.ptr,at);case 6:if(ap===0){ap=AL(ao);}au=BF($clone(aq,EY),false);$s=9;case 9:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}av=au;if(ao.NumMethod()===0){(ap).$set(av);}else{BG(ao,av,ap);}$s=-1;return new EY.ptr(ao,ap,148);case 7:case 4:$panic(new $String(an+\": value of type \"+aq.typ.String()+\" is not assignable to type \"+ao.String()));$s=-1;return new EY.ptr(HR.nil,0,0);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.assignTo};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.assignTo=function(an,ao,ap){return this.$val.assignTo(an,ao,ap);};EY.ptr.prototype.call=function(an,ao){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;bu=$f.bu;bv=$f.bv;bw=$f.bw;bx=$f.bx;by=$f.by;bz=$f.bz;ca=$f.ca;cb=$f.cb;cc=$f.cc;cd=$f.cd;ce=$f.ce;cf=$f.cf;cg=$f.cg;ch=$f.ch;ci=$f.ci;cj=$f.cj;ck=$f.ck;cl=$f.cl;cm=$f.cm;cn=$f.cn;co=$f.co;cp=$f.cp;cq=$f.cq;cr=$f.cr;cs=$f.cs;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=this;aq=IK.nil;ar=0;as=null;if(!((((ap.flag&512)>>>0)===0))){at=BE(an,$clone(ap,EY),((ap.flag>>0))>>10>>0);aq=at[1];ar=at[2];as=$clone(ap,EY).object();if(Z(ap.typ)){as=new(K(ap.typ))(as);}}else{aq=(ap.typ.kindType);ar=($clone(ap,EY).object());as=undefined;}if(ar===0){$panic(new $String(\"reflect.Value.Call: call of nil function\"));}au=an===\"CallSlice\";av=aq.rtype.NumIn();if(au){if(!aq.rtype.IsVariadic()){$panic(new $String(\"reflect: CallSlice of non-variadic function\"));}if(ao.$length<av){$panic(new $String(\"reflect: CallSlice with too few input arguments\"));}if(ao.$length>av){$panic(new $String(\"reflect: CallSlice with too many input arguments\"));}}else{if(aq.rtype.IsVariadic()){av=av-(1)>>0;}if(ao.$length<av){$panic(new $String(\"reflect: Call with too few input arguments\"));}if(!aq.rtype.IsVariadic()&&ao.$length>av){$panic(new $String(\"reflect: Call with too many input arguments\"));}}aw=ao;ax=0;while(true){if(!(ax<aw.$length)){break;}ay=((ax<0||ax>=aw.$length)?($throwRuntimeError(\"index out of range\"),undefined):aw.$array[aw.$offset+ax]);if($clone(ay,EY).Kind()===0){$panic(new $String(\"reflect: \"+an+\" using zero Value argument\"));}ax++;}az=0;case 1:if(!(az<av)){$s=2;continue;}ba=$clone(((az<0||az>=ao.$length)?($throwRuntimeError(\"index out of range\"),undefined):ao.$array[ao.$offset+az]),EY).Type();bb=aq.rtype.In(az);bc=ba;bd=bb;be=bc.AssignableTo(bd);$s=5;case 5:if($c){$c=false;be=be.$blk();}if(be&&be.$blk!==undefined){break s;}if(!be){$s=3;continue;}$s=4;continue;case 3:bf=bc.String();$s=6;case 6:if($c){$c=false;bf=bf.$blk();}if(bf&&bf.$blk!==undefined){break s;}bg=bd.String();$s=7;case 7:if($c){$c=false;bg=bg.$blk();}if(bg&&bg.$blk!==undefined){break s;}$panic(new $String(\"reflect: \"+an+\" using \"+bf+\" as type \"+bg));case 4:az=az+(1)>>0;$s=1;continue;case 2:if(!au&&aq.rtype.IsVariadic()){$s=8;continue;}$s=9;continue;case 8:bh=ao.$length-av>>0;bi=AC(aq.rtype.In(av),bh,bh);$s=10;case 10:if($c){$c=false;bi=bi.$blk();}if(bi&&bi.$blk!==undefined){break s;}bj=bi;bk=aq.rtype.In(av).Elem();$s=11;case 11:if($c){$c=false;bk=bk.$blk();}if(bk&&bk.$blk!==undefined){break s;}bl=bk;bm=0;case 12:if(!(bm<bh)){$s=13;continue;}bo=(bn=av+bm>>0,((bn<0||bn>=ao.$length)?($throwRuntimeError(\"index out of range\"),undefined):ao.$array[ao.$offset+bn]));bp=$clone(bo,EY).Type();bq=bp.AssignableTo(bl);$s=16;case 16:if($c){$c=false;bq=bq.$blk();}if(bq&&bq.$blk!==undefined){break s;}if(!bq){$s=14;continue;}$s=15;continue;case 14:br=bp.String();$s=17;case 17:if($c){$c=false;br=br.$blk();}if(br&&br.$blk!==undefined){break s;}bs=bl.String();$s=18;case 18:if($c){$c=false;bs=bs.$blk();}if(bs&&bs.$blk!==undefined){break s;}$panic(new $String(\"reflect: cannot use \"+br+\" as type \"+bs+\" in \"+an));case 15:bt=$clone(bj,EY).Index(bm);$s=19;case 19:if($c){$c=false;bt=bt.$blk();}if(bt&&bt.$blk!==undefined){break s;}$r=$clone(bt,EY).Set($clone(bo,EY));$s=20;case 20:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}bm=bm+(1)>>0;$s=12;continue;case 13:bu=ao;ao=$makeSlice(II,(av+1>>0));$copySlice($subslice(ao,0,av),bu);((av<0||av>=ao.$length)?($throwRuntimeError(\"index out of range\"),undefined):ao.$array[ao.$offset+av]=bj);case 9:bv=ao.$length;if(!((bv===aq.rtype.NumIn()))){$panic(new $String(\"reflect.Value.Call: wrong argument count\"));}bw=aq.rtype.NumOut();bx=new($global.Array)(aq.rtype.NumIn());by=ao;bz=0;case 21:if(!(bz<by.$length)){$s=22;continue;}ca=bz;cb=((bz<0||bz>=by.$length)?($throwRuntimeError(\"index out of range\"),undefined):by.$array[by.$offset+bz]);cc=aq.rtype.In(ca);cd=aq.rtype.In(ca).common();$s=23;case 23:if($c){$c=false;cd=cd.$blk();}if(cd&&cd.$blk!==undefined){break s;}ce=cd;cf=0;cg=$clone(cb,EY).assignTo(\"reflect.Value.Call\",ce,cf);$s=24;case 24:if($c){$c=false;cg=cg.$blk();}if(cg&&cg.$blk!==undefined){break s;}ch=$clone(cg,EY).object();$s=25;case 25:if($c){$c=false;ch=ch.$blk();}if(ch&&ch.$blk!==undefined){break s;}ci=ch;cj=BM(cc,ci);$s=26;case 26:if($c){$c=false;cj=cj.$blk();}if(cj&&cj.$blk!==undefined){break s;}bx[ca]=cj;bz++;$s=21;continue;case 22:ck=BJ(new HV([new $jsObjectPtr(ar),new $jsObjectPtr(as),new $jsObjectPtr(bx)]));$s=27;case 27:if($c){$c=false;ck=ck.$blk();}if(ck&&ck.$blk!==undefined){break s;}cl=ck;cm=bw;if(cm===(0)){$s=29;continue;}if(cm===(1)){$s=30;continue;}$s=31;continue;case 29:$s=-1;return II.nil;case 30:cn=AB(aq.rtype.Out(0),BL(aq.rtype.Out(0),cl),0);$s=33;case 33:if($c){$c=false;cn=cn.$blk();}if(cn&&cn.$blk!==undefined){break s;}$s=-1;return new II([$clone(cn,EY)]);case 31:co=$makeSlice(II,bw);cp=co;cq=0;case 34:if(!(cq<cp.$length)){$s=35;continue;}cr=cq;cs=AB(aq.rtype.Out(cr),BL(aq.rtype.Out(cr),cl[cr]),0);$s=36;case 36:if($c){$c=false;cs=cs.$blk();}if(cs&&cs.$blk!==undefined){break s;}((cr<0||cr>=co.$length)?($throwRuntimeError(\"index out of range\"),undefined):co.$array[co.$offset+cr]=cs);cq++;$s=34;continue;case 35:$s=-1;return co;case 32:case 28:$s=-1;return II.nil;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.call};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.bu=bu;$f.bv=bv;$f.bw=bw;$f.bx=bx;$f.by=by;$f.bz=bz;$f.ca=ca;$f.cb=cb;$f.cc=cc;$f.cd=cd;$f.ce=ce;$f.cf=cf;$f.cg=cg;$f.ch=ch;$f.ci=ci;$f.cj=cj;$f.ck=ck;$f.cl=cl;$f.cm=cm;$f.cn=cn;$f.co=co;$f.cp=cp;$f.cq=cq;$f.cr=cr;$f.cs=cs;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.call=function(an,ao){return this.$val.call(an,ao);};EY.ptr.prototype.Cap=function(){var an,ao,ap;an=this;ao=new EZ(an.flag).kind();ap=ao;if(ap===(17)){return an.typ.Len();}else if((ap===(18))||(ap===(23))){return $parseInt($clone(an,EY).object().$capacity)>>0;}$panic(new FC.ptr(\"reflect.Value.Cap\",ao));};EY.prototype.Cap=function(){return this.$val.Cap();};BL=function(an,ao){var an,ao;if($interfaceIsEqual(an,BK)){return new(K(BK))(ao);}return ao;};BM=function(an,ao){var an,ao;if($interfaceIsEqual(an,BK)){return ao.object;}return ao;};EY.ptr.prototype.Elem=function(){var an,ao,ap,aq,ar,as,at,au,av,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;ao=new EZ(an.flag).kind();ap=ao;if(ap===(20)){$s=2;continue;}if(ap===(22)){$s=3;continue;}$s=4;continue;case 2:aq=$clone(an,EY).object();if(aq===$ifaceNil){$s=-1;return new EY.ptr(HR.nil,0,0);}ar=L(aq.constructor);as=AB(ar,aq.$val,new EZ(an.flag).ro());$s=6;case 6:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}$s=-1;return as;case 3:if($clone(an,EY).IsNil()){$s=-1;return new EY.ptr(HR.nil,0,0);}at=$clone(an,EY).object();au=(an.typ.kindType);av=(((((an.flag&96)>>>0)|128)>>>0)|256)>>>0;av=(av|(((au.elem.Kind()>>>0))))>>>0;$s=-1;return new EY.ptr(au.elem,(BL(au.elem,at)),av);case 4:$panic(new FC.ptr(\"reflect.Value.Elem\",ao));case 5:case 1:$s=-1;return new EY.ptr(HR.nil,0,0);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Elem};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Elem=function(){return this.$val.Elem();};EY.ptr.prototype.Field=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=[ao];ap=[ap];aq=[aq];ar=[ar];as=this;if(!((new EZ(as.flag).kind()===25))){$panic(new FC.ptr(\"reflect.Value.Field\",new EZ(as.flag).kind()));}at=(as.typ.kindType);if(((an>>>0))>=((at.fields.$length>>>0))){$panic(new $String(\"reflect: Field index out of range\"));}ap[0]=$internalize(K(as.typ).fields[an].prop,$String);av=(au=at.fields,((an<0||an>=au.$length)?($throwRuntimeError(\"index out of range\"),undefined):au.$array[au.$offset+an]));ar[0]=av.typ;aw=(((as.flag&416)>>>0)|((ar[0].Kind()>>>0)))>>>0;if(!$clone(av.name,Q).isExported()){if(av.embedded()){aw=(aw|(64))>>>0;}else{aw=(aw|(32))>>>0;}}ay=$clone((ax=at.fields,((an<0||an>=ax.$length)?($throwRuntimeError(\"index out of range\"),undefined):ax.$array[ax.$offset+an])).name,Q).tag();if(!(ay===\"\")&&!((an===0))){$s=1;continue;}$s=2;continue;case 1:ao[0]=BN(ay);if(!(ao[0]===\"\")){$s=3;continue;}$s=4;continue;case 3:case 5:az=[az];ba=$clone(as,EY).Field(0);$s=7;case 7:if($c){$c=false;ba=ba.$blk();}if(ba&&ba.$blk!==undefined){break s;}as=ba;if(as.typ===BK){$s=8;continue;}$s=9;continue;case 8:az[0]=$clone(as,EY).object().object;$s=-1;return new EY.ptr(ar[0],(new(K(DK(ar[0])))((function(ao,ap,aq,ar,az){return function(){return $internalize(az[0][$externalize(ao[0],$String)],K(ar[0]));};})(ao,ap,aq,ar,az),(function(ao,ap,aq,ar,az){return function(bb){var bb;az[0][$externalize(ao[0],$String)]=$externalize(bb,K(ar[0]));};})(ao,ap,aq,ar,az))),aw);case 9:if(as.typ.Kind()===22){$s=10;continue;}$s=11;continue;case 10:bb=$clone(as,EY).Elem();$s=12;case 12:if($c){$c=false;bb=bb.$blk();}if(bb&&bb.$blk!==undefined){break s;}as=bb;case 11:$s=5;continue;case 6:case 4:case 2:aq[0]=as.ptr;if(!((((aw&128)>>>0)===0))&&!((ar[0].Kind()===17))&&!((ar[0].Kind()===25))){$s=13;continue;}$s=14;continue;case 13:$s=-1;return new EY.ptr(ar[0],(new(K(DK(ar[0])))((function(ao,ap,aq,ar){return function(){return BL(ar[0],aq[0][$externalize(ap[0],$String)]);};})(ao,ap,aq,ar),(function(ao,ap,aq,ar){return function(bc){var bc;aq[0][$externalize(ap[0],$String)]=BM(ar[0],bc);};})(ao,ap,aq,ar))),aw);case 14:bc=AB(ar[0],BL(ar[0],aq[0][$externalize(ap[0],$String)]),aw);$s=15;case 15:if($c){$c=false;bc=bc.$blk();}if(bc&&bc.$blk!==undefined){break s;}$s=-1;return bc;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Field};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Field=function(an){return this.$val.Field(an);};BN=function(an){var an,ao,ap,aq,ar,as;while(true){if(!(!(an===\"\"))){break;}ao=0;while(true){if(!(ao<an.length&&(an.charCodeAt(ao)===32))){break;}ao=ao+(1)>>0;}an=$substring(an,ao);if(an===\"\"){break;}ao=0;while(true){if(!(ao<an.length&&!((an.charCodeAt(ao)===32))&&!((an.charCodeAt(ao)===58))&&!((an.charCodeAt(ao)===34)))){break;}ao=ao+(1)>>0;}if((ao+1>>0)>=an.length||!((an.charCodeAt(ao)===58))||!((an.charCodeAt((ao+1>>0))===34))){break;}ap=($substring(an,0,ao));an=$substring(an,(ao+1>>0));ao=1;while(true){if(!(ao<an.length&&!((an.charCodeAt(ao)===34)))){break;}if(an.charCodeAt(ao)===92){ao=ao+(1)>>0;}ao=ao+(1)>>0;}if(ao>=an.length){break;}aq=($substring(an,0,(ao+1>>0)));an=$substring(an,(ao+1>>0));if(ap===\"js\"){ar=B.Unquote(aq);as=ar[0];return as;}}return\"\";};EY.ptr.prototype.Index=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=[an];ao=[ao];ap=[ap];aq=[aq];ar=[ar];as=[as];at=this;au=new EZ(at.flag).kind();av=au;if(av===(17)){$s=2;continue;}if(av===(23)){$s=3;continue;}if(av===(24)){$s=4;continue;}$s=5;continue;case 2:aw=(at.typ.kindType);if(an[0]<0||an[0]>((aw.len>>0))){$panic(new $String(\"reflect: array index out of range\"));}ar[0]=aw.elem;ax=(((((at.flag&384)>>>0)|new EZ(at.flag).ro())>>>0)|((ar[0].Kind()>>>0)))>>>0;ao[0]=at.ptr;if(!((((ax&128)>>>0)===0))&&!((ar[0].Kind()===17))&&!((ar[0].Kind()===25))){$s=7;continue;}$s=8;continue;case 7:$s=-1;return new EY.ptr(ar[0],(new(K(DK(ar[0])))((function(an,ao,ap,aq,ar,as){return function(){return BL(ar[0],ao[0][an[0]]);};})(an,ao,ap,aq,ar,as),(function(an,ao,ap,aq,ar,as){return function(ay){var ay;ao[0][an[0]]=BM(ar[0],ay);};})(an,ao,ap,aq,ar,as))),ax);case 8:ay=AB(ar[0],BL(ar[0],ao[0][an[0]]),ax);$s=9;case 9:if($c){$c=false;ay=ay.$blk();}if(ay&&ay.$blk!==undefined){break s;}$s=-1;return ay;case 3:az=$clone(at,EY).object();if(an[0]<0||an[0]>=($parseInt(az.$length)>>0)){$panic(new $String(\"reflect: slice index out of range\"));}ba=(at.typ.kindType);as[0]=ba.elem;bb=(((384|new EZ(at.flag).ro())>>>0)|((as[0].Kind()>>>0)))>>>0;an[0]=an[0]+(($parseInt(az.$offset)>>0))>>0;ap[0]=az.$array;if(!((((bb&128)>>>0)===0))&&!((as[0].Kind()===17))&&!((as[0].Kind()===25))){$s=10;continue;}$s=11;continue;case 10:$s=-1;return new EY.ptr(as[0],(new(K(DK(as[0])))((function(an,ao,ap,aq,ar,as){return function(){return BL(as[0],ap[0][an[0]]);};})(an,ao,ap,aq,ar,as),(function(an,ao,ap,aq,ar,as){return function(bc){var bc;ap[0][an[0]]=BM(as[0],bc);};})(an,ao,ap,aq,ar,as))),bb);case 11:bc=AB(as[0],BL(as[0],ap[0][an[0]]),bb);$s=12;case 12:if($c){$c=false;bc=bc.$blk();}if(bc&&bc.$blk!==undefined){break s;}$s=-1;return bc;case 4:bd=(at.ptr).$get();if(an[0]<0||an[0]>=bd.length){$panic(new $String(\"reflect: string index out of range\"));}be=(((new EZ(at.flag).ro()|8)>>>0)|128)>>>0;aq[0]=bd.charCodeAt(an[0]);$s=-1;return new EY.ptr(FL,((aq.$ptr||(aq.$ptr=new IA(function(){return this.$target[0];},function($v){this.$target[0]=$v;},aq)))),be);case 5:$panic(new FC.ptr(\"reflect.Value.Index\",au));case 6:case 1:$s=-1;return new EY.ptr(HR.nil,0,0);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Index};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Index=function(an){return this.$val.Index(an);};EY.ptr.prototype.InterfaceData=function(){var an;an=this;$panic(A.New(\"InterfaceData is not supported by GopherJS\"));};EY.prototype.InterfaceData=function(){return this.$val.InterfaceData();};EY.ptr.prototype.IsNil=function(){var an,ao,ap;an=this;ao=new EZ(an.flag).kind();ap=ao;if((ap===(22))||(ap===(23))){return $clone(an,EY).object()===K(an.typ).nil;}else if(ap===(18)){return $clone(an,EY).object()===$chanNil;}else if(ap===(19)){return $clone(an,EY).object()===$throwNilPointerError;}else if(ap===(21)){return $clone(an,EY).object()===false;}else if(ap===(20)){return $clone(an,EY).object()===$ifaceNil;}else if(ap===(26)){return $clone(an,EY).object()===0;}else{$panic(new FC.ptr(\"reflect.Value.IsNil\",ao));}};EY.prototype.IsNil=function(){return this.$val.IsNil();};EY.ptr.prototype.Len=function(){var an,ao,ap;an=this;ao=new EZ(an.flag).kind();ap=ao;if((ap===(17))||(ap===(24))){return $parseInt($clone(an,EY).object().length);}else if(ap===(23)){return $parseInt($clone(an,EY).object().$length)>>0;}else if(ap===(18)){return $parseInt($clone(an,EY).object().$buffer.length)>>0;}else if(ap===(21)){return $parseInt($keys($clone(an,EY).object()).length);}else{$panic(new FC.ptr(\"reflect.Value.Len\",ao));}};EY.prototype.Len=function(){return this.$val.Len();};EY.ptr.prototype.Pointer=function(){var an,ao,ap;an=this;ao=new EZ(an.flag).kind();ap=ao;if((ap===(18))||(ap===(21))||(ap===(22))||(ap===(26))){if($clone(an,EY).IsNil()){return 0;}return $clone(an,EY).object();}else if(ap===(19)){if($clone(an,EY).IsNil()){return 0;}return 1;}else if(ap===(23)){if($clone(an,EY).IsNil()){return 0;}return $clone(an,EY).object().$array;}else{$panic(new FC.ptr(\"reflect.Value.Pointer\",ao));}};EY.prototype.Pointer=function(){return this.$val.Pointer();};EY.ptr.prototype.Set=function(an){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(an.flag).mustBeExported();ap=$clone(an,EY).assignTo(\"reflect.Set\",ao.typ,0);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}an=ap;if(!((((ao.flag&128)>>>0)===0))){$s=2;continue;}$s=3;continue;case 2:aq=ao.typ.Kind();if(aq===(17)){$s=5;continue;}if(aq===(20)){$s=6;continue;}if(aq===(25)){$s=7;continue;}$s=8;continue;case 5:K(ao.typ).copy(ao.ptr,an.ptr);$s=9;continue;case 6:ar=BF($clone(an,EY),false);$s=10;case 10:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}ao.ptr.$set(ar);$s=9;continue;case 7:AA(ao.ptr,an.ptr,ao.typ);$s=9;continue;case 8:ao.ptr.$set($clone(an,EY).object());case 9:case 4:$s=-1;return;case 3:ao.ptr=an.ptr;$s=-1;return;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Set};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Set=function(an){return this.$val.Set(an);};EY.ptr.prototype.SetBytes=function(an){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(23);ap=ao.typ.Elem().Kind();$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}if(!((ap===8))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect.Value.SetBytes of non-byte slice\"));case 2:aq=an;if(!(ao.typ.Name()===\"\")){ar=true;$s=6;continue s;}as=ao.typ.Elem().Name();$s=7;case 7:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}ar=!(as===\"\");case 6:if(ar){$s=4;continue;}$s=5;continue;case 4:at=new(K(ao.typ))(aq.$array);at.$offset=aq.$offset;at.$length=aq.$length;at.$capacity=aq.$capacity;aq=at;case 5:ao.ptr.$set(aq);$s=-1;return;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.SetBytes};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.SetBytes=function(an){return this.$val.SetBytes(an);};EY.ptr.prototype.SetCap=function(an){var an,ao,ap,aq;ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(23);ap=ao.ptr.$get();if(an<($parseInt(ap.$length)>>0)||an>($parseInt(ap.$capacity)>>0)){$panic(new $String(\"reflect: slice capacity out of range in SetCap\"));}aq=new(K(ao.typ))(ap.$array);aq.$offset=ap.$offset;aq.$length=ap.$length;aq.$capacity=an;ao.ptr.$set(aq);};EY.prototype.SetCap=function(an){return this.$val.SetCap(an);};EY.ptr.prototype.SetLen=function(an){var an,ao,ap,aq;ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(23);ap=ao.ptr.$get();if(an<0||an>($parseInt(ap.$capacity)>>0)){$panic(new $String(\"reflect: slice length out of range in SetLen\"));}aq=new(K(ao.typ))(ap.$array);aq.$offset=ap.$offset;aq.$length=an;aq.$capacity=ap.$capacity;ao.ptr.$set(aq);};EY.prototype.SetLen=function(an){return this.$val.SetLen(an);};EY.ptr.prototype.Slice=function(an,ao){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=this;aq=0;ar=$ifaceNil;as=null;at=new EZ(ap.flag).kind();au=at;if(au===(17)){$s=2;continue;}if(au===(23)){$s=3;continue;}if(au===(24)){$s=4;continue;}$s=5;continue;case 2:if(((ap.flag&256)>>>0)===0){$panic(new $String(\"reflect.Value.Slice: slice of unaddressable array\"));}av=(ap.typ.kindType);aq=((av.len>>0));ar=AJ(av.elem);as=new(K(ar))($clone(ap,EY).object());$s=6;continue;case 3:ar=ap.typ;as=$clone(ap,EY).object();aq=$parseInt(as.$capacity)>>0;$s=6;continue;case 4:aw=(ap.ptr).$get();if(an<0||ao<an||ao>aw.length){$panic(new $String(\"reflect.Value.Slice: string slice index out of bounds\"));}ax=AE(new $String($substring(aw,an,ao)));$s=7;case 7:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}$s=-1;return ax;case 5:$panic(new FC.ptr(\"reflect.Value.Slice\",at));case 6:case 1:if(an<0||ao<an||ao>aq){$panic(new $String(\"reflect.Value.Slice: slice index out of bounds\"));}ay=AB(ar,$subslice(as,an,ao),new EZ(ap.flag).ro());$s=8;case 8:if($c){$c=false;ay=ay.$blk();}if(ay&&ay.$blk!==undefined){break s;}$s=-1;return ay;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Slice};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Slice=function(an,ao){return this.$val.Slice(an,ao);};EY.ptr.prototype.Slice3=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=this;ar=0;as=$ifaceNil;at=null;au=new EZ(aq.flag).kind();av=au;if(av===(17)){if(((aq.flag&256)>>>0)===0){$panic(new $String(\"reflect.Value.Slice: slice of unaddressable array\"));}aw=(aq.typ.kindType);ar=((aw.len>>0));as=AJ(aw.elem);at=new(K(as))($clone(aq,EY).object());}else if(av===(23)){as=aq.typ;at=$clone(aq,EY).object();ar=$parseInt(at.$capacity)>>0;}else{$panic(new FC.ptr(\"reflect.Value.Slice3\",au));}if(an<0||ao<an||ap<ao||ap>ar){$panic(new $String(\"reflect.Value.Slice3: slice index out of bounds\"));}ax=AB(as,$subslice(at,an,ao,ap),new EZ(aq.flag).ro());$s=1;case 1:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}$s=-1;return ax;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Slice3};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Slice3=function(an,ao,ap){return this.$val.Slice3(an,ao,ap);};EY.ptr.prototype.Close=function(){var an;an=this;new EZ(an.flag).mustBe(18);new EZ(an.flag).mustBeExported();$close($clone(an,EY).object());};EY.prototype.Close=function(){return this.$val.Close();};BP=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=false;ar=false;as=new IM([new IH([an])]);if(ao){as=$append(as,new IH([]));}at=BO(new HV([as]));$s=1;case 1:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}au=at;if(ao&&(($parseInt(au[0])>>0)===1)){av=false;aw=false;aq=av;ar=aw;$s=-1;return[aq,ar];}ax=au[1];ap.$set(ax[0]);ay=true;az=!!(ax[1]);aq=ay;ar=az;$s=-1;return[aq,ar];}return;}if($f===undefined){$f={$blk:BP};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.$s=$s;$f.$r=$r;return $f;};BQ=function(an,ao,ap){var an,ao,ap,aq,ar,as,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=new IM([new IH([an,ao.$get()])]);if(ap){aq=$append(aq,new IH([]));}ar=BO(new HV([aq]));$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=ar;if(ap&&(($parseInt(as[0])>>0)===1)){$s=-1;return false;}$s=-1;return true;}return;}if($f===undefined){$f={$blk:BQ};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.$s=$s;$f.$r=$r;return $f;};CP.ptr.prototype.offset=function(){var an;an=this;return an.offsetEmbed>>>1>>>0;};CP.prototype.offset=function(){return this.$val.offset();};CP.ptr.prototype.embedded=function(){var an;an=this;return!((((an.offsetEmbed&1)>>>0)===0));};CP.prototype.embedded=function(){return this.$val.embedded();};CC.prototype.String=function(){var an;an=this.$val;if(((an>>0))<CT.$length){return((an<0||an>=CT.$length)?($throwRuntimeError(\"index out of range\"),undefined):CT.$array[CT.$offset+an]);}return\"kind\"+B.Itoa(((an>>0)));};$ptrType(CC).prototype.String=function(){return new CC(this.$get()).String();};CE.ptr.prototype.String=function(){var an,ao;an=this;ao=$clone(an.nameOff(an.str),Q).name();if(!((((an.tflag&2)>>>0)===0))){return $substring(ao,1);}return ao;};CE.prototype.String=function(){return this.$val.String();};CE.ptr.prototype.Size=function(){var an;an=this;return an.size;};CE.prototype.Size=function(){return this.$val.Size();};CE.ptr.prototype.Bits=function(){var an,ao;an=this;if(an===HR.nil){$panic(new $String(\"reflect: Bits of nil Type\"));}ao=an.Kind();if(ao<2||ao>16){$panic(new $String(\"reflect: Bits of non-arithmetic Type \"+an.String()));}return $imul(((an.size>>0)),8);};CE.prototype.Bits=function(){return this.$val.Bits();};CE.ptr.prototype.Align=function(){var an;an=this;return((an.align>>0));};CE.prototype.Align=function(){return this.$val.Align();};CE.ptr.prototype.FieldAlign=function(){var an;an=this;return((an.fieldAlign>>0));};CE.prototype.FieldAlign=function(){return this.$val.FieldAlign();};CE.ptr.prototype.Kind=function(){var an;an=this;return((((an.kind&31)>>>0)>>>0));};CE.prototype.Kind=function(){return this.$val.Kind();};CE.ptr.prototype.common=function(){var an;an=this;return an;};CE.prototype.common=function(){return this.$val.common();};CE.ptr.prototype.exportedMethods=function(){var an,ao;an=this;ao=an.uncommon();if(ao===IE.nil){return IB.nil;}return ao.exportedMethods();};CE.prototype.exportedMethods=function(){return this.$val.exportedMethods();};CE.ptr.prototype.NumMethod=function(){var an,ao;an=this;if(an.Kind()===20){ao=(an.kindType);return ao.NumMethod();}return an.exportedMethods().$length;};CE.prototype.NumMethod=function(){return this.$val.NumMethod();};CE.ptr.prototype.MethodByName=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=new CS.ptr(\"\",\"\",$ifaceNil,new EY.ptr(HR.nil,0,0),0);ap=false;aq=this;if(aq.Kind()===20){ar=(aq.kindType);as=ar.MethodByName(an);CS.copy(ao,as[0]);ap=as[1];$s=-1;return[ao,ap];}at=aq.uncommon();if(at===IE.nil){au=new CS.ptr(\"\",\"\",$ifaceNil,new EY.ptr(HR.nil,0,0),0);av=false;CS.copy(ao,au);ap=av;$s=-1;return[ao,ap];}aw=at.exportedMethods();ax=0;case 1:if(!(ax<aw.$length)){$s=2;continue;}ay=ax;az=$clone(((ax<0||ax>=aw.$length)?($throwRuntimeError(\"index out of range\"),undefined):aw.$array[aw.$offset+ax]),CG);if($clone(aq.nameOff(az.name),Q).name()===an){$s=3;continue;}$s=4;continue;case 3:bb=aq.Method(ay);$s=5;case 5:if($c){$c=false;bb=bb.$blk();}if(bb&&bb.$blk!==undefined){break s;}ba=$clone(bb,CS);bc=true;CS.copy(ao,ba);ap=bc;$s=-1;return[ao,ap];case 4:ax++;$s=1;continue;case 2:bd=new CS.ptr(\"\",\"\",$ifaceNil,new EY.ptr(HR.nil,0,0),0);be=false;CS.copy(ao,bd);ap=be;$s=-1;return[ao,ap];}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.MethodByName};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.MethodByName=function(an){return this.$val.MethodByName(an);};CE.ptr.prototype.PkgPath=function(){var an,ao;an=this;if(((an.tflag&4)>>>0)===0){return\"\";}ao=an.uncommon();if(ao===IE.nil){return\"\";}return $clone(an.nameOff(ao.pkgPath),Q).name();};CE.prototype.PkgPath=function(){return this.$val.PkgPath();};CE.ptr.prototype.Name=function(){var an,ao,ap;an=this;if(((an.tflag&4)>>>0)===0){return\"\";}ao=an.String();ap=ao.length-1>>0;while(true){if(!(ap>=0)){break;}if(ao.charCodeAt(ap)===46){break;}ap=ap-(1)>>0;}return $substring(ao,(ap+1>>0));};CE.prototype.Name=function(){return this.$val.Name();};CE.ptr.prototype.ChanDir=function(){var an,ao;an=this;if(!((an.Kind()===18))){$panic(new $String(\"reflect: ChanDir of non-chan type\"));}ao=(an.kindType);return((ao.dir>>0));};CE.prototype.ChanDir=function(){return this.$val.ChanDir();};CE.ptr.prototype.IsVariadic=function(){var an,ao;an=this;if(!((an.Kind()===19))){$panic(new $String(\"reflect: IsVariadic of non-func type\"));}ao=(an.kindType);return!((((ao.outCount&32768)>>>0)===0));};CE.prototype.IsVariadic=function(){return this.$val.IsVariadic();};CE.ptr.prototype.Elem=function(){var an,ao,ap,aq,ar,as,at;an=this;ao=an.Kind();if(ao===(17)){ap=(an.kindType);return EQ(ap.elem);}else if(ao===(18)){aq=(an.kindType);return EQ(aq.elem);}else if(ao===(21)){ar=(an.kindType);return EQ(ar.elem);}else if(ao===(22)){as=(an.kindType);return EQ(as.elem);}else if(ao===(23)){at=(an.kindType);return EQ(at.elem);}$panic(new $String(\"reflect: Elem of invalid type\"));};CE.prototype.Elem=function(){return this.$val.Elem();};CE.ptr.prototype.Field=function(an){var an,ao,ap;ao=this;if(!((ao.Kind()===25))){$panic(new $String(\"reflect: Field of non-struct type\"));}ap=(ao.kindType);return ap.Field(an);};CE.prototype.Field=function(an){return this.$val.Field(an);};CE.ptr.prototype.FieldByIndex=function(an){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if(!((ao.Kind()===25))){$panic(new $String(\"reflect: FieldByIndex of non-struct type\"));}ap=(ao.kindType);aq=ap.FieldByIndex(an);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq;}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.FieldByIndex};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.FieldByIndex=function(an){return this.$val.FieldByIndex(an);};CE.ptr.prototype.FieldByName=function(an){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if(!((ao.Kind()===25))){$panic(new $String(\"reflect: FieldByName of non-struct type\"));}ap=(ao.kindType);aq=ap.FieldByName(an);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq;}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.FieldByName};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.FieldByName=function(an){return this.$val.FieldByName(an);};CE.ptr.prototype.FieldByNameFunc=function(an){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if(!((ao.Kind()===25))){$panic(new $String(\"reflect: FieldByNameFunc of non-struct type\"));}ap=(ao.kindType);aq=ap.FieldByNameFunc(an);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq;}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.FieldByNameFunc};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.FieldByNameFunc=function(an){return this.$val.FieldByNameFunc(an);};CE.ptr.prototype.In=function(an){var an,ao,ap,aq;ao=this;if(!((ao.Kind()===19))){$panic(new $String(\"reflect: In of non-func type\"));}ap=(ao.kindType);return EQ((aq=ap.in$(),((an<0||an>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+an])));};CE.prototype.In=function(an){return this.$val.In(an);};CE.ptr.prototype.Key=function(){var an,ao;an=this;if(!((an.Kind()===21))){$panic(new $String(\"reflect: Key of non-map type\"));}ao=(an.kindType);return EQ(ao.key);};CE.prototype.Key=function(){return this.$val.Key();};CE.ptr.prototype.Len=function(){var an,ao;an=this;if(!((an.Kind()===17))){$panic(new $String(\"reflect: Len of non-array type\"));}ao=(an.kindType);return((ao.len>>0));};CE.prototype.Len=function(){return this.$val.Len();};CE.ptr.prototype.NumField=function(){var an,ao;an=this;if(!((an.Kind()===25))){$panic(new $String(\"reflect: NumField of non-struct type\"));}ao=(an.kindType);return ao.fields.$length;};CE.prototype.NumField=function(){return this.$val.NumField();};CE.ptr.prototype.NumIn=function(){var an,ao;an=this;if(!((an.Kind()===19))){$panic(new $String(\"reflect: NumIn of non-func type\"));}ao=(an.kindType);return((ao.inCount>>0));};CE.prototype.NumIn=function(){return this.$val.NumIn();};CE.ptr.prototype.NumOut=function(){var an,ao;an=this;if(!((an.Kind()===19))){$panic(new $String(\"reflect: NumOut of non-func type\"));}ao=(an.kindType);return ao.out().$length;};CE.prototype.NumOut=function(){return this.$val.NumOut();};CE.ptr.prototype.Out=function(an){var an,ao,ap,aq;ao=this;if(!((ao.Kind()===19))){$panic(new $String(\"reflect: Out of non-func type\"));}ap=(ao.kindType);return EQ((aq=ap.out(),((an<0||an>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+an])));};CE.prototype.Out=function(an){return this.$val.Out(an);};CH.prototype.String=function(){var an,ao;an=this.$val;ao=an;if(ao===(2)){return\"chan<-\";}else if(ao===(1)){return\"<-chan\";}else if(ao===(3)){return\"chan\";}return\"ChanDir\"+B.Itoa(((an>>0)));};$ptrType(CH).prototype.String=function(){return new CH(this.$get()).String();};CL.ptr.prototype.Method=function(an){var an,ao,ap,aq,ar,as;ao=new CS.ptr(\"\",\"\",$ifaceNil,new EY.ptr(HR.nil,0,0),0);ap=this;if(an<0||an>=ap.methods.$length){return ao;}ar=(aq=ap.methods,((an<0||an>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+an]));as=$clone(ap.rtype.nameOff(ar.name),Q);ao.Name=$clone(as,Q).name();if(!$clone(as,Q).isExported()){ao.PkgPath=$clone(as,Q).pkgPath();if(ao.PkgPath===\"\"){ao.PkgPath=$clone(ap.pkgPath,Q).name();}}ao.Type=EQ(ap.rtype.typeOff(ar.typ));ao.Index=an;return ao;};CL.prototype.Method=function(an){return this.$val.Method(an);};CL.ptr.prototype.NumMethod=function(){var an;an=this;return an.methods.$length;};CL.prototype.NumMethod=function(){return this.$val.NumMethod();};CL.ptr.prototype.MethodByName=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax;ao=new CS.ptr(\"\",\"\",$ifaceNil,new EY.ptr(HR.nil,0,0),0);ap=false;aq=this;if(aq===IP.nil){return[ao,ap];}ar=IQ.nil;as=aq.methods;at=0;while(true){if(!(at<as.$length)){break;}au=at;ar=(av=aq.methods,((au<0||au>=av.$length)?($throwRuntimeError(\"index out of range\"),undefined):av.$array[av.$offset+au]));if($clone(aq.rtype.nameOff(ar.name),Q).name()===an){aw=$clone(aq.Method(au),CS);ax=true;CS.copy(ao,aw);ap=ax;return[ao,ap];}at++;}return[ao,ap];};CL.prototype.MethodByName=function(an){return this.$val.MethodByName(an);};DH.prototype.Get=function(an){var an,ao,ap,aq;ao=this.$val;ap=new DH(ao).Lookup(an);aq=ap[0];return aq;};$ptrType(DH).prototype.Get=function(an){return new DH(this.$get()).Get(an);};DH.prototype.Lookup=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba;ao=\"\";ap=false;aq=this.$val;while(true){if(!(!(aq===\"\"))){break;}ar=0;while(true){if(!(ar<aq.length&&(aq.charCodeAt(ar)===32))){break;}ar=ar+(1)>>0;}aq=$substring(aq,ar);if(aq===\"\"){break;}ar=0;while(true){if(!(ar<aq.length&&aq.charCodeAt(ar)>32&&!((aq.charCodeAt(ar)===58))&&!((aq.charCodeAt(ar)===34))&&!((aq.charCodeAt(ar)===127)))){break;}ar=ar+(1)>>0;}if((ar===0)||(ar+1>>0)>=aq.length||!((aq.charCodeAt(ar)===58))||!((aq.charCodeAt((ar+1>>0))===34))){break;}as=($substring(aq,0,ar));aq=$substring(aq,(ar+1>>0));ar=1;while(true){if(!(ar<aq.length&&!((aq.charCodeAt(ar)===34)))){break;}if(aq.charCodeAt(ar)===92){ar=ar+(1)>>0;}ar=ar+(1)>>0;}if(ar>=aq.length){break;}at=($substring(aq,0,(ar+1>>0)));aq=$substring(aq,(ar+1>>0));if(an===as){au=B.Unquote(at);av=au[0];aw=au[1];if(!($interfaceIsEqual(aw,$ifaceNil))){break;}ax=av;ay=true;ao=ax;ap=ay;return[ao,ap];}}az=\"\";ba=false;ao=az;ap=ba;return[ao,ap];};$ptrType(DH).prototype.Lookup=function(an){return new DH(this.$get()).Lookup(an);};CQ.ptr.prototype.Field=function(an){var an,ao,ap,aq,ar,as;ao=new DG.ptr(\"\",\"\",$ifaceNil,\"\",0,IR.nil,false);ap=this;if(an<0||an>=ap.fields.$length){$panic(new $String(\"reflect: Field index out of bounds\"));}ar=(aq=ap.fields,((an<0||an>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+an]));ao.Type=EQ(ar.typ);ao.Name=$clone(ar.name,Q).name();ao.Anonymous=ar.embedded();if(!$clone(ar.name,Q).isExported()){ao.PkgPath=$clone(ap.pkgPath,Q).name();}as=$clone(ar.name,Q).tag();if(!(as===\"\")){ao.Tag=(as);}ao.Offset=ar.offset();ao.Index=new IR([an]);return ao;};CQ.prototype.Field=function(an){return this.$val.Field(an);};CQ.ptr.prototype.FieldByIndex=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=new DG.ptr(\"\",\"\",$ifaceNil,\"\",0,IR.nil,false);ap=this;ao.Type=EQ(ap.rtype);aq=an;ar=0;case 1:if(!(ar<aq.$length)){$s=2;continue;}as=ar;at=((ar<0||ar>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+ar]);if(as>0){$s=3;continue;}$s=4;continue;case 3:au=ao.Type;aw=au.Kind();$s=8;case 8:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}if(!(aw===22)){av=false;$s=7;continue s;}ax=au.Elem();$s=9;case 9:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ay=ax.Kind();$s=10;case 10:if($c){$c=false;ay=ay.$blk();}if(ay&&ay.$blk!==undefined){break s;}av=ay===25;case 7:if(av){$s=5;continue;}$s=6;continue;case 5:az=au.Elem();$s=11;case 11:if($c){$c=false;az=az.$blk();}if(az&&az.$blk!==undefined){break s;}au=az;case 6:ao.Type=au;case 4:ba=ao.Type.Field(at);$s=12;case 12:if($c){$c=false;ba=ba.$blk();}if(ba&&ba.$blk!==undefined){break s;}DG.copy(ao,ba);ar++;$s=1;continue;case 2:$s=-1;return ao;}return;}if($f===undefined){$f={$blk:CQ.ptr.prototype.FieldByIndex};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.$s=$s;$f.$r=$r;return $f;};CQ.prototype.FieldByIndex=function(an){return this.$val.FieldByIndex(an);};CQ.ptr.prototype.FieldByNameFunc=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;bu=$f.bu;bv=$f.bv;bw=$f.bw;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=new DG.ptr(\"\",\"\",$ifaceNil,\"\",0,IR.nil,false);ap=false;aq=this;ar=new IS([]);as=new IS([new DI.ptr(aq,IR.nil)]);at=false;au=$makeMap(IT.keyFor,[]);case 1:if(!(as.$length>0)){$s=2;continue;}av=as;aw=$subslice(ar,0,0);ar=av;as=aw;ax=at;at=false;ay=ar;az=0;case 3:if(!(az<ay.$length)){$s=4;continue;}ba=$clone(((az<0||az>=ay.$length)?($throwRuntimeError(\"index out of range\"),undefined):ay.$array[ay.$offset+az]),DI);bb=ba.typ;if((bc=au[IT.keyFor(bb)],bc!==undefined?bc.v:false)){$s=5;continue;}$s=6;continue;case 5:az++;$s=3;continue;case 6:bd=bb;(au||$throwRuntimeError(\"assignment to entry in nil map\"))[IT.keyFor(bd)]={k:bd,v:true};be=bb.fields;bf=0;case 7:if(!(bf<be.$length)){$s=8;continue;}bg=bf;bi=(bh=bb.fields,((bg<0||bg>=bh.$length)?($throwRuntimeError(\"index out of range\"),undefined):bh.$array[bh.$offset+bg]));bj=$clone(bi.name,Q).name();bk=HR.nil;if(bi.embedded()){$s=9;continue;}$s=10;continue;case 9:bk=bi.typ;if(bk.Kind()===22){$s=11;continue;}$s=12;continue;case 11:bl=bk.Elem().common();$s=13;case 13:if($c){$c=false;bl=bl.$blk();}if(bl&&bl.$blk!==undefined){break s;}bk=bl;case 12:case 10:bm=an(bj);$s=16;case 16:if($c){$c=false;bm=bm.$blk();}if(bm&&bm.$blk!==undefined){break s;}if(bm){$s=14;continue;}$s=15;continue;case 14:if((bn=ax[IT.keyFor(bb)],bn!==undefined?bn.v:0)>1||ap){bo=new DG.ptr(\"\",\"\",$ifaceNil,\"\",0,IR.nil,false);bp=false;DG.copy(ao,bo);ap=bp;$s=-1;return[ao,ap];}DG.copy(ao,bb.Field(bg));ao.Index=IR.nil;ao.Index=$appendSlice(ao.Index,ba.index);ao.Index=$append(ao.Index,bg);ap=true;bf++;$s=7;continue;case 15:if(ap||bk===HR.nil||!((bk.Kind()===25))){bf++;$s=7;continue;}bq=(bk.kindType);if((br=at[IT.keyFor(bq)],br!==undefined?br.v:0)>0){bs=bq;(at||$throwRuntimeError(\"assignment to entry in nil map\"))[IT.keyFor(bs)]={k:bs,v:2};bf++;$s=7;continue;}if(at===false){at=$makeMap(IT.keyFor,[]);}bt=bq;(at||$throwRuntimeError(\"assignment to entry in nil map\"))[IT.keyFor(bt)]={k:bt,v:1};if((bu=ax[IT.keyFor(bb)],bu!==undefined?bu.v:0)>1){bv=bq;(at||$throwRuntimeError(\"assignment to entry in nil map\"))[IT.keyFor(bv)]={k:bv,v:2};}bw=IR.nil;bw=$appendSlice(bw,ba.index);bw=$append(bw,bg);as=$append(as,new DI.ptr(bq,bw));bf++;$s=7;continue;case 8:az++;$s=3;continue;case 4:if(ap){$s=2;continue;}$s=1;continue;case 2:$s=-1;return[ao,ap];}return;}if($f===undefined){$f={$blk:CQ.ptr.prototype.FieldByNameFunc};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.bu=bu;$f.bv=bv;$f.bw=bw;$f.$s=$s;$f.$r=$r;return $f;};CQ.prototype.FieldByNameFunc=function(an){return this.$val.FieldByNameFunc(an);};CQ.ptr.prototype.FieldByName=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=[an];ao=new DG.ptr(\"\",\"\",$ifaceNil,\"\",0,IR.nil,false);ap=false;aq=this;ar=false;if(!(an[0]===\"\")){as=aq.fields;at=0;while(true){if(!(at<as.$length)){break;}au=at;aw=(av=aq.fields,((au<0||au>=av.$length)?($throwRuntimeError(\"index out of range\"),undefined):av.$array[av.$offset+au]));if($clone(aw.name,Q).name()===an[0]){ax=$clone(aq.Field(au),DG);ay=true;DG.copy(ao,ax);ap=ay;$s=-1;return[ao,ap];}if(aw.embedded()){ar=true;}at++;}}if(!ar){$s=-1;return[ao,ap];}ba=aq.FieldByNameFunc((function(an){return function(ba){var ba;return ba===an[0];};})(an));$s=1;case 1:if($c){$c=false;ba=ba.$blk();}if(ba&&ba.$blk!==undefined){break s;}az=ba;DG.copy(ao,az[0]);ap=az[1];$s=-1;return[ao,ap];}return;}if($f===undefined){$f={$blk:CQ.ptr.prototype.FieldByName};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.$s=$s;$f.$r=$r;return $f;};CQ.prototype.FieldByName=function(an){return this.$val.FieldByName(an);};DK=function(an){var an;return $assertType(an,HR).ptrTo();};$pkg.PtrTo=DK;CE.ptr.prototype.Implements=function(an){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if($interfaceIsEqual(an,$ifaceNil)){$panic(new $String(\"reflect: nil type passed to Type.Implements\"));}ap=an.Kind();$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}if(!((ap===20))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect: non-interface type passed to Type.Implements\"));case 2:$s=-1;return DM($assertType(an,HR),ao);}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.Implements};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.Implements=function(an){return this.$val.Implements(an);};CE.ptr.prototype.AssignableTo=function(an){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if($interfaceIsEqual(an,$ifaceNil)){$panic(new $String(\"reflect: nil type passed to Type.AssignableTo\"));}ap=$assertType(an,HR);aq=DN(ap,ao);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq||DM(ap,ao);}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.AssignableTo};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.AssignableTo=function(an){return this.$val.AssignableTo(an);};CE.ptr.prototype.ConvertibleTo=function(an){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if($interfaceIsEqual(an,$ifaceNil)){$panic(new $String(\"reflect: nil type passed to Type.ConvertibleTo\"));}ap=$assertType(an,HR);aq=GJ(ap,ao);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return!(aq===$throwNilPointerError);}return;}if($f===undefined){$f={$blk:CE.ptr.prototype.ConvertibleTo};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};CE.prototype.ConvertibleTo=function(an){return this.$val.ConvertibleTo(an);};DM=function(an,ao){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl;if(!((an.Kind()===20))){return false;}ap=(an.kindType);if(ap.methods.$length===0){return true;}if(ao.Kind()===20){aq=(ao.kindType);ar=0;as=0;while(true){if(!(as<aq.methods.$length)){break;}au=(at=ap.methods,((ar<0||ar>=at.$length)?($throwRuntimeError(\"index out of range\"),undefined):at.$array[at.$offset+ar]));av=$clone(ap.rtype.nameOff(au.name),Q);ax=(aw=aq.methods,((as<0||as>=aw.$length)?($throwRuntimeError(\"index out of range\"),undefined):aw.$array[aw.$offset+as]));ay=$clone(ao.nameOff(ax.name),Q);if($clone(ay,Q).name()===$clone(av,Q).name()&&ao.typeOff(ax.typ)===ap.rtype.typeOff(au.typ)){if(!$clone(av,Q).isExported()){az=$clone(av,Q).pkgPath();if(az===\"\"){az=$clone(ap.pkgPath,Q).name();}ba=$clone(ay,Q).pkgPath();if(ba===\"\"){ba=$clone(aq.pkgPath,Q).name();}if(!(az===ba)){as=as+(1)>>0;continue;}}ar=ar+(1)>>0;if(ar>=ap.methods.$length){return true;}}as=as+(1)>>0;}return false;}bb=ao.uncommon();if(bb===IE.nil){return false;}bc=0;bd=bb.methods();be=0;while(true){if(!(be<((bb.mcount>>0)))){break;}bg=(bf=ap.methods,((bc<0||bc>=bf.$length)?($throwRuntimeError(\"index out of range\"),undefined):bf.$array[bf.$offset+bc]));bh=$clone(ap.rtype.nameOff(bg.name),Q);bi=$clone(((be<0||be>=bd.$length)?($throwRuntimeError(\"index out of range\"),undefined):bd.$array[bd.$offset+be]),CG);bj=$clone(ao.nameOff(bi.name),Q);if($clone(bj,Q).name()===$clone(bh,Q).name()&&ao.typeOff(bi.mtyp)===ap.rtype.typeOff(bg.typ)){if(!$clone(bh,Q).isExported()){bk=$clone(bh,Q).pkgPath();if(bk===\"\"){bk=$clone(ap.pkgPath,Q).name();}bl=$clone(bj,Q).pkgPath();if(bl===\"\"){bl=$clone(ao.nameOff(bb.pkgPath),Q).name();}if(!(bk===bl)){be=be+(1)>>0;continue;}}bc=bc+(1)>>0;if(bc>=ap.methods.$length){return true;}}be=be+(1)>>0;}return false;};DN=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(an===ao){$s=-1;return true;}if(!(an.Name()===\"\")&&!(ao.Name()===\"\")||!((an.Kind()===ao.Kind()))){$s=-1;return false;}ap=DP(an,ao,true);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:DN};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};DO=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(ap){$s=-1;return $interfaceIsEqual(an,ao);}ar=an.Name();$s=4;case 4:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=ao.Name();$s=5;case 5:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}if(!(ar===as)){aq=true;$s=3;continue s;}at=an.Kind();$s=6;case 6:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}au=ao.Kind();$s=7;case 7:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}aq=!((at===au));case 3:if(aq){$s=1;continue;}$s=2;continue;case 1:$s=-1;return false;case 2:av=an.common();$s=8;case 8:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}aw=av;ax=ao.common();$s=9;case 9:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ay=ax;az=DP(aw,ay,false);$s=10;case 10:if($c){$c=false;az=az.$blk();}if(az&&az.$blk!==undefined){break s;}$s=-1;return az;}return;}if($f===undefined){$f={$blk:DO};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.$s=$s;$f.$r=$r;return $f;};DP=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(an===ao){$s=-1;return true;}aq=an.Kind();if(!((aq===ao.Kind()))){$s=-1;return false;}if(1<=aq&&aq<=16||(aq===24)||(aq===26)){$s=-1;return true;}ar=aq;if(ar===(17)){$s=2;continue;}if(ar===(18)){$s=3;continue;}if(ar===(19)){$s=4;continue;}if(ar===(20)){$s=5;continue;}if(ar===(21)){$s=6;continue;}if((ar===(22))||(ar===(23))){$s=7;continue;}if(ar===(25)){$s=8;continue;}$s=9;continue;case 2:if(!(an.Len()===ao.Len())){as=false;$s=10;continue s;}at=DO(an.Elem(),ao.Elem(),ap);$s=11;case 11:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}as=at;case 10:$s=-1;return as;case 3:if(!(ao.ChanDir()===3)){au=false;$s=14;continue s;}av=DO(an.Elem(),ao.Elem(),ap);$s=15;case 15:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}au=av;case 14:if(au){$s=12;continue;}$s=13;continue;case 12:$s=-1;return true;case 13:if(!(ao.ChanDir()===an.ChanDir())){aw=false;$s=16;continue s;}ax=DO(an.Elem(),ao.Elem(),ap);$s=17;case 17:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}aw=ax;case 16:$s=-1;return aw;case 4:ay=(an.kindType);az=(ao.kindType);if(!((ay.outCount===az.outCount))||!((ay.inCount===az.inCount))){$s=-1;return false;}ba=0;case 18:if(!(ba<ay.rtype.NumIn())){$s=19;continue;}bb=DO(ay.rtype.In(ba),az.rtype.In(ba),ap);$s=22;case 22:if($c){$c=false;bb=bb.$blk();}if(bb&&bb.$blk!==undefined){break s;}if(!bb){$s=20;continue;}$s=21;continue;case 20:$s=-1;return false;case 21:ba=ba+(1)>>0;$s=18;continue;case 19:bc=0;case 23:if(!(bc<ay.rtype.NumOut())){$s=24;continue;}bd=DO(ay.rtype.Out(bc),az.rtype.Out(bc),ap);$s=27;case 27:if($c){$c=false;bd=bd.$blk();}if(bd&&bd.$blk!==undefined){break s;}if(!bd){$s=25;continue;}$s=26;continue;case 25:$s=-1;return false;case 26:bc=bc+(1)>>0;$s=23;continue;case 24:$s=-1;return true;case 5:be=(an.kindType);bf=(ao.kindType);if((be.methods.$length===0)&&(bf.methods.$length===0)){$s=-1;return true;}$s=-1;return false;case 6:bh=DO(an.Key(),ao.Key(),ap);$s=29;case 29:if($c){$c=false;bh=bh.$blk();}if(bh&&bh.$blk!==undefined){break s;}if(!(bh)){bg=false;$s=28;continue s;}bi=DO(an.Elem(),ao.Elem(),ap);$s=30;case 30:if($c){$c=false;bi=bi.$blk();}if(bi&&bi.$blk!==undefined){break s;}bg=bi;case 28:$s=-1;return bg;case 7:bj=DO(an.Elem(),ao.Elem(),ap);$s=31;case 31:if($c){$c=false;bj=bj.$blk();}if(bj&&bj.$blk!==undefined){break s;}$s=-1;return bj;case 8:bk=(an.kindType);bl=(ao.kindType);if(!((bk.fields.$length===bl.fields.$length))){$s=-1;return false;}if(!($clone(bk.pkgPath,Q).name()===$clone(bl.pkgPath,Q).name())){$s=-1;return false;}bm=bk.fields;bn=0;case 32:if(!(bn<bm.$length)){$s=33;continue;}bo=bn;bq=(bp=bk.fields,((bo<0||bo>=bp.$length)?($throwRuntimeError(\"index out of range\"),undefined):bp.$array[bp.$offset+bo]));bs=(br=bl.fields,((bo<0||bo>=br.$length)?($throwRuntimeError(\"index out of range\"),undefined):br.$array[br.$offset+bo]));if(!($clone(bq.name,Q).name()===$clone(bs.name,Q).name())){$s=-1;return false;}bt=DO(bq.typ,bs.typ,ap);$s=36;case 36:if($c){$c=false;bt=bt.$blk();}if(bt&&bt.$blk!==undefined){break s;}if(!bt){$s=34;continue;}$s=35;continue;case 34:$s=-1;return false;case 35:if(ap&&!($clone(bq.name,Q).tag()===$clone(bs.name,Q).tag())){$s=-1;return false;}if(!((bq.offsetEmbed===bs.offsetEmbed))){$s=-1;return false;}bn++;$s=32;continue;case 33:$s=-1;return true;case 9:case 1:$s=-1;return false;}return;}if($f===undefined){$f={$blk:DP};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.$s=$s;$f.$r=$r;return $f;};EQ=function(an){var an;if(an===HR.nil){return $ifaceNil;}return an;};EV=function(an){var an;return((an.kind&32)>>>0)===0;};EZ.prototype.kind=function(){var an;an=this.$val;return((((an&31)>>>0)>>>0));};$ptrType(EZ).prototype.kind=function(){return new EZ(this.$get()).kind();};EZ.prototype.ro=function(){var an;an=this.$val;if(!((((an&96)>>>0)===0))){return 32;}return 0;};$ptrType(EZ).prototype.ro=function(){return new EZ(this.$get()).ro();};EY.ptr.prototype.pointer=function(){var an;an=this;if(!((an.typ.size===4))||!an.typ.pointers()){$panic(new $String(\"can't call pointer on a non-pointer Value\"));}if(!((((an.flag&128)>>>0)===0))){return(an.ptr).$get();}return an.ptr;};EY.prototype.pointer=function(){return this.$val.pointer();};FC.ptr.prototype.Error=function(){var an;an=this;if(an.Kind===0){return\"reflect: call of \"+an.Method+\" on zero Value\";}return\"reflect: call of \"+an.Method+\" on \"+new CC(an.Kind).String()+\" Value\";};FC.prototype.Error=function(){return this.$val.Error();};EZ.prototype.mustBe=function(an){var an,ao;ao=this.$val;if(!((new EZ(ao).kind()===an))){$panic(new FC.ptr(BH(),new EZ(ao).kind()));}};$ptrType(EZ).prototype.mustBe=function(an){return new EZ(this.$get()).mustBe(an);};EZ.prototype.mustBeExported=function(){var an;an=this.$val;if(an===0){$panic(new FC.ptr(BH(),0));}if(!((((an&96)>>>0)===0))){$panic(new $String(\"reflect: \"+BH()+\" using value obtained using unexported field\"));}};$ptrType(EZ).prototype.mustBeExported=function(){return new EZ(this.$get()).mustBeExported();};EZ.prototype.mustBeAssignable=function(){var an;an=this.$val;if(an===0){$panic(new FC.ptr(BH(),0));}if(!((((an&96)>>>0)===0))){$panic(new $String(\"reflect: \"+BH()+\" using value obtained using unexported field\"));}if(((an&256)>>>0)===0){$panic(new $String(\"reflect: \"+BH()+\" using unaddressable value\"));}};$ptrType(EZ).prototype.mustBeAssignable=function(){return new EZ(this.$get()).mustBeAssignable();};EY.ptr.prototype.Addr=function(){var an;an=this;if(((an.flag&256)>>>0)===0){$panic(new $String(\"reflect.Value.Addr of unaddressable value\"));}return new EY.ptr(an.typ.ptrTo(),an.ptr,(new EZ(an.flag).ro()|22)>>>0);};EY.prototype.Addr=function(){return this.$val.Addr();};EY.ptr.prototype.Bool=function(){var an;an=this;new EZ(an.flag).mustBe(1);return(an.ptr).$get();};EY.prototype.Bool=function(){return this.$val.Bool();};EY.ptr.prototype.Bytes=function(){var an,ao,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;new EZ(an.flag).mustBe(23);ao=an.typ.Elem().Kind();$s=3;case 3:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}if(!((ao===8))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect.Value.Bytes of non-byte slice\"));case 2:$s=-1;return(an.ptr).$get();}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Bytes};}$f.an=an;$f.ao=ao;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Bytes=function(){return this.$val.Bytes();};EY.ptr.prototype.runes=function(){var an,ao,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;new EZ(an.flag).mustBe(23);ao=an.typ.Elem().Kind();$s=3;case 3:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}if(!((ao===5))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect.Value.Bytes of non-rune slice\"));case 2:$s=-1;return(an.ptr).$get();}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.runes};}$f.an=an;$f.ao=ao;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.runes=function(){return this.$val.runes();};EY.ptr.prototype.CanAddr=function(){var an;an=this;return!((((an.flag&256)>>>0)===0));};EY.prototype.CanAddr=function(){return this.$val.CanAddr();};EY.ptr.prototype.CanSet=function(){var an;an=this;return((an.flag&352)>>>0)===256;};EY.prototype.CanSet=function(){return this.$val.CanSet();};EY.ptr.prototype.Call=function(an){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBe(19);new EZ(ao.flag).mustBeExported();ap=$clone(ao,EY).call(\"Call\",an);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Call};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Call=function(an){return this.$val.Call(an);};EY.ptr.prototype.CallSlice=function(an){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBe(19);new EZ(ao.flag).mustBeExported();ap=$clone(ao,EY).call(\"CallSlice\",an);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.CallSlice};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.CallSlice=function(an){return this.$val.CallSlice(an);};EY.ptr.prototype.Complex=function(){var an,ao,ap,aq;an=this;ao=new EZ(an.flag).kind();ap=ao;if(ap===(15)){return((aq=(an.ptr).$get(),new $Complex128(aq.$real,aq.$imag)));}else if(ap===(16)){return(an.ptr).$get();}$panic(new FC.ptr(\"reflect.Value.Complex\",new EZ(an.flag).kind()));};EY.prototype.Complex=function(){return this.$val.Complex();};EY.ptr.prototype.FieldByIndex=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if(an.$length===1){$s=1;continue;}$s=2;continue;case 1:ap=$clone(ao,EY).Field((0>=an.$length?($throwRuntimeError(\"index out of range\"),undefined):an.$array[an.$offset+0]));$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;case 2:new EZ(ao.flag).mustBe(25);aq=an;ar=0;case 4:if(!(ar<aq.$length)){$s=5;continue;}as=ar;at=((ar<0||ar>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+ar]);if(as>0){$s=6;continue;}$s=7;continue;case 6:if(!($clone(ao,EY).Kind()===22)){au=false;$s=10;continue s;}av=ao.typ.Elem().Kind();$s=11;case 11:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}au=av===25;case 10:if(au){$s=8;continue;}$s=9;continue;case 8:if($clone(ao,EY).IsNil()){$panic(new $String(\"reflect: indirection through nil pointer to embedded struct\"));}aw=$clone(ao,EY).Elem();$s=12;case 12:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}ao=aw;case 9:case 7:ax=$clone(ao,EY).Field(at);$s=13;case 13:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ao=ax;ar++;$s=4;continue;case 5:$s=-1;return ao;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.FieldByIndex};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.FieldByIndex=function(an){return this.$val.FieldByIndex(an);};EY.ptr.prototype.FieldByName=function(an){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBe(25);aq=ao.typ.FieldByName(an);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ap=aq;ar=$clone(ap[0],DG);as=ap[1];if(as){$s=2;continue;}$s=3;continue;case 2:at=$clone(ao,EY).FieldByIndex(ar.Index);$s=4;case 4:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return at;case 3:$s=-1;return new EY.ptr(HR.nil,0,0);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.FieldByName};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.FieldByName=function(an){return this.$val.FieldByName(an);};EY.ptr.prototype.FieldByNameFunc=function(an){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;aq=ao.typ.FieldByNameFunc(an);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ap=aq;ar=$clone(ap[0],DG);as=ap[1];if(as){$s=2;continue;}$s=3;continue;case 2:at=$clone(ao,EY).FieldByIndex(ar.Index);$s=4;case 4:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return at;case 3:$s=-1;return new EY.ptr(HR.nil,0,0);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.FieldByNameFunc};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.FieldByNameFunc=function(an){return this.$val.FieldByNameFunc(an);};EY.ptr.prototype.Float=function(){var an,ao,ap;an=this;ao=new EZ(an.flag).kind();ap=ao;if(ap===(13)){return((an.ptr).$get());}else if(ap===(14)){return(an.ptr).$get();}$panic(new FC.ptr(\"reflect.Value.Float\",new EZ(an.flag).kind()));};EY.prototype.Float=function(){return this.$val.Float();};EY.ptr.prototype.Int=function(){var an,ao,ap,aq;an=this;ao=new EZ(an.flag).kind();ap=an.ptr;aq=ao;if(aq===(2)){return(new $Int64(0,(ap).$get()));}else if(aq===(3)){return(new $Int64(0,(ap).$get()));}else if(aq===(4)){return(new $Int64(0,(ap).$get()));}else if(aq===(5)){return(new $Int64(0,(ap).$get()));}else if(aq===(6)){return(ap).$get();}$panic(new FC.ptr(\"reflect.Value.Int\",new EZ(an.flag).kind()));};EY.prototype.Int=function(){return this.$val.Int();};EY.ptr.prototype.CanInterface=function(){var an;an=this;if(an.flag===0){$panic(new FC.ptr(\"reflect.Value.CanInterface\",0));}return((an.flag&96)>>>0)===0;};EY.prototype.CanInterface=function(){return this.$val.CanInterface();};EY.ptr.prototype.Interface=function(){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=$ifaceNil;ao=this;ap=BF($clone(ao,EY),true);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}an=ap;$s=-1;return an;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Interface};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Interface=function(){return this.$val.Interface();};EY.ptr.prototype.IsValid=function(){var an;an=this;return!((an.flag===0));};EY.prototype.IsValid=function(){return this.$val.IsValid();};EY.ptr.prototype.Kind=function(){var an;an=this;return new EZ(an.flag).kind();};EY.prototype.Kind=function(){return this.$val.Kind();};EY.ptr.prototype.MapIndex=function(an){var an,ao,ap,aq,ar,as,at,au,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBe(21);ap=(ao.typ.kindType);aq=$clone(an,EY).assignTo(\"reflect.Value.MapIndex\",ap.key,0);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}an=aq;ar=0;if(!((((an.flag&128)>>>0)===0))){ar=an.ptr;}else{ar=((an.$ptr_ptr||(an.$ptr_ptr=new JC(function(){return this.$target.ptr;},function($v){this.$target.ptr=$v;},an))));}as=AT(ao.typ,$clone(ao,EY).pointer(),ar);if(as===0){$s=-1;return new EY.ptr(HR.nil,0,0);}at=ap.elem;au=new EZ((((ao.flag|an.flag)>>>0))).ro();au=(au|(((at.Kind()>>>0))))>>>0;$s=-1;return FN(at,au,as);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.MapIndex};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.MapIndex=function(an){return this.$val.MapIndex(an);};EY.ptr.prototype.MapKeys=function(){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;new EZ(an.flag).mustBe(21);ao=(an.typ.kindType);ap=ao.key;aq=(new EZ(an.flag).ro()|((ap.Kind()>>>0)))>>>0;ar=$clone(an,EY).pointer();as=0;if(!(ar===0)){as=BB(ar);}at=AX(an.typ,ar);au=$makeSlice(II,as);av=0;av=0;case 1:if(!(av<au.$length)){$s=2;continue;}aw=AY(at);$s=3;case 3:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}ax=aw;if(ax===0){$s=2;continue;}((av<0||av>=au.$length)?($throwRuntimeError(\"index out of range\"),undefined):au.$array[au.$offset+av]=FN(ap,aq,ax));BA(at);av=av+(1)>>0;$s=1;continue;case 2:$s=-1;return $subslice(au,0,av);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.MapKeys};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.MapKeys=function(){return this.$val.MapKeys();};FM.ptr.prototype.Key=function(){var an,ao,ap,aq,ar,as,at,au,av,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;if(an.it===0){$panic(new $String(\"MapIter.Key called before Next\"));}ao=AY(an.it);$s=3;case 3:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}if(ao===0){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"MapIter.Key called on exhausted iterator\"));case 2:ap=(an.m.typ.kindType);aq=ap.key;ar=aq;as=(new EZ(an.m.flag).ro()|((aq.Kind()>>>0)))>>>0;at=AY(an.it);$s=4;case 4:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}au=at;av=FN(ar,as,au);$s=5;case 5:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}$s=-1;return av;}return;}if($f===undefined){$f={$blk:FM.ptr.prototype.Key};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.$s=$s;$f.$r=$r;return $f;};FM.prototype.Key=function(){return this.$val.Key();};FM.ptr.prototype.Value=function(){var an,ao,ap,aq,ar,as,at,au,av,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;if(an.it===0){$panic(new $String(\"MapIter.Value called before Next\"));}ao=AY(an.it);$s=3;case 3:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}if(ao===0){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"MapIter.Value called on exhausted iterator\"));case 2:ap=(an.m.typ.kindType);aq=ap.elem;ar=aq;as=(new EZ(an.m.flag).ro()|((aq.Kind()>>>0)))>>>0;at=AZ(an.it);$s=4;case 4:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}au=at;av=FN(ar,as,au);$s=5;case 5:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}$s=-1;return av;}return;}if($f===undefined){$f={$blk:FM.ptr.prototype.Value};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.$s=$s;$f.$r=$r;return $f;};FM.prototype.Value=function(){return this.$val.Value();};FM.ptr.prototype.Next=function(){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;if(an.it===0){$s=1;continue;}$s=2;continue;case 1:an.it=AX(an.m.typ,$clone(an.m,EY).pointer());$s=3;continue;case 2:ao=AY(an.it);$s=6;case 6:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}if(ao===0){$s=4;continue;}$s=5;continue;case 4:$panic(new $String(\"MapIter.Next called on exhausted iterator\"));case 5:BA(an.it);case 3:ap=AY(an.it);$s=7;case 7:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return!(ap===0);}return;}if($f===undefined){$f={$blk:FM.ptr.prototype.Next};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};FM.prototype.Next=function(){return this.$val.Next();};EY.ptr.prototype.MapRange=function(){var an;an=this;new EZ(an.flag).mustBe(21);return new FM.ptr($clone(an,EY),0);};EY.prototype.MapRange=function(){return this.$val.MapRange();};FN=function(an,ao,ap){var an,ao,ap,aq;if(EV(an)){aq=AL(an);AO(an,aq,ap);return new EY.ptr(an,aq,(ao|128)>>>0);}return new EY.ptr(an,(ap).$get(),ao);};EY.ptr.prototype.Method=function(an){var an,ao,ap;ao=this;if(ao.typ===HR.nil){$panic(new FC.ptr(\"reflect.Value.Method\",0));}if(!((((ao.flag&512)>>>0)===0))||((an>>>0))>=((ao.typ.NumMethod()>>>0))){$panic(new $String(\"reflect: Method index out of range\"));}if((ao.typ.Kind()===20)&&$clone(ao,EY).IsNil()){$panic(new $String(\"reflect: Method on nil interface value\"));}ap=(ao.flag&160)>>>0;ap=(ap|(19))>>>0;ap=(ap|((((((an>>>0))<<10>>>0)|512)>>>0)))>>>0;return new EY.ptr(ao.typ,ao.ptr,ap);};EY.prototype.Method=function(an){return this.$val.Method(an);};EY.ptr.prototype.NumMethod=function(){var an;an=this;if(an.typ===HR.nil){$panic(new FC.ptr(\"reflect.Value.NumMethod\",0));}if(!((((an.flag&512)>>>0)===0))){return 0;}return an.typ.NumMethod();};EY.prototype.NumMethod=function(){return this.$val.NumMethod();};EY.ptr.prototype.MethodByName=function(an){var an,ao,ap,aq,ar,as,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if(ao.typ===HR.nil){$panic(new FC.ptr(\"reflect.Value.MethodByName\",0));}if(!((((ao.flag&512)>>>0)===0))){$s=-1;return new EY.ptr(HR.nil,0,0);}aq=ao.typ.MethodByName(an);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ap=aq;ar=$clone(ap[0],CS);as=ap[1];if(!as){$s=-1;return new EY.ptr(HR.nil,0,0);}$s=-1;return $clone(ao,EY).Method(ar.Index);}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.MethodByName};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.MethodByName=function(an){return this.$val.MethodByName(an);};EY.ptr.prototype.NumField=function(){var an,ao;an=this;new EZ(an.flag).mustBe(25);ao=(an.typ.kindType);return ao.fields.$length;};EY.prototype.NumField=function(){return this.$val.NumField();};EY.ptr.prototype.OverflowComplex=function(an){var an,ao,ap,aq;ao=this;ap=new EZ(ao.flag).kind();aq=ap;if(aq===(15)){return FO(an.$real)||FO(an.$imag);}else if(aq===(16)){return false;}$panic(new FC.ptr(\"reflect.Value.OverflowComplex\",new EZ(ao.flag).kind()));};EY.prototype.OverflowComplex=function(an){return this.$val.OverflowComplex(an);};EY.ptr.prototype.OverflowFloat=function(an){var an,ao,ap,aq;ao=this;ap=new EZ(ao.flag).kind();aq=ap;if(aq===(13)){return FO(an);}else if(aq===(14)){return false;}$panic(new FC.ptr(\"reflect.Value.OverflowFloat\",new EZ(ao.flag).kind()));};EY.prototype.OverflowFloat=function(an){return this.$val.OverflowFloat(an);};FO=function(an){var an;if(an<0){an=-an;}return 3.4028234663852886e+38<an&&an<=1.7976931348623157e+308;};EY.ptr.prototype.OverflowInt=function(an){var an,ao,ap,aq,ar,as;ao=this;ap=new EZ(ao.flag).kind();aq=ap;if((aq===(2))||(aq===(3))||(aq===(4))||(aq===(5))||(aq===(6))){ar=$imul(ao.typ.size,8)>>>0;as=$shiftRightInt64(($shiftLeft64(an,((64-ar>>>0)))),((64-ar>>>0)));return!((an.$high===as.$high&&an.$low===as.$low));}$panic(new FC.ptr(\"reflect.Value.OverflowInt\",new EZ(ao.flag).kind()));};EY.prototype.OverflowInt=function(an){return this.$val.OverflowInt(an);};EY.ptr.prototype.OverflowUint=function(an){var an,ao,ap,aq,ar,as;ao=this;ap=new EZ(ao.flag).kind();aq=ap;if((aq===(7))||(aq===(12))||(aq===(8))||(aq===(9))||(aq===(10))||(aq===(11))){ar=$imul(ao.typ.size,8)>>>0;as=$shiftRightUint64(($shiftLeft64(an,((64-ar>>>0)))),((64-ar>>>0)));return!((an.$high===as.$high&&an.$low===as.$low));}$panic(new FC.ptr(\"reflect.Value.OverflowUint\",new EZ(ao.flag).kind()));};EY.prototype.OverflowUint=function(an){return this.$val.OverflowUint(an);};EY.ptr.prototype.Recv=function(){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=new EY.ptr(HR.nil,0,0);ao=false;ap=this;new EZ(ap.flag).mustBe(18);new EZ(ap.flag).mustBeExported();ar=$clone(ap,EY).recv(false);$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}aq=ar;an=aq[0];ao=aq[1];$s=-1;return[an,ao];}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Recv};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Recv=function(){return this.$val.Recv();};EY.ptr.prototype.recv=function(an){var an,ao,ap,aq,ar,as,at,au,av,aw,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=new EY.ptr(HR.nil,0,0);ap=false;aq=this;ar=(aq.typ.kindType);if((((ar.dir>>0))&1)===0){$panic(new $String(\"reflect: recv on send-only channel\"));}as=ar.elem;ao=new EY.ptr(as,0,((as.Kind()>>>0)));at=0;if(EV(as)){at=AL(as);ao.ptr=at;ao.flag=(ao.flag|(128))>>>0;}else{at=((ao.$ptr_ptr||(ao.$ptr_ptr=new JC(function(){return this.$target.ptr;},function($v){this.$target.ptr=$v;},ao))));}av=BP($clone(aq,EY).pointer(),an,at);$s=1;case 1:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}au=av;aw=au[0];ap=au[1];if(!aw){ao=new EY.ptr(HR.nil,0,0);}$s=-1;return[ao,ap];}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.recv};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.recv=function(an){return this.$val.recv(an);};EY.ptr.prototype.Send=function(an){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBe(18);new EZ(ao.flag).mustBeExported();ap=$clone(ao,EY).send($clone(an,EY),false);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}ap;$s=-1;return;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Send};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Send=function(an){return this.$val.Send(an);};EY.ptr.prototype.send=function(an,ao){var an,ao,ap,aq,ar,as,at,au,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=false;aq=this;ar=(aq.typ.kindType);if((((ar.dir>>0))&2)===0){$panic(new $String(\"reflect: send on recv-only channel\"));}new EZ(an.flag).mustBeExported();as=$clone(an,EY).assignTo(\"reflect.Value.Send\",ar.elem,0);$s=1;case 1:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}an=as;at=0;if(!((((an.flag&128)>>>0)===0))){at=an.ptr;}else{at=((an.$ptr_ptr||(an.$ptr_ptr=new JC(function(){return this.$target.ptr;},function($v){this.$target.ptr=$v;},an))));}au=BQ($clone(aq,EY).pointer(),at,ao);$s=2;case 2:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}ap=au;$s=-1;return ap;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.send};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.send=function(an,ao){return this.$val.send(an,ao);};EY.ptr.prototype.SetBool=function(an){var an,ao;ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(1);(ao.ptr).$set(an);};EY.prototype.SetBool=function(an){return this.$val.SetBool(an);};EY.ptr.prototype.setRunes=function(an){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(23);ap=ao.typ.Elem().Kind();$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}if(!((ap===5))){$s=1;continue;}$s=2;continue;case 1:$panic(new $String(\"reflect.Value.setRunes of non-rune slice\"));case 2:(ao.ptr).$set(an);$s=-1;return;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.setRunes};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.setRunes=function(an){return this.$val.setRunes(an);};EY.ptr.prototype.SetComplex=function(an){var an,ao,ap,aq;ao=this;new EZ(ao.flag).mustBeAssignable();ap=new EZ(ao.flag).kind();aq=ap;if(aq===(15)){(ao.ptr).$set((new $Complex64(an.$real,an.$imag)));}else if(aq===(16)){(ao.ptr).$set(an);}else{$panic(new FC.ptr(\"reflect.Value.SetComplex\",new EZ(ao.flag).kind()));}};EY.prototype.SetComplex=function(an){return this.$val.SetComplex(an);};EY.ptr.prototype.SetFloat=function(an){var an,ao,ap,aq;ao=this;new EZ(ao.flag).mustBeAssignable();ap=new EZ(ao.flag).kind();aq=ap;if(aq===(13)){(ao.ptr).$set(($fround(an)));}else if(aq===(14)){(ao.ptr).$set(an);}else{$panic(new FC.ptr(\"reflect.Value.SetFloat\",new EZ(ao.flag).kind()));}};EY.prototype.SetFloat=function(an){return this.$val.SetFloat(an);};EY.ptr.prototype.SetInt=function(an){var an,ao,ap,aq;ao=this;new EZ(ao.flag).mustBeAssignable();ap=new EZ(ao.flag).kind();aq=ap;if(aq===(2)){(ao.ptr).$set((((an.$low+((an.$high>>31)*4294967296))>>0)));}else if(aq===(3)){(ao.ptr).$set((((an.$low+((an.$high>>31)*4294967296))<<24>>24)));}else if(aq===(4)){(ao.ptr).$set((((an.$low+((an.$high>>31)*4294967296))<<16>>16)));}else if(aq===(5)){(ao.ptr).$set((((an.$low+((an.$high>>31)*4294967296))>>0)));}else if(aq===(6)){(ao.ptr).$set(an);}else{$panic(new FC.ptr(\"reflect.Value.SetInt\",new EZ(ao.flag).kind()));}};EY.prototype.SetInt=function(an){return this.$val.SetInt(an);};EY.ptr.prototype.SetMapIndex=function(an,ao){var an,ao,ap,aq,ar,as,at,au,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=this;new EZ(ap.flag).mustBe(21);new EZ(ap.flag).mustBeExported();new EZ(an.flag).mustBeExported();aq=(ap.typ.kindType);ar=$clone(an,EY).assignTo(\"reflect.Value.SetMapIndex\",aq.key,0);$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}an=ar;as=0;if(!((((an.flag&128)>>>0)===0))){as=an.ptr;}else{as=((an.$ptr_ptr||(an.$ptr_ptr=new JC(function(){return this.$target.ptr;},function($v){this.$target.ptr=$v;},an))));}if(ao.typ===HR.nil){AV(ap.typ,$clone(ap,EY).pointer(),as);$s=-1;return;}new EZ(ao.flag).mustBeExported();at=$clone(ao,EY).assignTo(\"reflect.Value.SetMapIndex\",aq.elem,0);$s=2;case 2:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}ao=at;au=0;if(!((((ao.flag&128)>>>0)===0))){au=ao.ptr;}else{au=((ao.$ptr_ptr||(ao.$ptr_ptr=new JC(function(){return this.$target.ptr;},function($v){this.$target.ptr=$v;},ao))));}$r=AU(ap.typ,$clone(ap,EY).pointer(),as,au);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.SetMapIndex};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.SetMapIndex=function(an,ao){return this.$val.SetMapIndex(an,ao);};EY.ptr.prototype.SetUint=function(an){var an,ao,ap,aq;ao=this;new EZ(ao.flag).mustBeAssignable();ap=new EZ(ao.flag).kind();aq=ap;if(aq===(7)){(ao.ptr).$set(((an.$low>>>0)));}else if(aq===(8)){(ao.ptr).$set(((an.$low<<24>>>24)));}else if(aq===(9)){(ao.ptr).$set(((an.$low<<16>>>16)));}else if(aq===(10)){(ao.ptr).$set(((an.$low>>>0)));}else if(aq===(11)){(ao.ptr).$set(an);}else if(aq===(12)){(ao.ptr).$set(((an.$low>>>0)));}else{$panic(new FC.ptr(\"reflect.Value.SetUint\",new EZ(ao.flag).kind()));}};EY.prototype.SetUint=function(an){return this.$val.SetUint(an);};EY.ptr.prototype.SetPointer=function(an){var an,ao;ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(26);(ao.ptr).$set(an);};EY.prototype.SetPointer=function(an){return this.$val.SetPointer(an);};EY.ptr.prototype.SetString=function(an){var an,ao;ao=this;new EZ(ao.flag).mustBeAssignable();new EZ(ao.flag).mustBe(24);(ao.ptr).$set(an);};EY.prototype.SetString=function(an){return this.$val.SetString(an);};EY.ptr.prototype.String=function(){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=this;ao=new EZ(an.flag).kind();ap=ao;if(ap===(0)){$s=-1;return\"<invalid Value>\";}else if(ap===(24)){$s=-1;return(an.ptr).$get();}aq=$clone(an,EY).Type().String();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return\"<\"+aq+\" Value>\";}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.String};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.String=function(){return this.$val.String();};EY.ptr.prototype.TryRecv=function(){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:an=new EY.ptr(HR.nil,0,0);ao=false;ap=this;new EZ(ap.flag).mustBe(18);new EZ(ap.flag).mustBeExported();ar=$clone(ap,EY).recv(true);$s=1;case 1:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}aq=ar;an=aq[0];ao=aq[1];$s=-1;return[an,ao];}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.TryRecv};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.TryRecv=function(){return this.$val.TryRecv();};EY.ptr.prototype.TrySend=function(an){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;new EZ(ao.flag).mustBe(18);new EZ(ao.flag).mustBeExported();ap=$clone(ao,EY).send($clone(an,EY),true);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.TrySend};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.TrySend=function(an){return this.$val.TrySend(an);};EY.ptr.prototype.Type=function(){var an,ao,ap,aq,ar,as,at,au;an=this;ao=an.flag;if(ao===0){$panic(new FC.ptr(\"reflect.Value.Type\",0));}if(((ao&512)>>>0)===0){return an.typ;}ap=((an.flag>>0))>>10>>0;if(an.typ.Kind()===20){aq=(an.typ.kindType);if(((ap>>>0))>=((aq.methods.$length>>>0))){$panic(new $String(\"reflect: internal error: invalid method index\"));}as=(ar=aq.methods,((ap<0||ap>=ar.$length)?($throwRuntimeError(\"index out of range\"),undefined):ar.$array[ar.$offset+ap]));return an.typ.typeOff(as.typ);}at=an.typ.exportedMethods();if(((ap>>>0))>=((at.$length>>>0))){$panic(new $String(\"reflect: internal error: invalid method index\"));}au=$clone(((ap<0||ap>=at.$length)?($throwRuntimeError(\"index out of range\"),undefined):at.$array[at.$offset+ap]),CG);return an.typ.typeOff(au.mtyp);};EY.prototype.Type=function(){return this.$val.Type();};EY.ptr.prototype.Uint=function(){var an,ao,ap,aq,ar;an=this;ao=new EZ(an.flag).kind();ap=an.ptr;aq=ao;if(aq===(7)){return(new $Uint64(0,(ap).$get()));}else if(aq===(8)){return(new $Uint64(0,(ap).$get()));}else if(aq===(9)){return(new $Uint64(0,(ap).$get()));}else if(aq===(10)){return(new $Uint64(0,(ap).$get()));}else if(aq===(11)){return(ap).$get();}else if(aq===(12)){return((ar=(ap).$get(),new $Uint64(0,ar.constructor===Number?ar:1)));}$panic(new FC.ptr(\"reflect.Value.Uint\",new EZ(an.flag).kind()));};EY.prototype.Uint=function(){return this.$val.Uint();};EY.ptr.prototype.UnsafeAddr=function(){var an;an=this;if(an.typ===HR.nil){$panic(new FC.ptr(\"reflect.Value.UnsafeAddr\",0));}if(((an.flag&256)>>>0)===0){$panic(new $String(\"reflect.Value.UnsafeAddr of unaddressable value\"));}return(an.ptr);};EY.prototype.UnsafeAddr=function(){return this.$val.UnsafeAddr();};GG=function(an){var an,ao,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(!(($clone(an,EY).Kind()===22))){$s=-1;return an;}ao=$clone(an,EY).Elem();$s=1;case 1:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}$s=-1;return ao;}return;}if($f===undefined){$f={$blk:GG};}$f.an=an;$f.ao=ao;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Indirect=GG;GH=function(an){var an,ao,ap,aq;if($interfaceIsEqual(an,$ifaceNil)){$panic(new $String(\"reflect: New(nil)\"));}ao=$assertType(an,HR);ap=AL(ao);aq=22;return new EY.ptr(ao.ptrTo(),ap,aq);};$pkg.New=GH;EY.ptr.prototype.Convert=function(an){var an,ao,ap,aq,ar,as,at,au,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ao=this;if(!((((ao.flag&512)>>>0)===0))){$s=1;continue;}$s=2;continue;case 1:ap=BI(\"Convert\",$clone(ao,EY));$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}ao=ap;case 2:aq=an.common();$s=4;case 4:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=GJ(aq,ao.typ);$s=5;case 5:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=ar;if(as===$throwNilPointerError){$s=6;continue;}$s=7;continue;case 6:at=an.String();$s=8;case 8:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$panic(new $String(\"reflect.Value.Convert: value of type \"+ao.typ.String()+\" cannot be converted to type \"+at));case 7:au=as($clone(ao,EY),an);$s=9;case 9:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}$s=-1;return au;}return;}if($f===undefined){$f={$blk:EY.ptr.prototype.Convert};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.$s=$s;$f.$r=$r;return $f;};EY.prototype.Convert=function(an){return this.$val.Convert(an);};GJ=function(an,ao){var an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=ao.Kind();if((ap===(2))||(ap===(3))||(ap===(4))||(ap===(5))||(ap===(6))){$s=2;continue;}if((ap===(7))||(ap===(8))||(ap===(9))||(ap===(10))||(ap===(11))||(ap===(12))){$s=3;continue;}if((ap===(13))||(ap===(14))){$s=4;continue;}if((ap===(15))||(ap===(16))){$s=5;continue;}if(ap===(24)){$s=6;continue;}if(ap===(23)){$s=7;continue;}$s=8;continue;case 2:aq=an.Kind();if((aq===(2))||(aq===(3))||(aq===(4))||(aq===(5))||(aq===(6))||(aq===(7))||(aq===(8))||(aq===(9))||(aq===(10))||(aq===(11))||(aq===(12))){$s=-1;return GP;}else if((aq===(13))||(aq===(14))){$s=-1;return GT;}else if(aq===(24)){$s=-1;return GX;}$s=8;continue;case 3:ar=an.Kind();if((ar===(2))||(ar===(3))||(ar===(4))||(ar===(5))||(ar===(6))||(ar===(7))||(ar===(8))||(ar===(9))||(ar===(10))||(ar===(11))||(ar===(12))){$s=-1;return GQ;}else if((ar===(13))||(ar===(14))){$s=-1;return GU;}else if(ar===(24)){$s=-1;return GY;}$s=8;continue;case 4:as=an.Kind();if((as===(2))||(as===(3))||(as===(4))||(as===(5))||(as===(6))){$s=-1;return GR;}else if((as===(7))||(as===(8))||(as===(9))||(as===(10))||(as===(11))||(as===(12))){$s=-1;return GS;}else if((as===(13))||(as===(14))){$s=-1;return GV;}$s=8;continue;case 5:at=an.Kind();if((at===(15))||(at===(16))){$s=-1;return GW;}$s=8;continue;case 6:if(!(an.Kind()===23)){au=false;$s=11;continue s;}av=an.Elem().PkgPath();$s=12;case 12:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}au=av===\"\";case 11:if(au){$s=9;continue;}$s=10;continue;case 9:aw=an.Elem().Kind();$s=14;case 14:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}ax=aw;if(ax===(8)){$s=-1;return HA;}else if(ax===(5)){$s=-1;return HC;}case 13:case 10:$s=8;continue;case 7:if(!(an.Kind()===24)){ay=false;$s=17;continue s;}az=ao.Elem().PkgPath();$s=18;case 18:if($c){$c=false;az=az.$blk();}if(az&&az.$blk!==undefined){break s;}ay=az===\"\";case 17:if(ay){$s=15;continue;}$s=16;continue;case 15:ba=ao.Elem().Kind();$s=20;case 20:if($c){$c=false;ba=ba.$blk();}if(ba&&ba.$blk!==undefined){break s;}bb=ba;if(bb===(8)){$s=-1;return GZ;}else if(bb===(5)){$s=-1;return HB;}case 19:case 16:case 8:case 1:bc=DP(an,ao,false);$s=23;case 23:if($c){$c=false;bc=bc.$blk();}if(bc&&bc.$blk!==undefined){break s;}if(bc){$s=21;continue;}$s=22;continue;case 21:$s=-1;return BC;case 22:if(!((an.Kind()===22)&&an.Name()===\"\"&&(ao.Kind()===22)&&ao.Name()===\"\")){bd=false;$s=26;continue s;}be=an.Elem().common();$s=27;case 27:if($c){$c=false;be=be.$blk();}if(be&&be.$blk!==undefined){break s;}bf=be;bg=ao.Elem().common();$s=28;case 28:if($c){$c=false;bg=bg.$blk();}if(bg&&bg.$blk!==undefined){break s;}bh=bg;bi=DP(bf,bh,false);$s=29;case 29:if($c){$c=false;bi=bi.$blk();}if(bi&&bi.$blk!==undefined){break s;}bd=bi;case 26:if(bd){$s=24;continue;}$s=25;continue;case 24:$s=-1;return BC;case 25:if(DM(an,ao)){if(ao.Kind()===20){$s=-1;return HE;}$s=-1;return HD;}$s=-1;return $throwNilPointerError;}return;}if($f===undefined){$f={$blk:GJ};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.$s=$s;$f.$r=$r;return $f;};GK=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=ap.common();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;as=AL(ar);at=ar.size;if(at===(4)){(as).$set(($fround(ao)));}else if(at===(8)){(as).$set(ao);}$s=-1;return new EY.ptr(ar,as,(((an|128)>>>0)|((ar.Kind()>>>0)))>>>0);}return;}if($f===undefined){$f={$blk:GK};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};GL=function(an,ao,ap){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=ap.common();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;as=AL(ar);at=ar.size;if(at===(8)){(as).$set((new $Complex64(ao.$real,ao.$imag)));}else if(at===(16)){(as).$set(ao);}$s=-1;return new EY.ptr(ar,as,(((an|128)>>>0)|((ar.Kind()>>>0)))>>>0);}return;}if($f===undefined){$f={$blk:GL};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};GM=function(an,ao,ap){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=$clone(GH(ap),EY).Elem();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;$clone(ar,EY).SetString(ao);ar.flag=(((ar.flag&~256)>>>0)|an)>>>0;$s=-1;return ar;}return;}if($f===undefined){$f={$blk:GM};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};GN=function(an,ao,ap){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=$clone(GH(ap),EY).Elem();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;$r=$clone(ar,EY).SetBytes(ao);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}ar.flag=(((ar.flag&~256)>>>0)|an)>>>0;$s=-1;return ar;}return;}if($f===undefined){$f={$blk:GN};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};GO=function(an,ao,ap){var an,ao,ap,aq,ar,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=$clone(GH(ap),EY).Elem();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;$r=$clone(ar,EY).setRunes(ao);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}ar.flag=(((ar.flag&~256)>>>0)|an)>>>0;$s=-1;return ar;}return;}if($f===undefined){$f={$blk:GO};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.$s=$s;$f.$r=$r;return $f;};GP=function(an,ao){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=AM(new EZ(an.flag).ro(),((ap=$clone(an,EY).Int(),new $Uint64(ap.$high,ap.$low))),ao);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq;}return;}if($f===undefined){$f={$blk:GP};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};GQ=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=AM(new EZ(an.flag).ro(),$clone(an,EY).Uint(),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GQ};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GR=function(an,ao){var an,ao,ap,aq,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:aq=AM(new EZ(an.flag).ro(),((ap=(new $Int64(0,$clone(an,EY).Float())),new $Uint64(ap.$high,ap.$low))),ao);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}$s=-1;return aq;}return;}if($f===undefined){$f={$blk:GR};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.$s=$s;$f.$r=$r;return $f;};GS=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=AM(new EZ(an.flag).ro(),(new $Uint64(0,$clone(an,EY).Float())),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GS};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GT=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=GK(new EZ(an.flag).ro(),($flatten64($clone(an,EY).Int())),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GT};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GU=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=GK(new EZ(an.flag).ro(),($flatten64($clone(an,EY).Uint())),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GU};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GV=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=GK(new EZ(an.flag).ro(),$clone(an,EY).Float(),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GV};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GW=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=GL(new EZ(an.flag).ro(),$clone(an,EY).Complex(),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GW};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GX=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=GM(new EZ(an.flag).ro(),($encodeRune($clone(an,EY).Int().$low)),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GX};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GY=function(an,ao){var an,ao,ap,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=GM(new EZ(an.flag).ro(),($encodeRune($clone(an,EY).Uint().$low)),ao);$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}$s=-1;return ap;}return;}if($f===undefined){$f={$blk:GY};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.$s=$s;$f.$r=$r;return $f;};GZ=function(an,ao){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=new EZ(an.flag).ro();aq=$clone(an,EY).Bytes();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=($bytesToString(aq));as=ao;at=GM(ap,ar,as);$s=2;case 2:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return at;}return;}if($f===undefined){$f={$blk:GZ};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};HA=function(an,ao){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=new EZ(an.flag).ro();aq=$clone(an,EY).String();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=(new IU($stringToBytes(aq)));as=ao;at=GN(ap,ar,as);$s=2;case 2:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return at;}return;}if($f===undefined){$f={$blk:HA};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};HB=function(an,ao){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=new EZ(an.flag).ro();aq=$clone(an,EY).runes();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=($runesToString(aq));as=ao;at=GM(ap,ar,as);$s=2;case 2:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return at;}return;}if($f===undefined){$f={$blk:HB};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};HC=function(an,ao){var an,ao,ap,aq,ar,as,at,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=new EZ(an.flag).ro();aq=$clone(an,EY).String();$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=(new JE($stringToRunes(aq)));as=ao;at=GO(ap,ar,as);$s=2;case 2:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}$s=-1;return at;}return;}if($f===undefined){$f={$blk:HC};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.$s=$s;$f.$r=$r;return $f;};HD=function(an,ao){var an,ao,ap,aq,ar,as,at,au,av,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:ap=ao.common();$s=1;case 1:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}aq=AL(ap);$s=2;case 2:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;as=BF($clone(an,EY),false);$s=3;case 3:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}at=as;au=ao.NumMethod();$s=7;case 7:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}if(au===0){$s=4;continue;}$s=5;continue;case 4:(ar).$set(at);$s=6;continue;case 5:BG($assertType(ao,HR),at,ar);case 6:av=ao.common();$s=8;case 8:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}$s=-1;return new EY.ptr(av,ar,(((new EZ(an.flag).ro()|128)>>>0)|20)>>>0);}return;}if($f===undefined){$f={$blk:HD};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.$s=$s;$f.$r=$r;return $f;};HE=function(an,ao){var an,ao,ap,aq,ar,as,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if($clone(an,EY).IsNil()){$s=1;continue;}$s=2;continue;case 1:ap=AK(ao);$s=3;case 3:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}aq=ap;aq.flag=(aq.flag|(new EZ(an.flag).ro()))>>>0;$s=-1;return aq;case 2:ar=$clone(an,EY).Elem();$s=4;case 4:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=HD($clone(ar,EY),ao);$s=5;case 5:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}$s=-1;return as;}return;}if($f===undefined){$f={$blk:HE};}$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.$s=$s;$f.$r=$r;return $f;};IE.methods=[{prop:\"methods\",name:\"methods\",pkg:\"reflect\",typ:$funcType([],[IB],false)},{prop:\"exportedMethods\",name:\"exportedMethods\",pkg:\"reflect\",typ:$funcType([],[IB],false)}];IK.methods=[{prop:\"in$\",name:\"in\",pkg:\"reflect\",typ:$funcType([],[HS],false)},{prop:\"out\",name:\"out\",pkg:\"reflect\",typ:$funcType([],[HS],false)}];Q.methods=[{prop:\"name\",name:\"name\",pkg:\"reflect\",typ:$funcType([],[$String],false)},{prop:\"tag\",name:\"tag\",pkg:\"reflect\",typ:$funcType([],[$String],false)},{prop:\"pkgPath\",name:\"pkgPath\",pkg:\"reflect\",typ:$funcType([],[$String],false)},{prop:\"isExported\",name:\"isExported\",pkg:\"reflect\",typ:$funcType([],[$Bool],false)},{prop:\"data\",name:\"data\",pkg:\"reflect\",typ:$funcType([$Int,$String],[IA],false)},{prop:\"nameLen\",name:\"nameLen\",pkg:\"reflect\",typ:$funcType([],[$Int],false)},{prop:\"tagLen\",name:\"tagLen\",pkg:\"reflect\",typ:$funcType([],[$Int],false)}];IJ.methods=[{prop:\"skipUntilValidKey\",name:\"skipUntilValidKey\",pkg:\"reflect\",typ:$funcType([],[],false)}];CC.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];HR.methods=[{prop:\"uncommon\",name:\"uncommon\",pkg:\"reflect\",typ:$funcType([],[IE],false)},{prop:\"nameOff\",name:\"nameOff\",pkg:\"reflect\",typ:$funcType([DB],[Q],false)},{prop:\"typeOff\",name:\"typeOff\",pkg:\"reflect\",typ:$funcType([DC],[HR],false)},{prop:\"ptrTo\",name:\"ptrTo\",pkg:\"reflect\",typ:$funcType([],[HR],false)},{prop:\"pointers\",name:\"pointers\",pkg:\"reflect\",typ:$funcType([],[$Bool],false)},{prop:\"Comparable\",name:\"Comparable\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Method\",name:\"Method\",pkg:\"\",typ:$funcType([$Int],[CS],false)},{prop:\"textOff\",name:\"textOff\",pkg:\"reflect\",typ:$funcType([DD],[$UnsafePointer],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Uintptr],false)},{prop:\"Bits\",name:\"Bits\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Align\",name:\"Align\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"FieldAlign\",name:\"FieldAlign\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Kind\",name:\"Kind\",pkg:\"\",typ:$funcType([],[CC],false)},{prop:\"common\",name:\"common\",pkg:\"reflect\",typ:$funcType([],[HR],false)},{prop:\"exportedMethods\",name:\"exportedMethods\",pkg:\"reflect\",typ:$funcType([],[IB],false)},{prop:\"NumMethod\",name:\"NumMethod\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"MethodByName\",name:\"MethodByName\",pkg:\"\",typ:$funcType([$String],[CS,$Bool],false)},{prop:\"PkgPath\",name:\"PkgPath\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Name\",name:\"Name\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"ChanDir\",name:\"ChanDir\",pkg:\"\",typ:$funcType([],[CH],false)},{prop:\"IsVariadic\",name:\"IsVariadic\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Elem\",name:\"Elem\",pkg:\"\",typ:$funcType([],[CB],false)},{prop:\"Field\",name:\"Field\",pkg:\"\",typ:$funcType([$Int],[DG],false)},{prop:\"FieldByIndex\",name:\"FieldByIndex\",pkg:\"\",typ:$funcType([IR],[DG],false)},{prop:\"FieldByName\",name:\"FieldByName\",pkg:\"\",typ:$funcType([$String],[DG,$Bool],false)},{prop:\"FieldByNameFunc\",name:\"FieldByNameFunc\",pkg:\"\",typ:$funcType([JG],[DG,$Bool],false)},{prop:\"In\",name:\"In\",pkg:\"\",typ:$funcType([$Int],[CB],false)},{prop:\"Key\",name:\"Key\",pkg:\"\",typ:$funcType([],[CB],false)},{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"NumField\",name:\"NumField\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"NumIn\",name:\"NumIn\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"NumOut\",name:\"NumOut\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Out\",name:\"Out\",pkg:\"\",typ:$funcType([$Int],[CB],false)},{prop:\"Implements\",name:\"Implements\",pkg:\"\",typ:$funcType([CB],[$Bool],false)},{prop:\"AssignableTo\",name:\"AssignableTo\",pkg:\"\",typ:$funcType([CB],[$Bool],false)},{prop:\"ConvertibleTo\",name:\"ConvertibleTo\",pkg:\"\",typ:$funcType([CB],[$Bool],false)}];CH.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];IP.methods=[{prop:\"Method\",name:\"Method\",pkg:\"\",typ:$funcType([$Int],[CS],false)},{prop:\"NumMethod\",name:\"NumMethod\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"MethodByName\",name:\"MethodByName\",pkg:\"\",typ:$funcType([$String],[CS,$Bool],false)}];JJ.methods=[{prop:\"offset\",name:\"offset\",pkg:\"reflect\",typ:$funcType([],[$Uintptr],false)},{prop:\"embedded\",name:\"embedded\",pkg:\"reflect\",typ:$funcType([],[$Bool],false)}];IT.methods=[{prop:\"Field\",name:\"Field\",pkg:\"\",typ:$funcType([$Int],[DG],false)},{prop:\"FieldByIndex\",name:\"FieldByIndex\",pkg:\"\",typ:$funcType([IR],[DG],false)},{prop:\"FieldByNameFunc\",name:\"FieldByNameFunc\",pkg:\"\",typ:$funcType([JG],[DG,$Bool],false)},{prop:\"FieldByName\",name:\"FieldByName\",pkg:\"\",typ:$funcType([$String],[DG,$Bool],false)}];DH.methods=[{prop:\"Get\",name:\"Get\",pkg:\"\",typ:$funcType([$String],[$String],false)},{prop:\"Lookup\",name:\"Lookup\",pkg:\"\",typ:$funcType([$String],[$String,$Bool],false)}];EY.methods=[{prop:\"object\",name:\"object\",pkg:\"reflect\",typ:$funcType([],[HW],false)},{prop:\"assignTo\",name:\"assignTo\",pkg:\"reflect\",typ:$funcType([$String,HR,$UnsafePointer],[EY],false)},{prop:\"call\",name:\"call\",pkg:\"reflect\",typ:$funcType([$String,II],[II],false)},{prop:\"Cap\",name:\"Cap\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Elem\",name:\"Elem\",pkg:\"\",typ:$funcType([],[EY],false)},{prop:\"Field\",name:\"Field\",pkg:\"\",typ:$funcType([$Int],[EY],false)},{prop:\"Index\",name:\"Index\",pkg:\"\",typ:$funcType([$Int],[EY],false)},{prop:\"InterfaceData\",name:\"InterfaceData\",pkg:\"\",typ:$funcType([],[JQ],false)},{prop:\"IsNil\",name:\"IsNil\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Pointer\",name:\"Pointer\",pkg:\"\",typ:$funcType([],[$Uintptr],false)},{prop:\"Set\",name:\"Set\",pkg:\"\",typ:$funcType([EY],[],false)},{prop:\"SetBytes\",name:\"SetBytes\",pkg:\"\",typ:$funcType([IU],[],false)},{prop:\"SetCap\",name:\"SetCap\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"SetLen\",name:\"SetLen\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"Slice\",name:\"Slice\",pkg:\"\",typ:$funcType([$Int,$Int],[EY],false)},{prop:\"Slice3\",name:\"Slice3\",pkg:\"\",typ:$funcType([$Int,$Int,$Int],[EY],false)},{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"pointer\",name:\"pointer\",pkg:\"reflect\",typ:$funcType([],[$UnsafePointer],false)},{prop:\"Addr\",name:\"Addr\",pkg:\"\",typ:$funcType([],[EY],false)},{prop:\"Bool\",name:\"Bool\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Bytes\",name:\"Bytes\",pkg:\"\",typ:$funcType([],[IU],false)},{prop:\"runes\",name:\"runes\",pkg:\"reflect\",typ:$funcType([],[JE],false)},{prop:\"CanAddr\",name:\"CanAddr\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"CanSet\",name:\"CanSet\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Call\",name:\"Call\",pkg:\"\",typ:$funcType([II],[II],false)},{prop:\"CallSlice\",name:\"CallSlice\",pkg:\"\",typ:$funcType([II],[II],false)},{prop:\"Complex\",name:\"Complex\",pkg:\"\",typ:$funcType([],[$Complex128],false)},{prop:\"FieldByIndex\",name:\"FieldByIndex\",pkg:\"\",typ:$funcType([IR],[EY],false)},{prop:\"FieldByName\",name:\"FieldByName\",pkg:\"\",typ:$funcType([$String],[EY],false)},{prop:\"FieldByNameFunc\",name:\"FieldByNameFunc\",pkg:\"\",typ:$funcType([JG],[EY],false)},{prop:\"Float\",name:\"Float\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Int\",name:\"Int\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"CanInterface\",name:\"CanInterface\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Interface\",name:\"Interface\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)},{prop:\"IsValid\",name:\"IsValid\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Kind\",name:\"Kind\",pkg:\"\",typ:$funcType([],[CC],false)},{prop:\"MapIndex\",name:\"MapIndex\",pkg:\"\",typ:$funcType([EY],[EY],false)},{prop:\"MapKeys\",name:\"MapKeys\",pkg:\"\",typ:$funcType([],[II],false)},{prop:\"MapRange\",name:\"MapRange\",pkg:\"\",typ:$funcType([],[JR],false)},{prop:\"Method\",name:\"Method\",pkg:\"\",typ:$funcType([$Int],[EY],false)},{prop:\"NumMethod\",name:\"NumMethod\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"MethodByName\",name:\"MethodByName\",pkg:\"\",typ:$funcType([$String],[EY],false)},{prop:\"NumField\",name:\"NumField\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"OverflowComplex\",name:\"OverflowComplex\",pkg:\"\",typ:$funcType([$Complex128],[$Bool],false)},{prop:\"OverflowFloat\",name:\"OverflowFloat\",pkg:\"\",typ:$funcType([$Float64],[$Bool],false)},{prop:\"OverflowInt\",name:\"OverflowInt\",pkg:\"\",typ:$funcType([$Int64],[$Bool],false)},{prop:\"OverflowUint\",name:\"OverflowUint\",pkg:\"\",typ:$funcType([$Uint64],[$Bool],false)},{prop:\"Recv\",name:\"Recv\",pkg:\"\",typ:$funcType([],[EY,$Bool],false)},{prop:\"recv\",name:\"recv\",pkg:\"reflect\",typ:$funcType([$Bool],[EY,$Bool],false)},{prop:\"Send\",name:\"Send\",pkg:\"\",typ:$funcType([EY],[],false)},{prop:\"send\",name:\"send\",pkg:\"reflect\",typ:$funcType([EY,$Bool],[$Bool],false)},{prop:\"SetBool\",name:\"SetBool\",pkg:\"\",typ:$funcType([$Bool],[],false)},{prop:\"setRunes\",name:\"setRunes\",pkg:\"reflect\",typ:$funcType([JE],[],false)},{prop:\"SetComplex\",name:\"SetComplex\",pkg:\"\",typ:$funcType([$Complex128],[],false)},{prop:\"SetFloat\",name:\"SetFloat\",pkg:\"\",typ:$funcType([$Float64],[],false)},{prop:\"SetInt\",name:\"SetInt\",pkg:\"\",typ:$funcType([$Int64],[],false)},{prop:\"SetMapIndex\",name:\"SetMapIndex\",pkg:\"\",typ:$funcType([EY,EY],[],false)},{prop:\"SetUint\",name:\"SetUint\",pkg:\"\",typ:$funcType([$Uint64],[],false)},{prop:\"SetPointer\",name:\"SetPointer\",pkg:\"\",typ:$funcType([$UnsafePointer],[],false)},{prop:\"SetString\",name:\"SetString\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"TryRecv\",name:\"TryRecv\",pkg:\"\",typ:$funcType([],[EY,$Bool],false)},{prop:\"TrySend\",name:\"TrySend\",pkg:\"\",typ:$funcType([EY],[$Bool],false)},{prop:\"Type\",name:\"Type\",pkg:\"\",typ:$funcType([],[CB],false)},{prop:\"Uint\",name:\"Uint\",pkg:\"\",typ:$funcType([],[$Uint64],false)},{prop:\"UnsafeAddr\",name:\"UnsafeAddr\",pkg:\"\",typ:$funcType([],[$Uintptr],false)},{prop:\"Convert\",name:\"Convert\",pkg:\"\",typ:$funcType([CB],[EY],false)}];EZ.methods=[{prop:\"kind\",name:\"kind\",pkg:\"reflect\",typ:$funcType([],[CC],false)},{prop:\"ro\",name:\"ro\",pkg:\"reflect\",typ:$funcType([],[EZ],false)},{prop:\"mustBe\",name:\"mustBe\",pkg:\"reflect\",typ:$funcType([CC],[],false)},{prop:\"mustBeExported\",name:\"mustBeExported\",pkg:\"reflect\",typ:$funcType([],[],false)},{prop:\"mustBeAssignable\",name:\"mustBeAssignable\",pkg:\"reflect\",typ:$funcType([],[],false)}];JS.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];JR.methods=[{prop:\"Key\",name:\"Key\",pkg:\"\",typ:$funcType([],[EY],false)},{prop:\"Value\",name:\"Value\",pkg:\"\",typ:$funcType([],[EY],false)},{prop:\"Next\",name:\"Next\",pkg:\"\",typ:$funcType([],[$Bool],false)}];N.init(\"reflect\",[{prop:\"pkgPath\",name:\"pkgPath\",embedded:false,exported:false,typ:DB,tag:\"\"},{prop:\"mcount\",name:\"mcount\",embedded:false,exported:false,typ:$Uint16,tag:\"\"},{prop:\"xcount\",name:\"xcount\",embedded:false,exported:false,typ:$Uint16,tag:\"\"},{prop:\"moff\",name:\"moff\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"_methods\",name:\"_methods\",embedded:false,exported:false,typ:IB,tag:\"\"}]);P.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"reflect:\\\"func\\\"\"},{prop:\"inCount\",name:\"inCount\",embedded:false,exported:false,typ:$Uint16,tag:\"\"},{prop:\"outCount\",name:\"outCount\",embedded:false,exported:false,typ:$Uint16,tag:\"\"},{prop:\"_in\",name:\"_in\",embedded:false,exported:false,typ:HS,tag:\"\"},{prop:\"_out\",name:\"_out\",embedded:false,exported:false,typ:HS,tag:\"\"}]);Q.init(\"reflect\",[{prop:\"bytes\",name:\"bytes\",embedded:false,exported:false,typ:IA,tag:\"\"}]);R.init(\"reflect\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"tag\",name:\"tag\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"exported\",name:\"exported\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);AW.init(\"reflect\",[{prop:\"t\",name:\"t\",embedded:false,exported:false,typ:CB,tag:\"\"},{prop:\"m\",name:\"m\",embedded:false,exported:false,typ:HW,tag:\"\"},{prop:\"keys\",name:\"keys\",embedded:false,exported:false,typ:HW,tag:\"\"},{prop:\"i\",name:\"i\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"last\",name:\"last\",embedded:false,exported:false,typ:HW,tag:\"\"}]);CB.init([{prop:\"Align\",name:\"Align\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"AssignableTo\",name:\"AssignableTo\",pkg:\"\",typ:$funcType([CB],[$Bool],false)},{prop:\"Bits\",name:\"Bits\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"ChanDir\",name:\"ChanDir\",pkg:\"\",typ:$funcType([],[CH],false)},{prop:\"Comparable\",name:\"Comparable\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"ConvertibleTo\",name:\"ConvertibleTo\",pkg:\"\",typ:$funcType([CB],[$Bool],false)},{prop:\"Elem\",name:\"Elem\",pkg:\"\",typ:$funcType([],[CB],false)},{prop:\"Field\",name:\"Field\",pkg:\"\",typ:$funcType([$Int],[DG],false)},{prop:\"FieldAlign\",name:\"FieldAlign\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"FieldByIndex\",name:\"FieldByIndex\",pkg:\"\",typ:$funcType([IR],[DG],false)},{prop:\"FieldByName\",name:\"FieldByName\",pkg:\"\",typ:$funcType([$String],[DG,$Bool],false)},{prop:\"FieldByNameFunc\",name:\"FieldByNameFunc\",pkg:\"\",typ:$funcType([JG],[DG,$Bool],false)},{prop:\"Implements\",name:\"Implements\",pkg:\"\",typ:$funcType([CB],[$Bool],false)},{prop:\"In\",name:\"In\",pkg:\"\",typ:$funcType([$Int],[CB],false)},{prop:\"IsVariadic\",name:\"IsVariadic\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Key\",name:\"Key\",pkg:\"\",typ:$funcType([],[CB],false)},{prop:\"Kind\",name:\"Kind\",pkg:\"\",typ:$funcType([],[CC],false)},{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Method\",name:\"Method\",pkg:\"\",typ:$funcType([$Int],[CS],false)},{prop:\"MethodByName\",name:\"MethodByName\",pkg:\"\",typ:$funcType([$String],[CS,$Bool],false)},{prop:\"Name\",name:\"Name\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"NumField\",name:\"NumField\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"NumIn\",name:\"NumIn\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"NumMethod\",name:\"NumMethod\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"NumOut\",name:\"NumOut\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Out\",name:\"Out\",pkg:\"\",typ:$funcType([$Int],[CB],false)},{prop:\"PkgPath\",name:\"PkgPath\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Uintptr],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"common\",name:\"common\",pkg:\"reflect\",typ:$funcType([],[HR],false)},{prop:\"uncommon\",name:\"uncommon\",pkg:\"reflect\",typ:$funcType([],[IE],false)}]);CE.init(\"reflect\",[{prop:\"size\",name:\"size\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"},{prop:\"ptrdata\",name:\"ptrdata\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"},{prop:\"hash\",name:\"hash\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"tflag\",name:\"tflag\",embedded:false,exported:false,typ:CD,tag:\"\"},{prop:\"align\",name:\"align\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"fieldAlign\",name:\"fieldAlign\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"kind\",name:\"kind\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"alg\",name:\"alg\",embedded:false,exported:false,typ:HZ,tag:\"\"},{prop:\"gcdata\",name:\"gcdata\",embedded:false,exported:false,typ:IA,tag:\"\"},{prop:\"str\",name:\"str\",embedded:false,exported:false,typ:DB,tag:\"\"},{prop:\"ptrToThis\",name:\"ptrToThis\",embedded:false,exported:false,typ:DC,tag:\"\"}]);CF.init(\"reflect\",[{prop:\"hash\",name:\"hash\",embedded:false,exported:false,typ:JH,tag:\"\"},{prop:\"equal\",name:\"equal\",embedded:false,exported:false,typ:JI,tag:\"\"}]);CG.init(\"reflect\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:DB,tag:\"\"},{prop:\"mtyp\",name:\"mtyp\",embedded:false,exported:false,typ:DC,tag:\"\"},{prop:\"ifn\",name:\"ifn\",embedded:false,exported:false,typ:DD,tag:\"\"},{prop:\"tfn\",name:\"tfn\",embedded:false,exported:false,typ:DD,tag:\"\"}]);CI.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"elem\",name:\"elem\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"slice\",name:\"slice\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"len\",name:\"len\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"}]);CJ.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"elem\",name:\"elem\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"dir\",name:\"dir\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"}]);CK.init(\"reflect\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:DB,tag:\"\"},{prop:\"typ\",name:\"typ\",embedded:false,exported:false,typ:DC,tag:\"\"}]);CL.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"pkgPath\",name:\"pkgPath\",embedded:false,exported:false,typ:Q,tag:\"\"},{prop:\"methods\",name:\"methods\",embedded:false,exported:false,typ:IC,tag:\"\"}]);CM.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"key\",name:\"key\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"elem\",name:\"elem\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"bucket\",name:\"bucket\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"keysize\",name:\"keysize\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"valuesize\",name:\"valuesize\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"bucketsize\",name:\"bucketsize\",embedded:false,exported:false,typ:$Uint16,tag:\"\"},{prop:\"flags\",name:\"flags\",embedded:false,exported:false,typ:$Uint32,tag:\"\"}]);CN.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"elem\",name:\"elem\",embedded:false,exported:false,typ:HR,tag:\"\"}]);CO.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"elem\",name:\"elem\",embedded:false,exported:false,typ:HR,tag:\"\"}]);CP.init(\"reflect\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:Q,tag:\"\"},{prop:\"typ\",name:\"typ\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"offsetEmbed\",name:\"offsetEmbed\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"}]);CQ.init(\"reflect\",[{prop:\"rtype\",name:\"rtype\",embedded:true,exported:false,typ:CE,tag:\"\"},{prop:\"pkgPath\",name:\"pkgPath\",embedded:false,exported:false,typ:Q,tag:\"\"},{prop:\"fields\",name:\"fields\",embedded:false,exported:false,typ:ID,tag:\"\"}]);CS.init(\"\",[{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"PkgPath\",name:\"PkgPath\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:CB,tag:\"\"},{prop:\"Func\",name:\"Func\",embedded:false,exported:true,typ:EY,tag:\"\"},{prop:\"Index\",name:\"Index\",embedded:false,exported:true,typ:$Int,tag:\"\"}]);DG.init(\"\",[{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"PkgPath\",name:\"PkgPath\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:CB,tag:\"\"},{prop:\"Tag\",name:\"Tag\",embedded:false,exported:true,typ:DH,tag:\"\"},{prop:\"Offset\",name:\"Offset\",embedded:false,exported:true,typ:$Uintptr,tag:\"\"},{prop:\"Index\",name:\"Index\",embedded:false,exported:true,typ:IR,tag:\"\"},{prop:\"Anonymous\",name:\"Anonymous\",embedded:false,exported:true,typ:$Bool,tag:\"\"}]);DI.init(\"reflect\",[{prop:\"typ\",name:\"typ\",embedded:false,exported:false,typ:IT,tag:\"\"},{prop:\"index\",name:\"index\",embedded:false,exported:false,typ:IR,tag:\"\"}]);EY.init(\"reflect\",[{prop:\"typ\",name:\"typ\",embedded:false,exported:false,typ:HR,tag:\"\"},{prop:\"ptr\",name:\"ptr\",embedded:false,exported:false,typ:$UnsafePointer,tag:\"\"},{prop:\"flag\",name:\"flag\",embedded:true,exported:false,typ:EZ,tag:\"\"}]);FC.init(\"\",[{prop:\"Method\",name:\"Method\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Kind\",name:\"Kind\",embedded:false,exported:true,typ:CC,tag:\"\"}]);FM.init(\"reflect\",[{prop:\"m\",name:\"m\",embedded:false,exported:false,typ:EY,tag:\"\"},{prop:\"it\",name:\"it\",embedded:false,exported:false,typ:$UnsafePointer,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}U=HQ.nil;W=HS.nil;I=false;O={};S={};BJ=$assertType($internalize($call,$emptyInterface),HX);BO=$assertType($internalize($select,$emptyInterface),HX);BK=L($jsObjectPtr);CT=new HY([\"invalid\",\"bool\",\"int\",\"int8\",\"int16\",\"int32\",\"int64\",\"uint\",\"uint8\",\"uint16\",\"uint32\",\"uint64\",\"uintptr\",\"float32\",\"float64\",\"complex64\",\"complex128\",\"array\",\"chan\",\"func\",\"interface\",\"map\",\"ptr\",\"slice\",\"string\",\"struct\",\"unsafe.Pointer\"]);FL=$assertType(AD(new $Uint8(0)),HR);$r=J();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"sort\"]=(function(){var $pkg={},$init,A,I,T,Z,AW,B,E,J,K,L,M,N,O,P,Q,R,U,AC,AG,AH,AI,AJ;A=$packages[\"reflect\"];I=$pkg.Interface=$newType(8,$kindInterface,\"sort.Interface\",true,\"sort\",true,null);T=$pkg.reverse=$newType(0,$kindStruct,\"sort.reverse\",true,\"sort\",false,function(Interface_){this.$val=this;if(arguments.length===0){this.Interface=$ifaceNil;return;}this.Interface=Interface_;});Z=$pkg.StringSlice=$newType(12,$kindSlice,\"sort.StringSlice\",true,\"sort\",true,null);AW=$sliceType($String);B=function(a,b){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=0;d=a;e=c;f=d;case 1:if(!(e<f)){$s=2;continue;}g=((((((e+f>>0)>>>0))>>>1>>>0)>>0));h=b(g);$s=6;case 6:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if(!h){$s=3;continue;}$s=4;continue;case 3:e=g+1>>0;$s=5;continue;case 4:f=g;case 5:$s=1;continue;case 2:$s=-1;return e;}return;}if($f===undefined){$f={$blk:B};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Search=B;E=function(a,b){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];c=B(a[0].$length,(function(a,b){return function(c){var c;return((c<0||c>=a[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):a[0].$array[a[0].$offset+c])>=b[0];};})(a,b));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:E};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};$pkg.SearchStrings=E;Z.prototype.Search=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=E($subslice(new AW(b.$array),b.$offset,b.$offset+b.$length),a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:Z.prototype.Search};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(Z).prototype.Search=function(a){return this.$get().Search(a);};J=function(a,b,c){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=b+1>>0;case 1:if(!(d<c)){$s=2;continue;}e=d;case 3:if(!(e>b)){f=false;$s=5;continue s;}g=a.Less(e,e-1>>0);$s=6;case 6:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;case 5:if(!(f)){$s=4;continue;}$r=a.Swap(e,e-1>>0);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e-(1)>>0;$s=3;continue;case 4:d=d+(1)>>0;$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:J};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};K=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=b;case 1:f=($imul(2,e))+1>>0;if(f>=c){$s=2;continue;}if(!((f+1>>0)<c)){g=false;$s=5;continue s;}h=a.Less(d+f>>0,(d+f>>0)+1>>0);$s=6;case 6:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;case 5:if(g){$s=3;continue;}$s=4;continue;case 3:f=f+(1)>>0;case 4:i=a.Less(d+e>>0,d+f>>0);$s=9;case 9:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}if(!i){$s=7;continue;}$s=8;continue;case 7:$s=-1;return;case 8:$r=a.Swap(d+e>>0,d+f>>0);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=f;$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:K};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};L=function(a,b,c){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=b;e=0;f=c-b>>0;h=(g=((f-1>>0))/2,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError(\"integer divide by zero\"));case 1:if(!(h>=0)){$s=2;continue;}$r=K(a,h,f,d);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}h=h-(1)>>0;$s=1;continue;case 2:i=f-1>>0;case 4:if(!(i>=0)){$s=5;continue;}$r=a.Swap(d,d+i>>0);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=K(a,e,i,d);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=i-(1)>>0;$s=4;continue;case 5:$s=-1;return;}return;}if($f===undefined){$f={$blk:L};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};M=function(a,b,c,d){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=a.Less(b,c);$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}if(e){$s=1;continue;}$s=2;continue;case 1:$r=a.Swap(b,c);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:f=a.Less(d,b);$s=7;case 7:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}if(f){$s=5;continue;}$s=6;continue;case 5:$r=a.Swap(d,b);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}g=a.Less(b,c);$s=11;case 11:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}if(g){$s=9;continue;}$s=10;continue;case 9:$r=a.Swap(b,c);$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 10:case 6:$s=-1;return;}return;}if($f===undefined){$f={$blk:M};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};N=function(a,b,c,d){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=0;case 1:if(!(e<d)){$s=2;continue;}$r=a.Swap(b+e>>0,c+e>>0);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e+(1)>>0;$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:N};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};O=function(a,b,c){var a,aa,ab,ac,ad,ae,af,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=0;f=((((((b+c>>0)>>>0))>>>1>>>0)>>0));if((c-b>>0)>40){$s=1;continue;}$s=2;continue;case 1:h=(g=((c-b>>0))/8,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError(\"integer divide by zero\"));$r=M(a,b,b+h>>0,b+($imul(2,h))>>0);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=M(a,f,f-h>>0,f+h>>0);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=M(a,c-1>>0,(c-1>>0)-h>>0,(c-1>>0)-($imul(2,h))>>0);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$r=M(a,b,f,c-1>>0);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=b;j=b+1>>0;k=c-1>>0;l=j;m=k;case 7:if(!(l<m)){n=false;$s=9;continue s;}o=a.Less(l,i);$s=10;case 10:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;case 9:if(!(n)){$s=8;continue;}l=l+(1)>>0;$s=7;continue;case 8:p=l;case 11:case 13:if(!(p<m)){q=false;$s=15;continue s;}r=a.Less(i,p);$s=16;case 16:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}q=!r;case 15:if(!(q)){$s=14;continue;}p=p+(1)>>0;$s=13;continue;case 14:case 17:if(!(p<m)){s=false;$s=19;continue s;}t=a.Less(i,m-1>>0);$s=20;case 20:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}s=t;case 19:if(!(s)){$s=18;continue;}m=m-(1)>>0;$s=17;continue;case 18:if(p>=m){$s=12;continue;}$r=a.Swap(p,m-1>>0);$s=21;case 21:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}p=p+(1)>>0;m=m-(1)>>0;$s=11;continue;case 12:u=(c-m>>0)<5;if(!u&&(c-m>>0)<(v=((c-b>>0))/4,(v===v&&v!==1/0&&v!==-1/0)?v>>0:$throwRuntimeError(\"integer divide by zero\"))){$s=22;continue;}$s=23;continue;case 22:w=0;x=a.Less(i,c-1>>0);$s=26;case 26:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}if(!x){$s=24;continue;}$s=25;continue;case 24:$r=a.Swap(m,c-1>>0);$s=27;case 27:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}m=m+(1)>>0;w=w+(1)>>0;case 25:y=a.Less(p-1>>0,i);$s=30;case 30:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}if(!y){$s=28;continue;}$s=29;continue;case 28:p=p-(1)>>0;w=w+(1)>>0;case 29:z=a.Less(f,i);$s=33;case 33:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}if(!z){$s=31;continue;}$s=32;continue;case 31:$r=a.Swap(f,p-1>>0);$s=34;case 34:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}p=p-(1)>>0;w=w+(1)>>0;case 32:u=w>1;case 23:if(u){$s=35;continue;}$s=36;continue;case 35:case 37:case 39:if(!(l<p)){aa=false;$s=41;continue s;}ab=a.Less(p-1>>0,i);$s=42;case 42:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=!ab;case 41:if(!(aa)){$s=40;continue;}p=p-(1)>>0;$s=39;continue;case 40:case 43:if(!(l<p)){ac=false;$s=45;continue s;}ad=a.Less(l,i);$s=46;case 46:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ac=ad;case 45:if(!(ac)){$s=44;continue;}l=l+(1)>>0;$s=43;continue;case 44:if(l>=p){$s=38;continue;}$r=a.Swap(l,p-1>>0);$s=47;case 47:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}l=l+(1)>>0;p=p-(1)>>0;$s=37;continue;case 38:case 36:$r=a.Swap(i,p-1>>0);$s=48;case 48:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}ae=p-1>>0;af=m;d=ae;e=af;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:O};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};P=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:case 1:if(!((c-b>>0)>12)){$s=2;continue;}if(d===0){$s=3;continue;}$s=4;continue;case 3:$r=L(a,b,c);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 4:d=d-(1)>>0;f=O(a,b,c);$s=6;case 6:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;g=e[0];h=e[1];if((g-b>>0)<(c-h>>0)){$s=7;continue;}$s=8;continue;case 7:$r=P(a,b,g,d);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b=h;$s=9;continue;case 8:$r=P(a,h,c,d);$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=g;case 9:$s=1;continue;case 2:if((c-b>>0)>1){$s=12;continue;}$s=13;continue;case 12:i=b+6>>0;case 14:if(!(i<c)){$s=15;continue;}j=a.Less(i,i-6>>0);$s=18;case 18:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}if(j){$s=16;continue;}$s=17;continue;case 16:$r=a.Swap(i,i-6>>0);$s=19;case 19:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 17:i=i+(1)>>0;$s=14;continue;case 15:$r=J(a,b,c);$s=20;case 20:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 13:$s=-1;return;}return;}if($f===undefined){$f={$blk:P};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};Q=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=a.Len();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;$r=P(a,0,c,R(c));$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:Q};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Sort=Q;R=function(a){var a,b,c;b=0;c=a;while(true){if(!(c>0)){break;}b=b+(1)>>0;c=(c>>$min((1),31))>>0;}return $imul(b,2);};T.ptr.prototype.Less=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.Interface.Less(b,a);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:T.ptr.prototype.Less};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};T.prototype.Less=function(a,b){return this.$val.Less(a,b);};U=function(a){var a;return new T.ptr(a);};$pkg.Reverse=U;Z.prototype.Len=function(){var a;a=this;return a.$length;};$ptrType(Z).prototype.Len=function(){return this.$get().Len();};Z.prototype.Less=function(a,b){var a,b,c;c=this;return((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a])<((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]);};$ptrType(Z).prototype.Less=function(a,b){return this.$get().Less(a,b);};Z.prototype.Swap=function(a,b){var a,b,c,d,e;c=this;d=((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]);e=((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]);((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]=d);((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]=e);};$ptrType(Z).prototype.Swap=function(a,b){return this.$get().Swap(a,b);};Z.prototype.Sort=function(){var a,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;$r=Q(a);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:Z.prototype.Sort};}$f.a=a;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(Z).prototype.Sort=function(){return this.$get().Sort();};AC=function(a){var a,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=Q(($subslice(new Z(a.$array),a.$offset,a.$offset+a.$length)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AC};}$f.a=a;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Strings=AC;AG=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=a;c=a.Len();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;$r=AH(b,d);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AG};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Stable=AG;AH=function(a,b){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=20;d=0;e=c;f=d;g=e;case 1:if(!(g<=b)){$s=2;continue;}$r=J(a,f,g);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}f=g;g=g+(c)>>0;$s=1;continue;case 2:$r=J(a,f,b);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 5:if(!(c<b)){$s=6;continue;}h=0;i=$imul(2,c);f=h;g=i;case 7:if(!(g<=b)){$s=8;continue;}$r=AI(a,f,f+c>>0,g);$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}f=g;g=g+(($imul(2,c)))>>0;$s=7;continue;case 8:j=f+c>>0;if(j<b){$s=10;continue;}$s=11;continue;case 10:$r=AI(a,f,j,b);$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 11:c=$imul(c,(2));$s=5;continue;case 6:$s=-1;return;}return;}if($f===undefined){$f={$blk:AH};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};AI=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if((c-b>>0)===1){$s=1;continue;}$s=2;continue;case 1:e=c;f=d;case 3:if(!(e<f)){$s=4;continue;}g=((((((e+f>>0)>>>0))>>>1>>>0)>>0));h=a.Less(g,b);$s=8;case 8:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if(h){$s=5;continue;}$s=6;continue;case 5:e=g+1>>0;$s=7;continue;case 6:f=g;case 7:$s=3;continue;case 4:i=b;case 9:if(!(i<(e-1>>0))){$s=10;continue;}$r=a.Swap(i,i+1>>0);$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=i+(1)>>0;$s=9;continue;case 10:$s=-1;return;case 2:if((d-c>>0)===1){$s=12;continue;}$s=13;continue;case 12:j=b;k=c;case 14:if(!(j<k)){$s=15;continue;}l=((((((j+k>>0)>>>0))>>>1>>>0)>>0));m=a.Less(c,l);$s=19;case 19:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}if(!m){$s=16;continue;}$s=17;continue;case 16:j=l+1>>0;$s=18;continue;case 17:k=l;case 18:$s=14;continue;case 15:n=c;case 20:if(!(n>j)){$s=21;continue;}$r=a.Swap(n,n-1>>0);$s=22;case 22:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}n=n-(1)>>0;$s=20;continue;case 21:$s=-1;return;case 13:o=((((((b+d>>0)>>>0))>>>1>>>0)>>0));p=o+c>>0;q=0;r=0;s=q;t=r;if(c>o){s=p-d>>0;t=o;}else{s=b;t=c;}u=p-1>>0;case 23:if(!(s<t)){$s=24;continue;}v=((((((s+t>>0)>>>0))>>>1>>>0)>>0));w=a.Less(u-v>>0,v);$s=28;case 28:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}if(!w){$s=25;continue;}$s=26;continue;case 25:s=v+1>>0;$s=27;continue;case 26:t=v;case 27:$s=23;continue;case 24:x=p-s>>0;if(s<c&&c<x){$s=29;continue;}$s=30;continue;case 29:$r=AJ(a,s,c,x);$s=31;case 31:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 30:if(b<s&&s<o){$s=32;continue;}$s=33;continue;case 32:$r=AI(a,b,s,o);$s=34;case 34:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 33:if(o<x&&x<d){$s=35;continue;}$s=36;continue;case 35:$r=AI(a,o,x,d);$s=37;case 37:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 36:$s=-1;return;}return;}if($f===undefined){$f={$blk:AI};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.$s=$s;$f.$r=$r;return $f;};AJ=function(a,b,c,d){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=c-b>>0;f=d-c>>0;case 1:if(!(!((e===f)))){$s=2;continue;}if(e>f){$s=3;continue;}$s=4;continue;case 3:$r=N(a,c-e>>0,c,f);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e-(f)>>0;$s=5;continue;case 4:$r=N(a,c-e>>0,(c+f>>0)-e>>0,e);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}f=f-(e)>>0;case 5:$s=1;continue;case 2:$r=N(a,c-e>>0,c,e);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AJ};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};T.methods=[{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)}];Z.methods=[{prop:\"Search\",name:\"Search\",pkg:\"\",typ:$funcType([$String],[$Int],false)},{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)},{prop:\"Sort\",name:\"Sort\",pkg:\"\",typ:$funcType([],[],false)}];I.init([{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)}]);T.init(\"\",[{prop:\"Interface\",name:\"Interface\",embedded:true,exported:true,typ:I,tag:\"\"}]);Z.init($String);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/fmtsort\"]=(function(){var $pkg={},$init,A,B,C,I,J,D,E,F,G,H;A=$packages[\"reflect\"];B=$packages[\"sort\"];C=$pkg.SortedMap=$newType(0,$kindStruct,\"fmtsort.SortedMap\",true,\"internal/fmtsort\",true,function(Key_,Value_){this.$val=this;if(arguments.length===0){this.Key=J.nil;this.Value=J.nil;return;}this.Key=Key_;this.Value=Value_;});I=$ptrType(C);J=$sliceType(A.Value);C.ptr.prototype.Len=function(){var a;a=this;return a.Key.$length;};C.prototype.Len=function(){return this.$val.Len();};C.ptr.prototype.Less=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;f=E($clone((d=c.Key,((a<0||a>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+a])),A.Value),$clone((e=c.Key,((b<0||b>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+b])),A.Value));$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return f<0;}return;}if($f===undefined){$f={$blk:C.ptr.prototype.Less};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};C.prototype.Less=function(a,b){return this.$val.Less(a,b);};C.ptr.prototype.Swap=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;c=this;d=(e=c.Key,((b<0||b>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+b]));f=(g=c.Key,((a<0||a>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+a]));(h=c.Key,((a<0||a>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+a]=d));(i=c.Key,((b<0||b>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+b]=f));j=(k=c.Value,((b<0||b>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+b]));l=(m=c.Value,((a<0||a>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+a]));(n=c.Value,((a<0||a>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+a]=j));(o=c.Value,((b<0||b>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+b]=l));};C.prototype.Swap=function(a,b){return this.$val.Swap(a,b);};D=function(a){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=$clone(a,A.Value).Type().Kind();$s=3;case 3:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}if(!((b===21))){$s=1;continue;}$s=2;continue;case 1:$s=-1;return I.nil;case 2:c=$makeSlice(J,$clone(a,A.Value).Len());d=$makeSlice(J,c.$length);e=$clone(a,A.Value).MapRange();f=0;case 4:g=e.Next();$s=6;case 6:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}if(!(g)){$s=5;continue;}h=e.Key();$s=7;case 7:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=h);i=e.Value();$s=8;case 8:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}((f<0||f>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+f]=i);f=f+(1)>>0;$s=4;continue;case 5:j=new C.ptr(c,d);$r=B.Stable(j);$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return j;}return;}if($f===undefined){$f={$blk:D};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Sort=D;E=function(a,b){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;bu=$f.bu;bv=$f.bv;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=$clone(a,A.Value).Type();d=$clone(b,A.Value).Type();e=c;f=d;if(!($interfaceIsEqual(e,f))){$s=-1;return-1;}g=$clone(a,A.Value).Kind();if((g===(2))||(g===(3))||(g===(4))||(g===(5))||(g===(6))){$s=2;continue;}if((g===(7))||(g===(8))||(g===(9))||(g===(10))||(g===(11))||(g===(12))){$s=3;continue;}if(g===(24)){$s=4;continue;}if((g===(13))||(g===(14))){$s=5;continue;}if((g===(15))||(g===(16))){$s=6;continue;}if(g===(1)){$s=7;continue;}if(g===(22)){$s=8;continue;}if(g===(18)){$s=9;continue;}if(g===(25)){$s=10;continue;}if(g===(17)){$s=11;continue;}if(g===(20)){$s=12;continue;}$s=13;continue;case 2:h=$clone(a,A.Value).Int();i=$clone(b,A.Value).Int();j=h;k=i;if((j.$high<k.$high||(j.$high===k.$high&&j.$low<k.$low))){$s=-1;return-1;}else if((j.$high>k.$high||(j.$high===k.$high&&j.$low>k.$low))){$s=-1;return 1;}else{$s=-1;return 0;}$s=14;continue;case 3:l=$clone(a,A.Value).Uint();m=$clone(b,A.Value).Uint();n=l;o=m;if((n.$high<o.$high||(n.$high===o.$high&&n.$low<o.$low))){$s=-1;return-1;}else if((n.$high>o.$high||(n.$high===o.$high&&n.$low>o.$low))){$s=-1;return 1;}else{$s=-1;return 0;}$s=14;continue;case 4:q=$clone(a,A.Value).String();$s=15;case 15:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;s=$clone(b,A.Value).String();$s=16;case 16:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}r=s;t=p;u=r;if(t<u){$s=-1;return-1;}else if(t>u){$s=-1;return 1;}else{$s=-1;return 0;}$s=14;continue;case 5:$s=-1;return G($clone(a,A.Value).Float(),$clone(b,A.Value).Float());case 6:v=$clone(a,A.Value).Complex();w=$clone(b,A.Value).Complex();x=v;y=w;z=G(x.$real,y.$real);if(!((z===0))){$s=-1;return z;}$s=-1;return G(x.$imag,y.$imag);case 7:aa=$clone(a,A.Value).Bool();ab=$clone(b,A.Value).Bool();ac=aa;ad=ab;if(ac===ad){$s=-1;return 0;}else if(ac){$s=-1;return 1;}else{$s=-1;return-1;}$s=14;continue;case 8:ae=$clone(a,A.Value).Pointer();af=$clone(b,A.Value).Pointer();ag=ae;ah=af;if(ag<ah){$s=-1;return-1;}else if(ag>ah){$s=-1;return 1;}else{$s=-1;return 0;}$s=14;continue;case 9:ai=F($clone(a,A.Value),$clone(b,A.Value));aj=ai[0];ak=ai[1];if(ak){$s=-1;return aj;}al=$clone(a,A.Value).Pointer();am=$clone(b,A.Value).Pointer();an=al;ao=am;if(an<ao){$s=-1;return-1;}else if(an>ao){$s=-1;return 1;}else{$s=-1;return 0;}$s=14;continue;case 10:ap=0;case 17:if(!(ap<$clone(a,A.Value).NumField())){$s=18;continue;}aq=$clone(a,A.Value).Field(ap);$s=19;case 19:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=$clone(aq,A.Value);as=$clone(b,A.Value).Field(ap);$s=20;case 20:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}at=$clone(as,A.Value);au=E(ar,at);$s=21;case 21:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}av=au;if(!((av===0))){$s=-1;return av;}ap=ap+(1)>>0;$s=17;continue;case 18:$s=-1;return 0;case 11:aw=0;case 22:if(!(aw<$clone(a,A.Value).Len())){$s=23;continue;}ax=$clone(a,A.Value).Index(aw);$s=24;case 24:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ay=$clone(ax,A.Value);az=$clone(b,A.Value).Index(aw);$s=25;case 25:if($c){$c=false;az=az.$blk();}if(az&&az.$blk!==undefined){break s;}ba=$clone(az,A.Value);bb=E(ay,ba);$s=26;case 26:if($c){$c=false;bb=bb.$blk();}if(bb&&bb.$blk!==undefined){break s;}bc=bb;if(!((bc===0))){$s=-1;return bc;}aw=aw+(1)>>0;$s=22;continue;case 23:$s=-1;return 0;case 12:bd=F($clone(a,A.Value),$clone(b,A.Value));be=bd[0];bf=bd[1];if(bf){$s=-1;return be;}bg=$clone(a,A.Value).Elem();$s=27;case 27:if($c){$c=false;bg=bg.$blk();}if(bg&&bg.$blk!==undefined){break s;}bh=$clone(bg,A.Value).Type();$s=28;case 28:if($c){$c=false;bh=bh.$blk();}if(bh&&bh.$blk!==undefined){break s;}bi=A.ValueOf(bh);$s=29;case 29:if($c){$c=false;bi=bi.$blk();}if(bi&&bi.$blk!==undefined){break s;}bj=$clone(bi,A.Value);bk=$clone(b,A.Value).Elem();$s=30;case 30:if($c){$c=false;bk=bk.$blk();}if(bk&&bk.$blk!==undefined){break s;}bl=$clone(bk,A.Value).Type();$s=31;case 31:if($c){$c=false;bl=bl.$blk();}if(bl&&bl.$blk!==undefined){break s;}bm=A.ValueOf(bl);$s=32;case 32:if($c){$c=false;bm=bm.$blk();}if(bm&&bm.$blk!==undefined){break s;}bn=$clone(bm,A.Value);bo=E(bj,bn);$s=33;case 33:if($c){$c=false;bo=bo.$blk();}if(bo&&bo.$blk!==undefined){break s;}bp=bo;if(!((bp===0))){$s=-1;return bp;}bq=$clone(a,A.Value).Elem();$s=34;case 34:if($c){$c=false;bq=bq.$blk();}if(bq&&bq.$blk!==undefined){break s;}br=$clone(bq,A.Value);bs=$clone(b,A.Value).Elem();$s=35;case 35:if($c){$c=false;bs=bs.$blk();}if(bs&&bs.$blk!==undefined){break s;}bt=$clone(bs,A.Value);bu=E(br,bt);$s=36;case 36:if($c){$c=false;bu=bu.$blk();}if(bu&&bu.$blk!==undefined){break s;}$s=-1;return bu;case 13:bv=e.String();$s=37;case 37:if($c){$c=false;bv=bv.$blk();}if(bv&&bv.$blk!==undefined){break s;}$panic(new $String(\"bad type in compare: \"+bv));case 14:case 1:$s=-1;return 0;}return;}if($f===undefined){$f={$blk:E};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.bu=bu;$f.bv=bv;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};F=function(a,b){var a,b;if($clone(a,A.Value).IsNil()){if($clone(b,A.Value).IsNil()){return[0,true];}return[-1,true];}if($clone(b,A.Value).IsNil()){return[1,true];}return[0,false];};G=function(a,b){var a,b;if(H(a)){return-1;}else if(H(b)){return 1;}else if(a<b){return-1;}else if(a>b){return 1;}return 0;};H=function(a){var a;return!((a===a));};I.methods=[{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)}];C.init(\"\",[{prop:\"Key\",name:\"Key\",embedded:false,exported:true,typ:J,tag:\"\"},{prop:\"Value\",name:\"Value\",embedded:false,exported:true,typ:J,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"io\"]=(function(){var $pkg={},$init,A,B,C,D,E,K,O,P,V,W,AG,AY,AZ,AJ,AK,Z,AA,AC,AE;A=$packages[\"errors\"];B=$packages[\"sync\"];C=$packages[\"sync/atomic\"];D=$pkg.Reader=$newType(8,$kindInterface,\"io.Reader\",true,\"io\",true,null);E=$pkg.Writer=$newType(8,$kindInterface,\"io.Writer\",true,\"io\",true,null);K=$pkg.ReadWriteCloser=$newType(8,$kindInterface,\"io.ReadWriteCloser\",true,\"io\",true,null);O=$pkg.ReaderFrom=$newType(8,$kindInterface,\"io.ReaderFrom\",true,\"io\",true,null);P=$pkg.WriterTo=$newType(8,$kindInterface,\"io.WriterTo\",true,\"io\",true,null);V=$pkg.RuneReader=$newType(8,$kindInterface,\"io.RuneReader\",true,\"io\",true,null);W=$pkg.RuneScanner=$newType(8,$kindInterface,\"io.RuneScanner\",true,\"io\",true,null);AG=$pkg.LimitedReader=$newType(0,$kindStruct,\"io.LimitedReader\",true,\"io\",true,function(R_,N_){this.$val=this;if(arguments.length===0){this.R=$ifaceNil;this.N=new $Int64(0,0);return;}this.R=R_;this.N=N_;});AY=$sliceType($Uint8);AZ=$ptrType(AG);Z=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;if(b.$length<c){f=0;g=$pkg.ErrShortBuffer;d=f;e=g;$s=-1;return[d,e];}case 1:if(!(d<c&&$interfaceIsEqual(e,$ifaceNil))){$s=2;continue;}h=0;j=a.Read($subslice(b,d));$s=3;case 3:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;h=i[0];e=i[1];d=d+(h)>>0;$s=1;continue;case 2:if(d>=c){e=$ifaceNil;}else if(d>0&&$interfaceIsEqual(e,$pkg.EOF)){e=$pkg.ErrUnexpectedEOF;}$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:Z};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};$pkg.ReadAtLeast=Z;AA=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=0;d=$ifaceNil;f=Z(a,b,b.$length);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;c=e[0];d=e[1];$s=-1;return[c,d];}return;}if($f===undefined){$f={$blk:AA};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};$pkg.ReadFull=AA;AC=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=new $Int64(0,0);d=$ifaceNil;f=AE(a,b,AY.nil);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;c=e[0];d=e[1];$s=-1;return[c,d];}return;}if($f===undefined){$f={$blk:AC};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Copy=AC;AE=function(a,b,c){var a,aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=new $Int64(0,0);e=$ifaceNil;f=$assertType(b,P,true);g=f[0];h=f[1];if(h){$s=1;continue;}$s=2;continue;case 1:j=g.WriteTo(a);$s=3;case 3:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;d=i[0];e=i[1];$s=-1;return[d,e];case 2:k=$assertType(a,O,true);l=k[0];m=k[1];if(m){$s=4;continue;}$s=5;continue;case 4:o=l.ReadFrom(b);$s=6;case 6:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;d=n[0];e=n[1];$s=-1;return[d,e];case 5:if(c===AY.nil){p=32768;q=$assertType(b,AZ,true);r=q[0];s=q[1];if(s&&(t=(new $Int64(0,p)),u=r.N,(t.$high>u.$high||(t.$high===u.$high&&t.$low>u.$low)))){if((v=r.N,(v.$high<0||(v.$high===0&&v.$low<1)))){p=1;}else{p=(((w=r.N,w.$low+((w.$high>>31)*4294967296))>>0));}}c=$makeSlice(AY,p);}case 7:y=b.Read(c);$s=9;case 9:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;z=x[0];aa=x[1];if(z>0){$s=10;continue;}$s=11;continue;case 10:ac=a.Write($subslice(c,0,z));$s=12;case 12:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}ab=ac;ad=ab[0];ae=ab[1];if(ad>0){d=(af=(new $Int64(0,ad)),new $Int64(d.$high+af.$high,d.$low+af.$low));}if(!($interfaceIsEqual(ae,$ifaceNil))){e=ae;$s=8;continue;}if(!((z===ad))){e=$pkg.ErrShortWrite;$s=8;continue;}case 11:if(!($interfaceIsEqual(aa,$ifaceNil))){if(!($interfaceIsEqual(aa,$pkg.EOF))){e=aa;}$s=8;continue;}$s=7;continue;case 8:ag=d;ah=e;d=ag;e=ah;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:AE};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AG.ptr.prototype.Read=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;if((e=d.N,(e.$high<0||(e.$high===0&&e.$low<=0)))){f=0;g=$pkg.EOF;b=f;c=g;$s=-1;return[b,c];}if((h=(new $Int64(0,a.$length)),i=d.N,(h.$high>i.$high||(h.$high===i.$high&&h.$low>i.$low)))){a=$subslice(a,0,$flatten64(d.N));}k=d.R.Read(a);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;b=j[0];c=j[1];d.N=(l=d.N,m=(new $Int64(0,b)),new $Int64(l.$high-m.$high,l.$low-m.$low));$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AG.ptr.prototype.Read};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};AG.prototype.Read=function(a){return this.$val.Read(a);};AZ.methods=[{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)}];D.init([{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)}]);E.init([{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)}]);K.init([{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)}]);O.init([{prop:\"ReadFrom\",name:\"ReadFrom\",pkg:\"\",typ:$funcType([D],[$Int64,$error],false)}]);P.init([{prop:\"WriteTo\",name:\"WriteTo\",pkg:\"\",typ:$funcType([E],[$Int64,$error],false)}]);V.init([{prop:\"ReadRune\",name:\"ReadRune\",pkg:\"\",typ:$funcType([],[$Int32,$Int,$error],false)}]);W.init([{prop:\"ReadRune\",name:\"ReadRune\",pkg:\"\",typ:$funcType([],[$Int32,$Int,$error],false)},{prop:\"UnreadRune\",name:\"UnreadRune\",pkg:\"\",typ:$funcType([],[$error],false)}]);AG.init(\"\",[{prop:\"R\",name:\"R\",embedded:false,exported:true,typ:D,tag:\"\"},{prop:\"N\",name:\"N\",embedded:false,exported:true,typ:$Int64,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.ErrShortWrite=A.New(\"short write\");$pkg.ErrShortBuffer=A.New(\"short buffer\");$pkg.EOF=A.New(\"EOF\");$pkg.ErrUnexpectedEOF=A.New(\"unexpected EOF\");$pkg.ErrNoProgress=A.New(\"multiple Read calls return no data or error\");AJ=A.New(\"Seek: invalid whence\");AK=A.New(\"Seek: invalid offset\");$pkg.ErrClosedPipe=A.New(\"io: read/write on closed pipe\");}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"syscall\"]=(function(){var $pkg={},$init,A,D,B,C,CB,CF,CI,CL,EH,EI,GM,GN,GV,GW,GX,GY,NJ,NS,NX,NY,NZ,OA,OB,OC,OD,OE,OF,OG,OH,OI,OJ,OK,OS,OU,OW,OX,OY,PL,PN,PV,PZ,QF,QG,QH,QL,QM,QN,QO,QP,QT,QU,RA,RB,RC,RD,RE,RG,RK,RL,RO,RP,RQ,RR,RS,RT,RU,RV,RW,RX,RY,RZ,SF,E,F,P,Q,R,AG,FX,GO,GP,GQ,HR,PU,HW,G,H,I,K,L,M,S,T,U,V,Y,Z,AA,AB,AC,BC,BD,BZ,CA,CD,CE,CG,CH,CJ,CK,CM,CN,CZ,DA,DF,DH,DL,DP,EJ,EK,EL,EM,EU,EV,EX,FP,FQ,FR,FS,GA,GC,GR,GT,GU,GZ,HC,HD,HE,HF,HG,HH,HI,HJ,HL,HO,HZ,IB,IR,IS,IY,IZ,JB,JE,JF,JZ,KU,KY,LG,LH,LJ,LT,LU,LV,MF,MK,ML,MM,MO,MR,MS,MT,MW,MX,MY,MZ,NA,NB;A=$packages[\"github.com/gopherjs/gopherjs/js\"];D=$packages[\"internal/race\"];B=$packages[\"runtime\"];C=$packages[\"sync\"];CB=$pkg.RawConn=$newType(8,$kindInterface,\"syscall.RawConn\",true,\"syscall\",true,null);CF=$pkg.NetlinkRouteRequest=$newType(0,$kindStruct,\"syscall.NetlinkRouteRequest\",true,\"syscall\",true,function(Header_,Data_){this.$val=this;if(arguments.length===0){this.Header=new OS.ptr(0,0,0,0,0);this.Data=new OU.ptr(0);return;}this.Header=Header_;this.Data=Data_;});CI=$pkg.NetlinkMessage=$newType(0,$kindStruct,\"syscall.NetlinkMessage\",true,\"syscall\",true,function(Header_,Data_){this.$val=this;if(arguments.length===0){this.Header=new OS.ptr(0,0,0,0,0);this.Data=PL.nil;return;}this.Header=Header_;this.Data=Data_;});CL=$pkg.NetlinkRouteAttr=$newType(0,$kindStruct,\"syscall.NetlinkRouteAttr\",true,\"syscall\",true,function(Attr_,Value_){this.$val=this;if(arguments.length===0){this.Attr=new OW.ptr(0,0);this.Value=PL.nil;return;}this.Attr=Attr_;this.Value=Value_;});EH=$pkg.SockaddrLinklayer=$newType(0,$kindStruct,\"syscall.SockaddrLinklayer\",true,\"syscall\",true,function(Protocol_,Ifindex_,Hatype_,Pkttype_,Halen_,Addr_,raw_){this.$val=this;if(arguments.length===0){this.Protocol=0;this.Ifindex=0;this.Hatype=0;this.Pkttype=0;this.Halen=0;this.Addr=QF.zero();this.raw=new OA.ptr(0,0,0,0,0,0,QF.zero());return;}this.Protocol=Protocol_;this.Ifindex=Ifindex_;this.Hatype=Hatype_;this.Pkttype=Pkttype_;this.Halen=Halen_;this.Addr=Addr_;this.raw=raw_;});EI=$pkg.SockaddrNetlink=$newType(0,$kindStruct,\"syscall.SockaddrNetlink\",true,\"syscall\",true,function(Family_,Pad_,Pid_,Groups_,raw_){this.$val=this;if(arguments.length===0){this.Family=0;this.Pad=0;this.Pid=0;this.Groups=0;this.raw=new OB.ptr(0,0,0,0);return;}this.Family=Family_;this.Pad=Pad_;this.Pid=Pid_;this.Groups=Groups_;this.raw=raw_;});GM=$pkg.mmapper=$newType(0,$kindStruct,\"syscall.mmapper\",true,\"syscall\",false,function(Mutex_,active_,mmap_,munmap_){this.$val=this;if(arguments.length===0){this.Mutex=new C.Mutex.ptr(0,0);this.active=false;this.mmap=$throwNilPointerError;this.munmap=$throwNilPointerError;return;}this.Mutex=Mutex_;this.active=active_;this.mmap=mmap_;this.munmap=munmap_;});GN=$pkg.Errno=$newType(4,$kindUintptr,\"syscall.Errno\",true,\"syscall\",true,null);GV=$pkg.Sockaddr=$newType(8,$kindInterface,\"syscall.Sockaddr\",true,\"syscall\",true,null);GW=$pkg.SockaddrInet4=$newType(0,$kindStruct,\"syscall.SockaddrInet4\",true,\"syscall\",true,function(Port_,Addr_,raw_){this.$val=this;if(arguments.length===0){this.Port=0;this.Addr=RB.zero();this.raw=new NX.ptr(0,0,RB.zero(),QF.zero());return;}this.Port=Port_;this.Addr=Addr_;this.raw=raw_;});GX=$pkg.SockaddrInet6=$newType(0,$kindStruct,\"syscall.SockaddrInet6\",true,\"syscall\",true,function(Port_,ZoneId_,Addr_,raw_){this.$val=this;if(arguments.length===0){this.Port=0;this.ZoneId=0;this.Addr=QH.zero();this.raw=new NY.ptr(0,0,0,QH.zero(),0);return;}this.Port=Port_;this.ZoneId=ZoneId_;this.Addr=Addr_;this.raw=raw_;});GY=$pkg.SockaddrUnix=$newType(0,$kindStruct,\"syscall.SockaddrUnix\",true,\"syscall\",true,function(Name_,raw_){this.$val=this;if(arguments.length===0){this.Name=\"\";this.raw=new NZ.ptr(0,RA.zero());return;}this.Name=Name_;this.raw=raw_;});NJ=$pkg.Timespec=$newType(0,$kindStruct,\"syscall.Timespec\",true,\"syscall\",true,function(Sec_,Nsec_){this.$val=this;if(arguments.length===0){this.Sec=new $Int64(0,0);this.Nsec=new $Int64(0,0);return;}this.Sec=Sec_;this.Nsec=Nsec_;});NS=$pkg.Stat_t=$newType(0,$kindStruct,\"syscall.Stat_t\",true,\"syscall\",true,function(Dev_,Ino_,Nlink_,Mode_,Uid_,Gid_,X__pad0_,Rdev_,Size_,Blksize_,Blocks_,Atim_,Mtim_,Ctim_,X__unused_){this.$val=this;if(arguments.length===0){this.Dev=new $Uint64(0,0);this.Ino=new $Uint64(0,0);this.Nlink=new $Uint64(0,0);this.Mode=0;this.Uid=0;this.Gid=0;this.X__pad0=0;this.Rdev=new $Uint64(0,0);this.Size=new $Int64(0,0);this.Blksize=new $Int64(0,0);this.Blocks=new $Int64(0,0);this.Atim=new NJ.ptr(new $Int64(0,0),new $Int64(0,0));this.Mtim=new NJ.ptr(new $Int64(0,0),new $Int64(0,0));this.Ctim=new NJ.ptr(new $Int64(0,0),new $Int64(0,0));this.X__unused=QU.zero();return;}this.Dev=Dev_;this.Ino=Ino_;this.Nlink=Nlink_;this.Mode=Mode_;this.Uid=Uid_;this.Gid=Gid_;this.X__pad0=X__pad0_;this.Rdev=Rdev_;this.Size=Size_;this.Blksize=Blksize_;this.Blocks=Blocks_;this.Atim=Atim_;this.Mtim=Mtim_;this.Ctim=Ctim_;this.X__unused=X__unused_;});NX=$pkg.RawSockaddrInet4=$newType(0,$kindStruct,\"syscall.RawSockaddrInet4\",true,\"syscall\",true,function(Family_,Port_,Addr_,Zero_){this.$val=this;if(arguments.length===0){this.Family=0;this.Port=0;this.Addr=RB.zero();this.Zero=QF.zero();return;}this.Family=Family_;this.Port=Port_;this.Addr=Addr_;this.Zero=Zero_;});NY=$pkg.RawSockaddrInet6=$newType(0,$kindStruct,\"syscall.RawSockaddrInet6\",true,\"syscall\",true,function(Family_,Port_,Flowinfo_,Addr_,Scope_id_){this.$val=this;if(arguments.length===0){this.Family=0;this.Port=0;this.Flowinfo=0;this.Addr=QH.zero();this.Scope_id=0;return;}this.Family=Family_;this.Port=Port_;this.Flowinfo=Flowinfo_;this.Addr=Addr_;this.Scope_id=Scope_id_;});NZ=$pkg.RawSockaddrUnix=$newType(0,$kindStruct,\"syscall.RawSockaddrUnix\",true,\"syscall\",true,function(Family_,Path_){this.$val=this;if(arguments.length===0){this.Family=0;this.Path=RA.zero();return;}this.Family=Family_;this.Path=Path_;});OA=$pkg.RawSockaddrLinklayer=$newType(0,$kindStruct,\"syscall.RawSockaddrLinklayer\",true,\"syscall\",true,function(Family_,Protocol_,Ifindex_,Hatype_,Pkttype_,Halen_,Addr_){this.$val=this;if(arguments.length===0){this.Family=0;this.Protocol=0;this.Ifindex=0;this.Hatype=0;this.Pkttype=0;this.Halen=0;this.Addr=QF.zero();return;}this.Family=Family_;this.Protocol=Protocol_;this.Ifindex=Ifindex_;this.Hatype=Hatype_;this.Pkttype=Pkttype_;this.Halen=Halen_;this.Addr=Addr_;});OB=$pkg.RawSockaddrNetlink=$newType(0,$kindStruct,\"syscall.RawSockaddrNetlink\",true,\"syscall\",true,function(Family_,Pad_,Pid_,Groups_){this.$val=this;if(arguments.length===0){this.Family=0;this.Pad=0;this.Pid=0;this.Groups=0;return;}this.Family=Family_;this.Pad=Pad_;this.Pid=Pid_;this.Groups=Groups_;});OC=$pkg.RawSockaddr=$newType(0,$kindStruct,\"syscall.RawSockaddr\",true,\"syscall\",true,function(Family_,Data_){this.$val=this;if(arguments.length===0){this.Family=0;this.Data=RC.zero();return;}this.Family=Family_;this.Data=Data_;});OD=$pkg.RawSockaddrAny=$newType(0,$kindStruct,\"syscall.RawSockaddrAny\",true,\"syscall\",true,function(Addr_,Pad_){this.$val=this;if(arguments.length===0){this.Addr=new OC.ptr(0,RC.zero());this.Pad=RD.zero();return;}this.Addr=Addr_;this.Pad=Pad_;});OE=$pkg._Socklen=$newType(4,$kindUint32,\"syscall._Socklen\",true,\"syscall\",false,null);OF=$pkg.Linger=$newType(0,$kindStruct,\"syscall.Linger\",true,\"syscall\",true,function(Onoff_,Linger_){this.$val=this;if(arguments.length===0){this.Onoff=0;this.Linger=0;return;}this.Onoff=Onoff_;this.Linger=Linger_;});OG=$pkg.Iovec=$newType(0,$kindStruct,\"syscall.Iovec\",true,\"syscall\",true,function(Base_,Len_){this.$val=this;if(arguments.length===0){this.Base=PV.nil;this.Len=new $Uint64(0,0);return;}this.Base=Base_;this.Len=Len_;});OH=$pkg.IPMreq=$newType(0,$kindStruct,\"syscall.IPMreq\",true,\"syscall\",true,function(Multiaddr_,Interface_){this.$val=this;if(arguments.length===0){this.Multiaddr=RB.zero();this.Interface=RB.zero();return;}this.Multiaddr=Multiaddr_;this.Interface=Interface_;});OI=$pkg.IPMreqn=$newType(0,$kindStruct,\"syscall.IPMreqn\",true,\"syscall\",true,function(Multiaddr_,Address_,Ifindex_){this.$val=this;if(arguments.length===0){this.Multiaddr=RB.zero();this.Address=RB.zero();this.Ifindex=0;return;}this.Multiaddr=Multiaddr_;this.Address=Address_;this.Ifindex=Ifindex_;});OJ=$pkg.IPv6Mreq=$newType(0,$kindStruct,\"syscall.IPv6Mreq\",true,\"syscall\",true,function(Multiaddr_,Interface_){this.$val=this;if(arguments.length===0){this.Multiaddr=QH.zero();this.Interface=0;return;}this.Multiaddr=Multiaddr_;this.Interface=Interface_;});OK=$pkg.Msghdr=$newType(0,$kindStruct,\"syscall.Msghdr\",true,\"syscall\",true,function(Name_,Namelen_,Pad_cgo_0_,Iov_,Iovlen_,Control_,Controllen_,Flags_,Pad_cgo_1_){this.$val=this;if(arguments.length===0){this.Name=PV.nil;this.Namelen=0;this.Pad_cgo_0=RB.zero();this.Iov=RG.nil;this.Iovlen=new $Uint64(0,0);this.Control=PV.nil;this.Controllen=new $Uint64(0,0);this.Flags=0;this.Pad_cgo_1=RB.zero();return;}this.Name=Name_;this.Namelen=Namelen_;this.Pad_cgo_0=Pad_cgo_0_;this.Iov=Iov_;this.Iovlen=Iovlen_;this.Control=Control_;this.Controllen=Controllen_;this.Flags=Flags_;this.Pad_cgo_1=Pad_cgo_1_;});OS=$pkg.NlMsghdr=$newType(0,$kindStruct,\"syscall.NlMsghdr\",true,\"syscall\",true,function(Len_,Type_,Flags_,Seq_,Pid_){this.$val=this;if(arguments.length===0){this.Len=0;this.Type=0;this.Flags=0;this.Seq=0;this.Pid=0;return;}this.Len=Len_;this.Type=Type_;this.Flags=Flags_;this.Seq=Seq_;this.Pid=Pid_;});OU=$pkg.RtGenmsg=$newType(0,$kindStruct,\"syscall.RtGenmsg\",true,\"syscall\",true,function(Family_){this.$val=this;if(arguments.length===0){this.Family=0;return;}this.Family=Family_;});OW=$pkg.RtAttr=$newType(0,$kindStruct,\"syscall.RtAttr\",true,\"syscall\",true,function(Len_,Type_){this.$val=this;if(arguments.length===0){this.Len=0;this.Type=0;return;}this.Len=Len_;this.Type=Type_;});OX=$pkg.IfInfomsg=$newType(0,$kindStruct,\"syscall.IfInfomsg\",true,\"syscall\",true,function(Family_,X__ifi_pad_,Type_,Index_,Flags_,Change_){this.$val=this;if(arguments.length===0){this.Family=0;this.X__ifi_pad=0;this.Type=0;this.Index=0;this.Flags=0;this.Change=0;return;}this.Family=Family_;this.X__ifi_pad=X__ifi_pad_;this.Type=Type_;this.Index=Index_;this.Flags=Flags_;this.Change=Change_;});OY=$pkg.IfAddrmsg=$newType(0,$kindStruct,\"syscall.IfAddrmsg\",true,\"syscall\",true,function(Family_,Prefixlen_,Flags_,Scope_,Index_){this.$val=this;if(arguments.length===0){this.Family=0;this.Prefixlen=0;this.Flags=0;this.Scope=0;this.Index=0;return;}this.Family=Family_;this.Prefixlen=Prefixlen_;this.Flags=Flags_;this.Scope=Scope_;this.Index=Index_;});PL=$sliceType($Uint8);PN=$sliceType($String);PV=$ptrType($Uint8);PZ=$ptrType($Int32);QF=$arrayType($Uint8,8);QG=$ptrType($Uint16);QH=$arrayType($Uint8,16);QL=$ptrType(EI);QM=$sliceType(CI);QN=$ptrType(OS);QO=$sliceType(CL);QP=$ptrType(OW);QT=$arrayType($Uint8,32);QU=$arrayType($Int64,3);RA=$arrayType($Int8,108);RB=$arrayType($Uint8,4);RC=$arrayType($Int8,14);RD=$arrayType($Int8,96);RE=$ptrType(OE);RG=$ptrType(OG);RK=$structType(\"syscall\",[{prop:\"addr\",name:\"addr\",embedded:false,exported:false,typ:$Uintptr,tag:\"\"},{prop:\"len\",name:\"len\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"cap\",name:\"cap\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);RL=$ptrType($Int64);RO=$funcType([$Uintptr],[],false);RP=$funcType([$Uintptr],[$Bool],false);RQ=$ptrType(CF);RR=$ptrType(EH);RS=$ptrType(GM);RT=$mapType(PV,PL);RU=$funcType([$Uintptr,$Uintptr,$Int,$Int,$Int,$Int64],[$Uintptr,$error],false);RV=$funcType([$Uintptr,$Uintptr],[$error],false);RW=$ptrType(GW);RX=$ptrType(GX);RY=$ptrType(GY);RZ=$ptrType(NJ);SF=$ptrType(OK);G=function(){$flushConsole=(function(){if(!((F.$length===0))){$global.console.log($externalize(($bytesToString(F)),$String));F=PL.nil;}});};H=function(){if(!E){$global.console.error($externalize(\"warning: system calls not available, see https://github.com/gopherjs/gopherjs/blob/master/doc/syscalls.md\",$String));}E=true;};I=function(k){var k,l,m;l=$global.goPrintToConsole;if(!(l===undefined)){l(k);return;}F=$appendSlice(F,k);while(true){m=L(F,10);if(m===-1){break;}$global.console.log($externalize(($bytesToString($subslice(F,0,m))),$String));F=$subslice(F,(m+1>>0));}};K=function(k){var k;T(231,((k>>>0)),0,0);};$pkg.Exit=K;L=function(k,l){var k,l,m,n,o,p;m=k;n=0;while(true){if(!(n<m.$length)){break;}o=n;p=((n<0||n>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+n]);if(p===l){return o;}n++;}return-1;};M=function(){var k,l,m,n,o,p;k=$global.process;if(k===undefined){return PN.nil;}l=k.env;m=$global.Object.keys(l);n=$makeSlice(PN,$parseInt(m.length));o=0;while(true){if(!(o<$parseInt(m.length))){break;}p=$internalize(m[o],$String);((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]=p+\"=\"+$internalize(l[$externalize(p,$String)],$String));o=o+(1)>>0;}return n;};S=function(k){var k,l,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);$deferred.push([(function(){$recover();}),[]]);if(P===null){if(Q){return null;}Q=true;l=$global.require;if(l===undefined){$panic(new $String(\"\"));}P=l($externalize(\"syscall\",$String));}return P[$externalize(k,$String)];}catch(err){$err=err;return null;}finally{$callDeferred($deferred,$err);}};T=function(k,l,m,n){var aa,ab,ac,ad,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;o=0;p=0;q=0;r=S(\"Syscall\");if(!(r===null)){s=r(k,l,m,n);t=((($parseInt(s[0])>>0)>>>0));u=((($parseInt(s[1])>>0)>>>0));v=((($parseInt(s[2])>>0)>>>0));o=t;p=u;q=v;return[o,p,q];}if((k===1)&&((l===1)||(l===2))){w=m;x=$makeSlice(PL,$parseInt(w.length));x.$array=w;I(x);y=(($parseInt(w.length)>>>0));z=0;aa=0;o=y;p=z;q=aa;return[o,p,q];}if(k===231){B.Goexit();}H();ab=((R>>>0));ac=0;ad=13;o=ab;p=ac;q=ad;return[o,p,q];};$pkg.Syscall=T;U=function(k,l,m,n,o,p,q){var aa,ab,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;r=0;s=0;t=0;u=S(\"Syscall6\");if(!(u===null)){v=u(k,l,m,n,o,p,q);w=((($parseInt(v[0])>>0)>>>0));x=((($parseInt(v[1])>>0)>>>0));y=((($parseInt(v[2])>>0)>>>0));r=w;s=x;t=y;return[r,s,t];}if(!((k===202))){H();}z=((R>>>0));aa=0;ab=13;r=z;s=aa;t=ab;return[r,s,t];};$pkg.Syscall6=U;V=function(k,l,m,n){var k,l,m,n,o,p,q,r,s,t,u,v,w,x,y;o=0;p=0;q=0;r=S(\"Syscall\");if(!(r===null)){s=r(k,l,m,n);t=((($parseInt(s[0])>>0)>>>0));u=((($parseInt(s[1])>>0)>>>0));v=((($parseInt(s[2])>>0)>>>0));o=t;p=u;q=v;return[o,p,q];}H();w=((R>>>0));x=0;y=13;o=w;p=x;q=y;return[o,p,q];};$pkg.RawSyscall=V;Y=function(k){var k,l,m,n,o,p;l=new($global.Uint8Array)(k.length+1>>0);m=(new PL($stringToBytes(k)));n=0;while(true){if(!(n<m.$length)){break;}o=n;p=((n<0||n>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+n]);if(p===0){return[PV.nil,new GN(22)];}l[o]=p;n++;}l[k.length]=0;return[((l)),$ifaceNil];};$pkg.BytePtrFromString=Y;Z=function(k,l,m){var k,l,m,n,o,p,q,r,s,t,u;n=new $Uint64(0,0);o=false;if(k.$length<(((l+m>>>0)>>0))){p=new $Uint64(0,0);q=false;n=p;o=q;return[n,o];}if(false){r=AA($subslice(k,l),m);s=true;n=r;o=s;return[n,o];}t=AB($subslice(k,l),m);u=true;n=t;o=u;return[n,o];};AA=function(k,l){var aa,ab,ac,ad,ae,af,ag,ah,ai,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;m=l;if(m===(1)){return(new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])));}else if(m===(2)){$unused((1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]));return(n=(new $Uint64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),o=$shiftLeft64((new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),8),new $Uint64(n.$high|o.$high,(n.$low|o.$low)>>>0));}else if(m===(4)){$unused((3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]));return(p=(q=(r=(new $Uint64(0,(3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]))),s=$shiftLeft64((new $Uint64(0,(2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2]))),8),new $Uint64(r.$high|s.$high,(r.$low|s.$low)>>>0)),t=$shiftLeft64((new $Uint64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),16),new $Uint64(q.$high|t.$high,(q.$low|t.$low)>>>0)),u=$shiftLeft64((new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),24),new $Uint64(p.$high|u.$high,(p.$low|u.$low)>>>0));}else if(m===(8)){$unused((7>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+7]));return(v=(w=(x=(y=(z=(aa=(ab=(new $Uint64(0,(7>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+7]))),ac=$shiftLeft64((new $Uint64(0,(6>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+6]))),8),new $Uint64(ab.$high|ac.$high,(ab.$low|ac.$low)>>>0)),ad=$shiftLeft64((new $Uint64(0,(5>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+5]))),16),new $Uint64(aa.$high|ad.$high,(aa.$low|ad.$low)>>>0)),ae=$shiftLeft64((new $Uint64(0,(4>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+4]))),24),new $Uint64(z.$high|ae.$high,(z.$low|ae.$low)>>>0)),af=$shiftLeft64((new $Uint64(0,(3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]))),32),new $Uint64(y.$high|af.$high,(y.$low|af.$low)>>>0)),ag=$shiftLeft64((new $Uint64(0,(2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2]))),40),new $Uint64(x.$high|ag.$high,(x.$low|ag.$low)>>>0)),ah=$shiftLeft64((new $Uint64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),48),new $Uint64(w.$high|ah.$high,(w.$low|ah.$low)>>>0)),ai=$shiftLeft64((new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),56),new $Uint64(v.$high|ai.$high,(v.$low|ai.$low)>>>0));}else{$panic(new $String(\"syscall: readInt with unsupported size\"));}};AB=function(k,l){var aa,ab,ac,ad,ae,af,ag,ah,ai,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;m=l;if(m===(1)){return(new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])));}else if(m===(2)){$unused((1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]));return(n=(new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),o=$shiftLeft64((new $Uint64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),8),new $Uint64(n.$high|o.$high,(n.$low|o.$low)>>>0));}else if(m===(4)){$unused((3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]));return(p=(q=(r=(new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),s=$shiftLeft64((new $Uint64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),8),new $Uint64(r.$high|s.$high,(r.$low|s.$low)>>>0)),t=$shiftLeft64((new $Uint64(0,(2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2]))),16),new $Uint64(q.$high|t.$high,(q.$low|t.$low)>>>0)),u=$shiftLeft64((new $Uint64(0,(3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]))),24),new $Uint64(p.$high|u.$high,(p.$low|u.$low)>>>0));}else if(m===(8)){$unused((7>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+7]));return(v=(w=(x=(y=(z=(aa=(ab=(new $Uint64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),ac=$shiftLeft64((new $Uint64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),8),new $Uint64(ab.$high|ac.$high,(ab.$low|ac.$low)>>>0)),ad=$shiftLeft64((new $Uint64(0,(2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2]))),16),new $Uint64(aa.$high|ad.$high,(aa.$low|ad.$low)>>>0)),ae=$shiftLeft64((new $Uint64(0,(3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]))),24),new $Uint64(z.$high|ae.$high,(z.$low|ae.$low)>>>0)),af=$shiftLeft64((new $Uint64(0,(4>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+4]))),32),new $Uint64(y.$high|af.$high,(y.$low|af.$low)>>>0)),ag=$shiftLeft64((new $Uint64(0,(5>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+5]))),40),new $Uint64(x.$high|ag.$high,(x.$low|ag.$low)>>>0)),ah=$shiftLeft64((new $Uint64(0,(6>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+6]))),48),new $Uint64(w.$high|ah.$high,(w.$low|ah.$low)>>>0)),ai=$shiftLeft64((new $Uint64(0,(7>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+7]))),56),new $Uint64(v.$high|ai.$high,(v.$low|ai.$low)>>>0));}else{$panic(new $String(\"syscall: readInt with unsupported size\"));}};AC=function(k,l,m){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;n=0;o=0;p=PN.nil;q=k.$length;o=0;while(true){if(!(!((l===0))&&k.$length>0)){break;}r=FR(k);s=r[0];t=r[1];if(!t||(u=(new $Uint64(0,k.$length)),(s.$high>u.$high||(s.$high===u.$high&&s.$low>u.$low)))){v=q;w=o;x=m;n=v;o=w;p=x;return[n,o,p];}y=$subslice(k,0,$flatten64(s));k=$subslice(k,$flatten64(s));z=FQ(y);aa=z[0];t=z[1];if(!t){break;}if((aa.$high===0&&aa.$low===0)){continue;}ab=FS(y);ac=ab[0];t=ab[1];if(!t||(ad=new $Uint64(0+ac.$high,19+ac.$low),ae=(new $Uint64(0,y.$length)),(ad.$high>ae.$high||(ad.$high===ae.$high&&ad.$low>ae.$low)))){break;}af=$subslice(y,19,$flatten64(new $Uint64(0+ac.$high,19+ac.$low)));ag=af;ah=0;while(true){if(!(ah<ag.$length)){break;}ai=ah;aj=((ah<0||ah>=ag.$length)?($throwRuntimeError(\"index out of range\"),undefined):ag.$array[ag.$offset+ah]);if(aj===0){af=$subslice(af,0,ai);break;}ah++;}if(($bytesToString(af))===\".\"||($bytesToString(af))===\"..\"){continue;}l=l-(1)>>0;o=o+(1)>>0;m=$append(m,($bytesToString(af)));}ak=q-k.$length>>0;al=o;am=m;n=ak;o=al;p=am;return[n,o,p];};$pkg.ParseDirent=AC;BC=function(k){var k;JB(k,2,1);};$pkg.CloseOnExec=BC;BD=function(k,l){var k,l,m,n,o,p;m=$ifaceNil;n=JB(k,3,0);o=n[0];m=n[1];if(!($interfaceIsEqual(m,$ifaceNil))){m=m;return m;}if(l){o=o|(2048);}else{o=(o&~(2048))>>0;}p=JB(k,4,o);m=p[1];m=m;return m;};$pkg.SetNonblock=BD;BZ=function(k,l){var k,l;};CA=function(k,l){var k,l;};CD=function(k){var k;return(((k+4>>0)-1>>0))&-4;};CE=function(k){var k;return(((k+4>>0)-1>>0))&-4;};CF.ptr.prototype.toWireFormat=function(){var k,l;k=this;l=$makeSlice(PL,k.Header.Len);(($sliceToArray($subslice(l,0,4)))).$set(k.Header.Len);(($sliceToArray($subslice(l,4,6)))).$set(k.Header.Type);(($sliceToArray($subslice(l,6,8)))).$set(k.Header.Flags);(($sliceToArray($subslice(l,8,12)))).$set(k.Header.Seq);(($sliceToArray($subslice(l,12,16)))).$set(k.Header.Pid);(16>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+16]=(k.Data.Family));return l;};CF.prototype.toWireFormat=function(){return this.$val.toWireFormat();};CG=function(k,l,m){var k,l,m,n;n=new CF.ptr(new OS.ptr(0,0,0,0,0),new OU.ptr(0));n.Header.Len=17;n.Header.Type=((k<<16>>>16));n.Header.Flags=769;n.Header.Seq=((l>>>0));n.Data.Family=((m<<24>>>24));return n.toWireFormat();};CH=function(k,l){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);m=HO(16,3,0);n=m[0];o=m[1];if(!($interfaceIsEqual(o,$ifaceNil))){$s=-1;return[PL.nil,o];}$deferred.push([IR,[n]]);p=new EI.ptr(16,0,0,0,new OB.ptr(0,0,0,0));q=GZ(n,p);$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=q;if(!($interfaceIsEqual(r,$ifaceNil))){$s=-1;return[PL.nil,r];}s=CG(k,1,l);t=HE(n,s,0,p);$s=2;case 2:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}u=t;if(!($interfaceIsEqual(u,$ifaceNil))){$s=-1;return[PL.nil,u];}v=PL.nil;w=$makeSlice(PL,DF());done:while(true){x=w;y=HD(n,x,0);z=y[0];aa=y[2];if(!($interfaceIsEqual(aa,$ifaceNil))){$s=-1;return[PL.nil,aa];}if(z<16){$s=-1;return[PL.nil,new GN(22)];}x=$subslice(x,0,z);v=$appendSlice(v,x);ab=CJ(x);ac=ab[0];aa=ab[1];if(!($interfaceIsEqual(aa,$ifaceNil))){$s=-1;return[PL.nil,aa];}ad=ac;ae=0;while(true){if(!(ae<ad.$length)){break;}af=$clone(((ae<0||ae>=ad.$length)?($throwRuntimeError(\"index out of range\"),undefined):ad.$array[ad.$offset+ae]),CI);ag=EM(n);ah=ag[0];ai=ag[1];if(!($interfaceIsEqual(ai,$ifaceNil))){$s=-1;return[PL.nil,ai];}aj=ah;if($assertType(aj,QL,true)[1]){ak=aj.$val;if(!((af.Header.Seq===1))||!((af.Header.Pid===ak.Pid))){$s=-1;return[PL.nil,new GN(22)];}}else{al=aj;$s=-1;return[PL.nil,new GN(22)];}if(af.Header.Type===3){break done;}if(af.Header.Type===2){$s=-1;return[PL.nil,new GN(22)];}ae++;}}$s=-1;return[v,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[PL.nil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:CH};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};$pkg.NetlinkRIB=CH;CJ=function(k){var k,l,m,n,o,p,q,r;l=QM.nil;while(true){if(!(k.$length>=16)){break;}m=CK(k);n=m[0];o=m[1];p=m[2];q=m[3];if(!($interfaceIsEqual(q,$ifaceNil))){return[QM.nil,q];}r=new CI.ptr($clone(n,OS),$subslice(o,0,(((n.Len>>0))-16>>0)));l=$append(l,r);k=$subslice(k,p);}return[l,$ifaceNil];};$pkg.ParseNetlinkMessage=CJ;CK=function(k){var k,l,m,n,o,p;o=((l=($sliceToArray(k)),m=new OS.ptr(0,0,0,0,0),n=new DataView(l.buffer,l.byteOffset),m.Len=n.getUint32(0,true),m.Type=n.getUint16(4,true),m.Flags=n.getUint16(6,true),m.Seq=n.getUint32(8,true),m.Pid=n.getUint32(12,true),m));p=CD(((o.Len>>0)));if(((o.Len>>0))<16||p>k.$length){return[QN.nil,PL.nil,0,new GN(22)];}return[o,$subslice(k,16),p,$ifaceNil];};CM=function(k){var k,l,m,n,o,p,q,r,s,t;l=PL.nil;m=k.Header.Type;if((m===(16))||(m===(17))){l=$subslice(k.Data,16);}else if((m===(20))||(m===(21))){l=$subslice(k.Data,8);}else if((m===(24))||(m===(25))){l=$subslice(k.Data,12);}else{return[QO.nil,new GN(22)];}n=QO.nil;while(true){if(!(l.$length>=4)){break;}o=CN(l);p=o[0];q=o[1];r=o[2];s=o[3];if(!($interfaceIsEqual(s,$ifaceNil))){return[QO.nil,s];}t=new CL.ptr($clone(p,OW),$subslice(q,0,(((p.Len>>0))-4>>0)));n=$append(n,t);l=$subslice(l,r);}return[n,$ifaceNil];};$pkg.ParseNetlinkRouteAttr=CM;CN=function(k){var k,l,m,n,o;o=((l=($sliceToArray(k)),m=new OW.ptr(0,0),n=new DataView(l.buffer,l.byteOffset),m.Len=n.getUint16(0,true),m.Type=n.getUint16(2,true),m));if(((o.Len>>0))<4||((o.Len>>0))>k.$length){return[QP.nil,PL.nil,0,new GN(22)];}return[o,$subslice(k,4),CE(((o.Len>>0))),$ifaceNil];};CZ=function(k){var k;if(k<0){return\"-\"+DA(((-k>>>0)));}return DA(((k>>>0)));};DA=function(k){var k,l,m,n,o;l=QT.zero();m=31;while(true){if(!(k>=10)){break;}((m<0||m>=l.length)?($throwRuntimeError(\"index out of range\"),undefined):l[m]=((((n=k%10,n===n?n:$throwRuntimeError(\"integer divide by zero\"))+48>>>0)<<24>>>24)));m=m-(1)>>0;k=(o=k/(10),(o===o&&o!==1/0&&o!==-1/0)?o>>>0:$throwRuntimeError(\"integer divide by zero\"));}((m<0||m>=l.length)?($throwRuntimeError(\"index out of range\"),undefined):l[m]=(((k+48>>>0)<<24>>>24)));return($bytesToString($subslice(new PL(l),m)));};NJ.ptr.prototype.Unix=function(){var k,l,m,n,o;k=new $Int64(0,0);l=new $Int64(0,0);m=this;n=(m.Sec);o=(m.Nsec);k=n;l=o;return[k,l];};NJ.prototype.Unix=function(){return this.$val.Unix();};NJ.ptr.prototype.Nano=function(){var k,l,m;k=this;return(l=$mul64((k.Sec),new $Int64(0,1000000000)),m=(k.Nsec),new $Int64(l.$high+m.$high,l.$low+m.$low));};NJ.prototype.Nano=function(){return this.$val.Nano();};DF=function(){$throwRuntimeError(\"native function not implemented: syscall.Getpagesize\");};$pkg.Getpagesize=DF;DH=function(k,l){var k,l,m;m=$ifaceNil;m=DL(-100,k,l,0);return m;};$pkg.Chmod=DH;DL=function(k,l,m,n){var k,l,m,n,o;o=$ifaceNil;if(!((((n&~256)>>0)===0))){o=new GN(22);return o;}else if(!(((n&256)===0))){o=new GN(95);return o;}o=HZ(k,l,m);return o;};$pkg.Fchmodat=DL;DP=function(k,l,m){var k,l,m,n,o,p;n=0;o=$ifaceNil;p=IB(-100,k,l|0,m);n=p[0];o=p[1];return[n,o];};$pkg.Open=DP;GW.ptr.prototype.sockaddr=function(){var k,l,m,n,o,p,q,r,s;k=this;if(k.Port<0||k.Port>65535){return[0,0,new GN(22)];}k.raw.Family=2;m=(((l=k.raw,(l.$ptr_Port||(l.$ptr_Port=new QG(function(){return this.$target.Port;},function($v){this.$target.Port=$v;},l))))));m.nilCheck,m[0]=(((k.Port>>8>>0)<<24>>>24));m.nilCheck,m[1]=((k.Port<<24>>>24));n=0;while(true){if(!(n<4)){break;}(p=k.raw.Addr,((n<0||n>=p.length)?($throwRuntimeError(\"index out of range\"),undefined):p[n]=(o=k.Addr,((n<0||n>=o.length)?($throwRuntimeError(\"index out of range\"),undefined):o[n]))));n=n+(1)>>0;}q=new Uint8Array(16);return[(q),16,$ifaceNil];};GW.prototype.sockaddr=function(){return this.$val.sockaddr();};GX.ptr.prototype.sockaddr=function(){var k,l,m,n,o,p,q,r,s;k=this;if(k.Port<0||k.Port>65535){return[0,0,new GN(22)];}k.raw.Family=10;m=(((l=k.raw,(l.$ptr_Port||(l.$ptr_Port=new QG(function(){return this.$target.Port;},function($v){this.$target.Port=$v;},l))))));m.nilCheck,m[0]=(((k.Port>>8>>0)<<24>>>24));m.nilCheck,m[1]=((k.Port<<24>>>24));k.raw.Scope_id=k.ZoneId;n=0;while(true){if(!(n<16)){break;}(p=k.raw.Addr,((n<0||n>=p.length)?($throwRuntimeError(\"index out of range\"),undefined):p[n]=(o=k.Addr,((n<0||n>=o.length)?($throwRuntimeError(\"index out of range\"),undefined):o[n]))));n=n+(1)>>0;}q=new Uint8Array(28);return[(q),28,$ifaceNil];};GX.prototype.sockaddr=function(){return this.$val.sockaddr();};GY.ptr.prototype.sockaddr=function(){var k,l,m,n,o,p,q,r,s;k=this;l=k.Name;m=l.length;if(m>108){return[0,0,new GN(22)];}if((m===108)&&!((l.charCodeAt(0)===64))){return[0,0,new GN(22)];}k.raw.Family=1;n=0;while(true){if(!(n<m)){break;}(o=k.raw.Path,((n<0||n>=o.length)?($throwRuntimeError(\"index out of range\"),undefined):o[n]=((l.charCodeAt(n)<<24>>24))));n=n+(1)>>0;}p=2;if(m>0){p=p+((((m>>>0))+1>>>0))>>>0;}if(k.raw.Path[0]===64){k.raw.Path[0]=0;p=p-(1)>>>0;}q=new Uint8Array(110);return[(q),p,$ifaceNil];};GY.prototype.sockaddr=function(){return this.$val.sockaddr();};EH.ptr.prototype.sockaddr=function(){var k,l,m,n,o,p,q;k=this;if(k.Ifindex<0||k.Ifindex>2147483647){return[0,0,new GN(22)];}k.raw.Family=17;k.raw.Protocol=k.Protocol;k.raw.Ifindex=((k.Ifindex>>0));k.raw.Hatype=k.Hatype;k.raw.Pkttype=k.Pkttype;k.raw.Halen=k.Halen;l=0;while(true){if(!(l<8)){break;}(n=k.raw.Addr,((l<0||l>=n.length)?($throwRuntimeError(\"index out of range\"),undefined):n[l]=(m=k.Addr,((l<0||l>=m.length)?($throwRuntimeError(\"index out of range\"),undefined):m[l]))));l=l+(1)>>0;}o=new Uint8Array(20);return[(o),20,$ifaceNil];};EH.prototype.sockaddr=function(){return this.$val.sockaddr();};EI.ptr.prototype.sockaddr=function(){var k,l,m,n;k=this;k.raw.Family=16;k.raw.Pad=k.Pad;k.raw.Pid=k.Pid;k.raw.Groups=k.Groups;l=new Uint8Array(12);return[(l),12,$ifaceNil];};EI.prototype.sockaddr=function(){return this.$val.sockaddr();};EJ=function(k){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;l=k.Addr.Family;if(l===(16)){p=new Uint8Array(112);s=((m=(p),n=new OB.ptr(0,0,0,0),o=new DataView(m.buffer,m.byteOffset),n.Family=o.getUint16(0,true),n.Pad=o.getUint16(2,true),n.Pid=o.getUint32(4,true),n.Groups=o.getUint32(8,true),n));q=k,r=new DataView(p.buffer,p.byteOffset),q.Addr.Family=r.getUint16(0,true),q.Addr.Data=new($nativeArray($kindInt8))(p.buffer,$min(p.byteOffset+2,p.buffer.byteLength)),q.Pad=new($nativeArray($kindInt8))(p.buffer,$min(p.byteOffset+16,p.buffer.byteLength));t=new EI.ptr(0,0,0,0,new OB.ptr(0,0,0,0));t.Family=s.Family;t.Pad=s.Pad;t.Pid=s.Pid;t.Groups=s.Groups;return[t,$ifaceNil];}else if(l===(17)){x=new Uint8Array(112);aa=((u=(x),v=new OA.ptr(0,0,0,0,0,0,QF.zero()),w=new DataView(u.buffer,u.byteOffset),v.Family=w.getUint16(0,true),v.Protocol=w.getUint16(2,true),v.Ifindex=w.getInt32(4,true),v.Hatype=w.getUint16(8,true),v.Pkttype=w.getUint8(10,true),v.Halen=w.getUint8(11,true),v.Addr=new($nativeArray($kindUint8))(u.buffer,$min(u.byteOffset+12,u.buffer.byteLength)),v));y=k,z=new DataView(x.buffer,x.byteOffset),y.Addr.Family=z.getUint16(0,true),y.Addr.Data=new($nativeArray($kindInt8))(x.buffer,$min(x.byteOffset+2,x.buffer.byteLength)),y.Pad=new($nativeArray($kindInt8))(x.buffer,$min(x.byteOffset+16,x.buffer.byteLength));ab=new EH.ptr(0,0,0,0,0,QF.zero(),new OA.ptr(0,0,0,0,0,0,QF.zero()));ab.Protocol=aa.Protocol;ab.Ifindex=((aa.Ifindex>>0));ab.Hatype=aa.Hatype;ab.Pkttype=aa.Pkttype;ab.Halen=aa.Halen;ac=0;while(true){if(!(ac<8)){break;}(ae=ab.Addr,((ac<0||ac>=ae.length)?($throwRuntimeError(\"index out of range\"),undefined):ae[ac]=(ad=aa.Addr,((ac<0||ac>=ad.length)?($throwRuntimeError(\"index out of range\"),undefined):ad[ac]))));ac=ac+(1)>>0;}return[ab,$ifaceNil];}else if(l===(1)){ai=new Uint8Array(112);al=((af=(ai),ag=new NZ.ptr(0,RA.zero()),ah=new DataView(af.buffer,af.byteOffset),ag.Family=ah.getUint16(0,true),ag.Path=new($nativeArray($kindInt8))(af.buffer,$min(af.byteOffset+2,af.buffer.byteLength)),ag));aj=k,ak=new DataView(ai.buffer,ai.byteOffset),aj.Addr.Family=ak.getUint16(0,true),aj.Addr.Data=new($nativeArray($kindInt8))(ai.buffer,$min(ai.byteOffset+2,ai.buffer.byteLength)),aj.Pad=new($nativeArray($kindInt8))(ai.buffer,$min(ai.byteOffset+16,ai.buffer.byteLength));am=new GY.ptr(\"\",new NZ.ptr(0,RA.zero()));if(al.Path[0]===0){al.Path[0]=64;}an=0;while(true){if(!(an<108&&!(((ao=al.Path,((an<0||an>=ao.length)?($throwRuntimeError(\"index out of range\"),undefined):ao[an]))===0)))){break;}an=an+(1)>>0;}ap=$subslice(new PL((($sliceToArray(new PL(al.Path))))),0,an);am.Name=($bytesToString(ap));return[am,$ifaceNil];}else if(l===(2)){at=new Uint8Array(112);aw=((aq=(at),ar=new NX.ptr(0,0,RB.zero(),QF.zero()),as=new DataView(aq.buffer,aq.byteOffset),ar.Family=as.getUint16(0,true),ar.Port=as.getUint16(2,true),ar.Addr=new($nativeArray($kindUint8))(aq.buffer,$min(aq.byteOffset+4,aq.buffer.byteLength)),ar.Zero=new($nativeArray($kindUint8))(aq.buffer,$min(aq.byteOffset+8,aq.buffer.byteLength)),ar));au=k,av=new DataView(at.buffer,at.byteOffset),au.Addr.Family=av.getUint16(0,true),au.Addr.Data=new($nativeArray($kindInt8))(at.buffer,$min(at.byteOffset+2,at.buffer.byteLength)),au.Pad=new($nativeArray($kindInt8))(at.buffer,$min(at.byteOffset+16,at.buffer.byteLength));ax=new GW.ptr(0,RB.zero(),new NX.ptr(0,0,RB.zero(),QF.zero()));ay=(((aw.$ptr_Port||(aw.$ptr_Port=new QG(function(){return this.$target.Port;},function($v){this.$target.Port=$v;},aw)))));ax.Port=((((ay.nilCheck,ay[0])>>0))<<8>>0)+(((ay.nilCheck,ay[1])>>0))>>0;az=0;while(true){if(!(az<4)){break;}(bb=ax.Addr,((az<0||az>=bb.length)?($throwRuntimeError(\"index out of range\"),undefined):bb[az]=(ba=aw.Addr,((az<0||az>=ba.length)?($throwRuntimeError(\"index out of range\"),undefined):ba[az]))));az=az+(1)>>0;}return[ax,$ifaceNil];}else if(l===(10)){bf=new Uint8Array(112);bi=((bc=(bf),bd=new NY.ptr(0,0,0,QH.zero(),0),be=new DataView(bc.buffer,bc.byteOffset),bd.Family=be.getUint16(0,true),bd.Port=be.getUint16(2,true),bd.Flowinfo=be.getUint32(4,true),bd.Addr=new($nativeArray($kindUint8))(bc.buffer,$min(bc.byteOffset+8,bc.buffer.byteLength)),bd.Scope_id=be.getUint32(24,true),bd));bg=k,bh=new DataView(bf.buffer,bf.byteOffset),bg.Addr.Family=bh.getUint16(0,true),bg.Addr.Data=new($nativeArray($kindInt8))(bf.buffer,$min(bf.byteOffset+2,bf.buffer.byteLength)),bg.Pad=new($nativeArray($kindInt8))(bf.buffer,$min(bf.byteOffset+16,bf.buffer.byteLength));bj=new GX.ptr(0,0,QH.zero(),new NY.ptr(0,0,0,QH.zero(),0));bk=(((bi.$ptr_Port||(bi.$ptr_Port=new QG(function(){return this.$target.Port;},function($v){this.$target.Port=$v;},bi)))));bj.Port=((((bk.nilCheck,bk[0])>>0))<<8>>0)+(((bk.nilCheck,bk[1])>>0))>>0;bj.ZoneId=bi.Scope_id;bl=0;while(true){if(!(bl<16)){break;}(bn=bj.Addr,((bl<0||bl>=bn.length)?($throwRuntimeError(\"index out of range\"),undefined):bn[bl]=(bm=bi.Addr,((bl<0||bl>=bm.length)?($throwRuntimeError(\"index out of range\"),undefined):bm[bl]))));bl=bl+(1)>>0;}return[bj,$ifaceNil];}return[$ifaceNil,new GN(97)];};EK=function(k){var k,l,m,n,o,p,q,r,s;l=0;m=$ifaceNil;n=$ifaceNil;o=new OD.ptr(new OC.ptr(0,RC.zero()),RD.zero());p=112;q=MK(k,o,(r||(r=new RE(function(){return p;},function($v){p=$v;}))));l=q[0];n=q[1];if(!($interfaceIsEqual(n,$ifaceNil))){return[l,m,n];}s=EJ(o);m=s[0];n=s[1];if(!($interfaceIsEqual(n,$ifaceNil))){IR(l);l=0;}return[l,m,n];};$pkg.Accept=EK;EL=function(k,l){var k,l,m,n,o,p,q,r,s,t;m=0;n=$ifaceNil;o=$ifaceNil;p=new OD.ptr(new OC.ptr(0,RC.zero()),RD.zero());q=112;r=ML(k,p,(s||(s=new RE(function(){return q;},function($v){q=$v;}))),l);m=r[0];o=r[1];if(!($interfaceIsEqual(o,$ifaceNil))){return[m,n,o];}if(q>112){$panic(new $String(\"RawSockaddrAny too small\"));}t=EJ(p);n=t[0];o=t[1];if(!($interfaceIsEqual(o,$ifaceNil))){IR(m);m=0;}return[m,n,o];};$pkg.Accept4=EL;EM=function(k){var k,l,m,n,o,p,q;l=$ifaceNil;m=$ifaceNil;n=new OD.ptr(new OC.ptr(0,RC.zero()),RD.zero());o=112;m=MW(k,n,(p||(p=new RE(function(){return o;},function($v){o=$v;}))));if(!($interfaceIsEqual(m,$ifaceNil))){return[l,m];}q=EJ(n);l=q[0];m=q[1];return[l,m];};$pkg.Getsockname=EM;EU=function(k,l,m,n){var k,l,m,n,o,p,q,r;o=$ifaceNil;p=new Uint8Array(12);o=MS(k,l,m,(p),12);q=n,r=new DataView(p.buffer,p.byteOffset),q.Multiaddr=new($nativeArray($kindUint8))(p.buffer,$min(p.byteOffset+0,p.buffer.byteLength)),q.Address=new($nativeArray($kindUint8))(p.buffer,$min(p.byteOffset+4,p.buffer.byteLength)),q.Ifindex=r.getInt32(8,true);return o;};$pkg.SetsockoptIPMreqn=EU;EV=function(k,l,m,n){var aa,ab,ac,ad,ae,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;o=0;p=0;q=0;r=$ifaceNil;s=$ifaceNil;t=new OK.ptr(PV.nil,0,RB.zero(),RG.nil,new $Uint64(0,0),PV.nil,new $Uint64(0,0),0,RB.zero());u=new OD.ptr(new OC.ptr(0,RC.zero()),RD.zero());v=new Uint8Array(112);t.Name=((v));w=u,x=new DataView(v.buffer,v.byteOffset),w.Addr.Family=x.getUint16(0,true),w.Addr.Data=new($nativeArray($kindInt8))(v.buffer,$min(v.byteOffset+2,v.buffer.byteLength)),w.Pad=new($nativeArray($kindInt8))(v.buffer,$min(v.byteOffset+16,v.buffer.byteLength));t.Namelen=112;y=new OG.ptr(PV.nil,new $Uint64(0,0));if(l.$length>0){y.Base=$indexPtr(l.$array,l.$offset+0,PV);y.SetLen(l.$length);}z=0;if(m.$length>0){if(l.$length===0){aa=0;ab=HC(k,1,3);aa=ab[0];s=ab[1];if(!($interfaceIsEqual(s,$ifaceNil))){return[o,p,q,r,s];}if(!((aa===2))){y.Base=(ac||(ac=new PV(function(){return z;},function($v){z=$v;})));y.SetLen(1);}}t.Control=$indexPtr(m.$array,m.$offset+0,PV);t.SetControllen(m.$length);}t.Iov=y;t.Iovlen=new $Uint64(0,1);ad=MZ(k,t,n);o=ad[0];s=ad[1];if(!($interfaceIsEqual(s,$ifaceNil))){return[o,p,q,r,s];}p=((t.Controllen.$low>>0));q=((t.Flags>>0));if(!((u.Addr.Family===0))){ae=EJ(u);r=ae[0];s=ae[1];}return[o,p,q,r,s];};$pkg.Recvmsg=EV;EX=function(k,l,m,n,o){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:p=[p];q=[q];r=[r];s=0;t=$ifaceNil;u=0;v=0;if(!($interfaceIsEqual(n,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:w=$ifaceNil;y=n.sockaddr();$s=3;case 3:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;u=x[0];v=x[1];w=x[2];if(!($interfaceIsEqual(w,$ifaceNil))){z=0;aa=w;s=z;t=aa;$s=-1;return[s,t];}case 2:r[0]=new OK.ptr(PV.nil,0,RB.zero(),RG.nil,new $Uint64(0,0),PV.nil,new $Uint64(0,0),0,RB.zero());r[0].Name=(u);r[0].Namelen=((v>>>0));q[0]=new OG.ptr(PV.nil,new $Uint64(0,0));if(l.$length>0){q[0].Base=$indexPtr(l.$array,l.$offset+0,PV);q[0].SetLen(l.$length);}p[0]=0;if(m.$length>0){if(l.$length===0){ab=0;ac=HC(k,1,3);ab=ac[0];t=ac[1];if(!($interfaceIsEqual(t,$ifaceNil))){ad=0;ae=t;s=ad;t=ae;$s=-1;return[s,t];}if(!((ab===2))){q[0].Base=(p.$ptr||(p.$ptr=new PV(function(){return this.$target[0];},function($v){this.$target[0]=$v;},p)));q[0].SetLen(1);}}r[0].Control=$indexPtr(m.$array,m.$offset+0,PV);r[0].SetControllen(m.$length);}r[0].Iov=q[0];r[0].Iovlen=new $Uint64(0,1);af=NA(k,r[0],o);s=af[0];t=af[1];if(!($interfaceIsEqual(t,$ifaceNil))){ag=0;ah=t;s=ag;t=ah;$s=-1;return[s,t];}if(m.$length>0&&(l.$length===0)){s=0;}ai=s;aj=$ifaceNil;s=ai;t=aj;$s=-1;return[s,t];}return;}if($f===undefined){$f={$blk:EX};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$pkg.SendmsgN=EX;FP=function(k,l){var k,l,m,n,o;m=0;n=$ifaceNil;o=JF(k,l);m=o[0];n=o[1];return[m,n];};$pkg.ReadDirent=FP;FQ=function(k){var k;return Z(k,0,8);};FR=function(k){var k;return Z(k,16,2);};FS=function(k){var k,l,m,n;l=FR(k);m=l[0];n=l[1];if(!n){return[new $Uint64(0,0),false];}return[new $Uint64(m.$high-0,m.$low-19),true];};GA=function(k,l){var k,l,m;m=$ifaceNil;m=MO(-100,k,l,0);return m;};$pkg.Stat=GA;GC=function(k,l){var k,l,m;m=$ifaceNil;m=MO(-100,k,l,256);return m;};$pkg.Lstat=GC;OG.ptr.prototype.SetLen=function(k){var k,l;l=this;l.Len=(new $Uint64(0,k));};OG.prototype.SetLen=function(k){return this.$val.SetLen(k);};OK.ptr.prototype.SetControllen=function(k){var k,l;l=this;l.Controllen=(new $Uint64(0,k));};OK.prototype.SetControllen=function(k){return this.$val.SetControllen(k);};GM.ptr.prototype.Mmap=function(k,l,m,n,o){var aa,ab,ac,ad,ae,af,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);p=[p];q=PL.nil;r=$ifaceNil;s=this;if(m<=0){t=PL.nil;u=new GN(22);q=t;r=u;$s=-1;return[q,r];}w=s.mmap(0,((m>>>0)),n,o,k,l);$s=1;case 1:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}v=w;x=v[0];y=v[1];if(!($interfaceIsEqual(y,$ifaceNil))){z=PL.nil;aa=y;q=z;r=aa;$s=-1;return[q,r];}p[0]=new RK.ptr(x,m,m);ab=p[0];ac=$indexPtr(ab.$array,ab.$offset+(ab.$capacity-1>>0),PV);$r=s.Mutex.Lock();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(s.Mutex,\"Unlock\"),[]]);ad=ac;(s.active||$throwRuntimeError(\"assignment to entry in nil map\"))[PV.keyFor(ad)]={k:ad,v:ab};ae=ab;af=$ifaceNil;q=ae;r=af;$s=-1;return[q,r];}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return[q,r];}if($curGoroutine.asleep){if($f===undefined){$f={$blk:GM.ptr.prototype.Mmap};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};GM.prototype.Mmap=function(k,l,m,n,o){return this.$val.Mmap(k,l,m,n,o);};GM.ptr.prototype.Munmap=function(k){var k,l,m,n,o,p,q,r,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);l=$ifaceNil;m=this;if((k.$length===0)||!((k.$length===k.$capacity))){l=new GN(22);$s=-1;return l;}n=$indexPtr(k.$array,k.$offset+(k.$capacity-1>>0),PV);$r=m.Mutex.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(m.Mutex,\"Unlock\"),[]]);p=(o=m.active[PV.keyFor(n)],o!==undefined?o.v:PL.nil);if(p===PL.nil||!($indexPtr(p.$array,p.$offset+0,PV)===$indexPtr(k.$array,k.$offset+0,PV))){l=new GN(22);$s=-1;return l;}q=m.munmap((($sliceToArray(p))),((p.$length>>>0)));$s=2;case 2:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=q;if(!($interfaceIsEqual(r,$ifaceNil))){l=r;$s=-1;return l;}delete m.active[PV.keyFor(n)];l=$ifaceNil;$s=-1;return l;}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return l;}if($curGoroutine.asleep){if($f===undefined){$f={$blk:GM.ptr.prototype.Munmap};}$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};GM.prototype.Munmap=function(k){return this.$val.Munmap(k);};GN.prototype.Error=function(){var k,l;k=this.$val;if(0<=((k>>0))&&((k>>0))<133){l=((k<0||k>=HW.length)?($throwRuntimeError(\"index out of range\"),undefined):HW[k]);if(!(l===\"\")){return l;}}return\"errno \"+CZ(((k>>0)));};$ptrType(GN).prototype.Error=function(){return new GN(this.$get()).Error();};GN.prototype.Temporary=function(){var k;k=this.$val;return(k===4)||(k===24)||new GN(k).Timeout();};$ptrType(GN).prototype.Temporary=function(){return new GN(this.$get()).Temporary();};GN.prototype.Timeout=function(){var k;k=this.$val;return(k===11)||(k===11)||(k===110);};$ptrType(GN).prototype.Timeout=function(){return new GN(this.$get()).Timeout();};GR=function(k){var k,l;l=k;if(l===(0)){return $ifaceNil;}else if(l===(11)){return GO;}else if(l===(22)){return GP;}else if(l===(2)){return GQ;}return new GN(k);};GT=function(k,l){var k,l,m,n,o;m=0;n=$ifaceNil;o=JZ(k,l);m=o[0];n=o[1];if(false){if(m>0){D.WriteRange(($sliceToArray(l)),m);}if($interfaceIsEqual(n,$ifaceNil)){D.Acquire(((PU||(PU=new RL(function(){return HR;},function($v){HR=$v;})))));}}if(false&&m>0){CA(($sliceToArray(l)),m);}return[m,n];};$pkg.Read=GT;GU=function(k,l){var k,l,m,n,o;m=0;n=$ifaceNil;if(false){D.ReleaseMerge(((PU||(PU=new RL(function(){return HR;},function($v){HR=$v;})))));}o=KU(k,l);m=o[0];n=o[1];if(false&&m>0){D.ReadRange(($sliceToArray(l)),m);}if(false&&m>0){BZ(($sliceToArray(l)),m);}return[m,n];};$pkg.Write=GU;GZ=function(k,l){var k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:m=$ifaceNil;o=l.sockaddr();$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;p=n[0];q=n[1];m=n[2];if(!($interfaceIsEqual(m,$ifaceNil))){m=m;$s=-1;return m;}m=MM(k,p,q);$s=-1;return m;}return;}if($f===undefined){$f={$blk:GZ};}$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Bind=GZ;HC=function(k,l,m){var k,l,m,n,o,p,q,r,s,t,u;n=0;o=$ifaceNil;p=0;q=4;o=MR(k,l,m,((r||(r=new PZ(function(){return p;},function($v){p=$v;})))),(s||(s=new RE(function(){return q;},function($v){q=$v;}))));t=((p>>0));u=o;n=t;o=u;return[n,o];};$pkg.GetsockoptInt=HC;HD=function(k,l,m){var k,l,m,n,o,p,q,r,s,t,u;n=0;o=$ifaceNil;p=$ifaceNil;q=new OD.ptr(new OC.ptr(0,RC.zero()),RD.zero());r=112;s=MX(k,l,m,q,(t||(t=new RE(function(){return r;},function($v){r=$v;}))));n=s[0];p=s[1];if(!($interfaceIsEqual(p,$ifaceNil))){return[n,o,p];}if(!((q.Addr.Family===0))){u=EJ(q);o=u[0];p=u[1];}return[n,o,p];};$pkg.Recvfrom=HD;HE=function(k,l,m,n){var k,l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:o=$ifaceNil;q=n.sockaddr();$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;r=p[0];s=p[1];o=p[2];if(!($interfaceIsEqual(o,$ifaceNil))){o=o;$s=-1;return o;}o=MY(k,l,m,r,s);$s=-1;return o;}return;}if($f===undefined){$f={$blk:HE};}$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Sendto=HE;HF=function(k,l,m,n){var k,l,m,n,o,p;o=$ifaceNil;o=MS(k,l,m,((p||(p=new PV(function(){return n;},function($v){n=$v;})))),1);return o;};$pkg.SetsockoptByte=HF;HG=function(k,l,m,n){var k,l,m,n,o,p,q;o=$ifaceNil;p=((n>>0));o=MS(k,l,m,((q||(q=new PZ(function(){return p;},function($v){p=$v;})))),4);return o;};$pkg.SetsockoptInt=HG;HH=function(k,l,m,n){var k,l,m,n,o;o=$ifaceNil;o=MS(k,l,m,($sliceToArray(new PL(n))),4);return o;};$pkg.SetsockoptInet4Addr=HH;HI=function(k,l,m,n){var k,l,m,n,o,p,q,r;o=$ifaceNil;p=new Uint8Array(8);o=MS(k,l,m,(p),8);q=n,r=new DataView(p.buffer,p.byteOffset),q.Multiaddr=new($nativeArray($kindUint8))(p.buffer,$min(p.byteOffset+0,p.buffer.byteLength)),q.Interface=new($nativeArray($kindUint8))(p.buffer,$min(p.byteOffset+4,p.buffer.byteLength));return o;};$pkg.SetsockoptIPMreq=HI;HJ=function(k,l,m,n){var k,l,m,n,o,p,q,r;o=$ifaceNil;p=new Uint8Array(20);o=MS(k,l,m,(p),20);q=n,r=new DataView(p.buffer,p.byteOffset),q.Multiaddr=new($nativeArray($kindUint8))(p.buffer,$min(p.byteOffset+0,p.buffer.byteLength)),q.Interface=r.getUint32(16,true);return o;};$pkg.SetsockoptIPv6Mreq=HJ;HL=function(k,l,m,n){var k,l,m,n,o,p,q,r;o=$ifaceNil;p=new Uint8Array(8);o=MS(k,l,m,(p),8);q=n,r=new DataView(p.buffer,p.byteOffset),q.Onoff=r.getInt32(0,true),q.Linger=r.getInt32(4,true);return o;};$pkg.SetsockoptLinger=HL;HO=function(k,l,m){var k,l,m,n,o,p,q,r;n=0;o=$ifaceNil;if((k===10)&&$pkg.SocketDisableIPv6){p=-1;q=new GN(97);n=p;o=q;return[n,o];}r=MT(k,l,m);n=r[0];o=r[1];return[n,o];};$pkg.Socket=HO;HZ=function(k,l,m){var k,l,m,n,o,p,q,r;n=$ifaceNil;o=PV.nil;p=Y(l);o=p[0];n=p[1];if(!($interfaceIsEqual(n,$ifaceNil))){return n;}q=T(268,((k>>>0)),((o)),((m>>>0)));r=q[2];if(!((r===0))){n=GR(r);}return n;};IB=function(k,l,m,n){var k,l,m,n,o,p,q,r,s,t,u;o=0;p=$ifaceNil;q=PV.nil;r=Y(l);q=r[0];p=r[1];if(!($interfaceIsEqual(p,$ifaceNil))){return[o,p];}s=U(257,((k>>>0)),((q)),((m>>>0)),((n>>>0)),0,0);t=s[0];u=s[2];o=((t>>0));if(!((u===0))){p=GR(u);}return[o,p];};IR=function(k){var k,l,m,n;l=$ifaceNil;m=T(3,((k>>>0)),0,0);n=m[2];if(!((n===0))){l=GR(n);}return l;};$pkg.Close=IR;IS=function(k){var k,l,m,n,o,p;l=0;m=$ifaceNil;n=T(32,((k>>>0)),0,0);o=n[0];p=n[2];l=((o>>0));if(!((p===0))){m=GR(p);}return[l,m];};$pkg.Dup=IS;IY=function(k){var k,l,m,n;l=$ifaceNil;m=T(81,((k>>>0)),0,0);n=m[2];if(!((n===0))){l=GR(n);}return l;};$pkg.Fchdir=IY;IZ=function(k,l){var k,l,m,n,o;m=$ifaceNil;n=T(91,((k>>>0)),((l>>>0)),0);o=n[2];if(!((o===0))){m=GR(o);}return m;};$pkg.Fchmod=IZ;JB=function(k,l,m){var k,l,m,n,o,p,q,r;n=0;o=$ifaceNil;p=T(72,((k>>>0)),((l>>>0)),((m>>>0)));q=p[0];r=p[2];n=((q>>0));if(!((r===0))){o=GR(r);}return[n,o];};JE=function(k){var k,l,m,n;l=$ifaceNil;m=T(74,((k>>>0)),0,0);n=m[2];if(!((n===0))){l=GR(n);}return l;};$pkg.Fsync=JE;JF=function(k,l){var k,l,m,n,o,p,q,r;m=0;n=$ifaceNil;o=0;if(l.$length>0){o=($sliceToArray(l));}else{o=(new Uint8Array(0));}p=T(217,((k>>>0)),(o),((l.$length>>>0)));q=p[0];r=p[2];m=((q>>0));if(!((r===0))){n=GR(r);}return[m,n];};$pkg.Getdents=JF;JZ=function(k,l){var k,l,m,n,o,p,q,r;m=0;n=$ifaceNil;o=0;if(l.$length>0){o=($sliceToArray(l));}else{o=(new Uint8Array(0));}p=T(0,((k>>>0)),(o),((l.$length>>>0)));q=p[0];r=p[2];m=((q>>0));if(!((r===0))){n=GR(r);}return[m,n];};KU=function(k,l){var k,l,m,n,o,p,q,r;m=0;n=$ifaceNil;o=0;if(l.$length>0){o=($sliceToArray(l));}else{o=(new Uint8Array(0));}p=T(1,((k>>>0)),(o),((l.$length>>>0)));q=p[0];r=p[2];m=((q>>0));if(!((r===0))){n=GR(r);}return[m,n];};KY=function(k,l){var k,l,m,n,o;m=$ifaceNil;n=T(11,(k),(l),0);o=n[2];if(!((o===0))){m=GR(o);}return m;};LG=function(k,l,m){var k,l,m,n,o,p;n=$ifaceNil;o=T(93,((k>>>0)),((l>>>0)),((m>>>0)));p=o[2];if(!((p===0))){n=GR(p);}return n;};$pkg.Fchown=LG;LH=function(k,l){var k,l,m,n,o,p,q,r;m=$ifaceNil;o=new Uint8Array(144);n=T(5,((k>>>0)),((o)),0);p=l,q=new DataView(o.buffer,o.byteOffset),p.Dev=new $Uint64(q.getUint32(4,true),q.getUint32(0,true)),p.Ino=new $Uint64(q.getUint32(12,true),q.getUint32(8,true)),p.Nlink=new $Uint64(q.getUint32(20,true),q.getUint32(16,true)),p.Mode=q.getUint32(24,true),p.Uid=q.getUint32(28,true),p.Gid=q.getUint32(32,true),p.X__pad0=q.getInt32(36,true),p.Rdev=new $Uint64(q.getUint32(44,true),q.getUint32(40,true)),p.Size=new $Int64(q.getUint32(52,true),q.getUint32(48,true)),p.Blksize=new $Int64(q.getUint32(60,true),q.getUint32(56,true)),p.Blocks=new $Int64(q.getUint32(68,true),q.getUint32(64,true)),p.Atim.Sec=new $Int64(q.getUint32(76,true),q.getUint32(72,true)),p.Atim.Nsec=new $Int64(q.getUint32(84,true),q.getUint32(80,true)),p.Mtim.Sec=new $Int64(q.getUint32(92,true),q.getUint32(88,true)),p.Mtim.Nsec=new $Int64(q.getUint32(100,true),q.getUint32(96,true)),p.Ctim.Sec=new $Int64(q.getUint32(108,true),q.getUint32(104,true)),p.Ctim.Nsec=new $Int64(q.getUint32(116,true),q.getUint32(112,true)),p.X__unused=new($nativeArray($kindInt64))(o.buffer,$min(o.byteOffset+120,o.buffer.byteLength));r=n[2];if(!((r===0))){m=GR(r);}return m;};$pkg.Fstat=LH;LJ=function(k,l){var k,l,m,n,o;m=$ifaceNil;n=T(77,((k>>>0)),((l.$low>>>0)),0);o=n[2];if(!((o===0))){m=GR(o);}return m;};$pkg.Ftruncate=LJ;LT=function(k,l,m){var k,l,m,n,o,p,q,r,s;n=0;o=$ifaceNil;p=0;if(l.$length>0){p=($sliceToArray(l));}else{p=(new Uint8Array(0));}q=U(17,((k>>>0)),(p),((l.$length>>>0)),((m.$low>>>0)),0,0);r=q[0];s=q[2];n=((r>>0));if(!((s===0))){o=GR(s);}return[n,o];};$pkg.Pread=LT;LU=function(k,l,m){var k,l,m,n,o,p,q,r,s;n=0;o=$ifaceNil;p=0;if(l.$length>0){p=($sliceToArray(l));}else{p=(new Uint8Array(0));}q=U(18,((k>>>0)),(p),((l.$length>>>0)),((m.$low>>>0)),0,0);r=q[0];s=q[2];n=((r>>0));if(!((s===0))){o=GR(s);}return[n,o];};$pkg.Pwrite=LU;LV=function(k,l,m){var k,l,m,n,o,p,q,r;n=new $Int64(0,0);o=$ifaceNil;p=T(8,((k>>>0)),((l.$low>>>0)),((m>>>0)));q=p[0];r=p[2];n=(new $Int64(0,q.constructor===Number?q:1));if(!((r===0))){o=GR(r);}return[n,o];};$pkg.Seek=LV;MF=function(k,l){var k,l,m,n,o;m=$ifaceNil;n=T(48,((k>>>0)),((l>>>0)),0);o=n[2];if(!((o===0))){m=GR(o);}return m;};$pkg.Shutdown=MF;MK=function(k,l,m){var k,l,m,n,o,p,q,r,s,t,u;n=0;o=$ifaceNil;q=new Uint8Array(112);p=T(43,((k>>>0)),((q)),((m)));r=l,s=new DataView(q.buffer,q.byteOffset),r.Addr.Family=s.getUint16(0,true),r.Addr.Data=new($nativeArray($kindInt8))(q.buffer,$min(q.byteOffset+2,q.buffer.byteLength)),r.Pad=new($nativeArray($kindInt8))(q.buffer,$min(q.byteOffset+16,q.buffer.byteLength));t=p[0];u=p[2];n=((t>>0));if(!((u===0))){o=GR(u);}return[n,o];};ML=function(k,l,m,n){var k,l,m,n,o,p,q,r,s,t,u,v;o=0;p=$ifaceNil;r=new Uint8Array(112);q=U(288,((k>>>0)),((r)),((m)),((n>>>0)),0,0);s=l,t=new DataView(r.buffer,r.byteOffset),s.Addr.Family=t.getUint16(0,true),s.Addr.Data=new($nativeArray($kindInt8))(r.buffer,$min(r.byteOffset+2,r.buffer.byteLength)),s.Pad=new($nativeArray($kindInt8))(r.buffer,$min(r.byteOffset+16,r.buffer.byteLength));u=q[0];v=q[2];o=((u>>0));if(!((v===0))){p=GR(v);}return[o,p];};MM=function(k,l,m){var k,l,m,n,o,p;n=$ifaceNil;o=T(49,((k>>>0)),(l),((m>>>0)));p=o[2];if(!((p===0))){n=GR(p);}return n;};MO=function(k,l,m,n){var k,l,m,n,o,p,q,r,s,t,u,v;o=$ifaceNil;p=PV.nil;q=Y(l);p=q[0];o=q[1];if(!($interfaceIsEqual(o,$ifaceNil))){return o;}s=new Uint8Array(144);r=U(262,((k>>>0)),((p)),((s)),((n>>>0)),0,0);t=m,u=new DataView(s.buffer,s.byteOffset),t.Dev=new $Uint64(u.getUint32(4,true),u.getUint32(0,true)),t.Ino=new $Uint64(u.getUint32(12,true),u.getUint32(8,true)),t.Nlink=new $Uint64(u.getUint32(20,true),u.getUint32(16,true)),t.Mode=u.getUint32(24,true),t.Uid=u.getUint32(28,true),t.Gid=u.getUint32(32,true),t.X__pad0=u.getInt32(36,true),t.Rdev=new $Uint64(u.getUint32(44,true),u.getUint32(40,true)),t.Size=new $Int64(u.getUint32(52,true),u.getUint32(48,true)),t.Blksize=new $Int64(u.getUint32(60,true),u.getUint32(56,true)),t.Blocks=new $Int64(u.getUint32(68,true),u.getUint32(64,true)),t.Atim.Sec=new $Int64(u.getUint32(76,true),u.getUint32(72,true)),t.Atim.Nsec=new $Int64(u.getUint32(84,true),u.getUint32(80,true)),t.Mtim.Sec=new $Int64(u.getUint32(92,true),u.getUint32(88,true)),t.Mtim.Nsec=new $Int64(u.getUint32(100,true),u.getUint32(96,true)),t.Ctim.Sec=new $Int64(u.getUint32(108,true),u.getUint32(104,true)),t.Ctim.Nsec=new $Int64(u.getUint32(116,true),u.getUint32(112,true)),t.X__unused=new($nativeArray($kindInt64))(s.buffer,$min(s.byteOffset+120,s.buffer.byteLength));v=r[2];if(!((v===0))){o=GR(v);}return o;};MR=function(k,l,m,n,o){var k,l,m,n,o,p,q,r;p=$ifaceNil;q=U(55,((k>>>0)),((l>>>0)),((m>>>0)),(n),((o)),0);r=q[2];if(!((r===0))){p=GR(r);}return p;};MS=function(k,l,m,n,o){var k,l,m,n,o,p,q,r;p=$ifaceNil;q=U(54,((k>>>0)),((l>>>0)),((m>>>0)),(n),(o),0);r=q[2];if(!((r===0))){p=GR(r);}return p;};MT=function(k,l,m){var k,l,m,n,o,p,q,r;n=0;o=$ifaceNil;p=V(41,((k>>>0)),((l>>>0)),((m>>>0)));q=p[0];r=p[2];n=((q>>0));if(!((r===0))){o=GR(r);}return[n,o];};MW=function(k,l,m){var k,l,m,n,o,p,q,r,s;n=$ifaceNil;p=new Uint8Array(112);o=V(51,((k>>>0)),((p)),((m)));q=l,r=new DataView(p.buffer,p.byteOffset),q.Addr.Family=r.getUint16(0,true),q.Addr.Data=new($nativeArray($kindInt8))(p.buffer,$min(p.byteOffset+2,p.buffer.byteLength)),q.Pad=new($nativeArray($kindInt8))(p.buffer,$min(p.byteOffset+16,p.buffer.byteLength));s=o[2];if(!((s===0))){n=GR(s);}return n;};MX=function(k,l,m,n,o){var k,l,m,n,o,p,q,r,s,t,u,v,w,x;p=0;q=$ifaceNil;r=0;if(l.$length>0){r=($sliceToArray(l));}else{r=(new Uint8Array(0));}t=new Uint8Array(112);s=U(45,((k>>>0)),(r),((l.$length>>>0)),((m>>>0)),((t)),((o)));u=n,v=new DataView(t.buffer,t.byteOffset),u.Addr.Family=v.getUint16(0,true),u.Addr.Data=new($nativeArray($kindInt8))(t.buffer,$min(t.byteOffset+2,t.buffer.byteLength)),u.Pad=new($nativeArray($kindInt8))(t.buffer,$min(t.byteOffset+16,t.buffer.byteLength));w=s[0];x=s[2];p=((w>>0));if(!((x===0))){q=GR(x);}return[p,q];};MY=function(k,l,m,n,o){var k,l,m,n,o,p,q,r,s;p=$ifaceNil;q=0;if(l.$length>0){q=($sliceToArray(l));}else{q=(new Uint8Array(0));}r=U(44,((k>>>0)),(q),((l.$length>>>0)),((m>>>0)),(n),((o>>>0)));s=r[2];if(!((s===0))){p=GR(s);}return p;};MZ=function(k,l,m){var k,l,m,n,o,p,q,r,s,t,u;n=0;o=$ifaceNil;q=new Uint8Array(48);p=T(47,((k>>>0)),((q)),((m>>>0)));r=l,s=new DataView(q.buffer,q.byteOffset),r.Namelen=s.getUint32(4,true),r.Pad_cgo_0=new($nativeArray($kindUint8))(q.buffer,$min(q.byteOffset+8,q.buffer.byteLength)),r.Iovlen=new $Uint64(s.getUint32(20,true),s.getUint32(16,true)),r.Controllen=new $Uint64(s.getUint32(36,true),s.getUint32(32,true)),r.Flags=s.getInt32(40,true),r.Pad_cgo_1=new($nativeArray($kindUint8))(q.buffer,$min(q.byteOffset+44,q.buffer.byteLength));t=p[0];u=p[2];n=((t>>0));if(!((u===0))){o=GR(u);}return[n,o];};NA=function(k,l,m){var k,l,m,n,o,p,q,r,s,t,u;n=0;o=$ifaceNil;q=new Uint8Array(48);p=T(46,((k>>>0)),((q)),((m>>>0)));r=l,s=new DataView(q.buffer,q.byteOffset),r.Namelen=s.getUint32(4,true),r.Pad_cgo_0=new($nativeArray($kindUint8))(q.buffer,$min(q.byteOffset+8,q.buffer.byteLength)),r.Iovlen=new $Uint64(s.getUint32(20,true),s.getUint32(16,true)),r.Controllen=new $Uint64(s.getUint32(36,true),s.getUint32(32,true)),r.Flags=s.getInt32(40,true),r.Pad_cgo_1=new($nativeArray($kindUint8))(q.buffer,$min(q.byteOffset+44,q.buffer.byteLength));t=p[0];u=p[2];n=((t>>0));if(!((u===0))){o=GR(u);}return[n,o];};NB=function(k,l,m,n,o,p){var k,l,m,n,o,p,q,r,s,t,u;q=0;r=$ifaceNil;s=U(9,(k),(l),((m>>>0)),((n>>>0)),((o>>>0)),((p.$low>>>0)));t=s[0];u=s[2];q=(t);if(!((u===0))){r=GR(u);}return[q,r];};RQ.methods=[{prop:\"toWireFormat\",name:\"toWireFormat\",pkg:\"syscall\",typ:$funcType([],[PL],false)}];RR.methods=[{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"syscall\",typ:$funcType([],[$UnsafePointer,OE,$error],false)}];QL.methods=[{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"syscall\",typ:$funcType([],[$UnsafePointer,OE,$error],false)}];RS.methods=[{prop:\"Mmap\",name:\"Mmap\",pkg:\"\",typ:$funcType([$Int,$Int64,$Int,$Int,$Int],[PL,$error],false)},{prop:\"Munmap\",name:\"Munmap\",pkg:\"\",typ:$funcType([PL],[$error],false)}];GN.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)}];RW.methods=[{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"syscall\",typ:$funcType([],[$UnsafePointer,OE,$error],false)}];RX.methods=[{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"syscall\",typ:$funcType([],[$UnsafePointer,OE,$error],false)}];RY.methods=[{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"syscall\",typ:$funcType([],[$UnsafePointer,OE,$error],false)}];RZ.methods=[{prop:\"Unix\",name:\"Unix\",pkg:\"\",typ:$funcType([],[$Int64,$Int64],false)},{prop:\"Nano\",name:\"Nano\",pkg:\"\",typ:$funcType([],[$Int64],false)}];RG.methods=[{prop:\"SetLen\",name:\"SetLen\",pkg:\"\",typ:$funcType([$Int],[],false)}];SF.methods=[{prop:\"SetControllen\",name:\"SetControllen\",pkg:\"\",typ:$funcType([$Int],[],false)}];CB.init([{prop:\"Control\",name:\"Control\",pkg:\"\",typ:$funcType([RO],[$error],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([RP],[$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([RP],[$error],false)}]);CF.init(\"\",[{prop:\"Header\",name:\"Header\",embedded:false,exported:true,typ:OS,tag:\"\"},{prop:\"Data\",name:\"Data\",embedded:false,exported:true,typ:OU,tag:\"\"}]);CI.init(\"\",[{prop:\"Header\",name:\"Header\",embedded:false,exported:true,typ:OS,tag:\"\"},{prop:\"Data\",name:\"Data\",embedded:false,exported:true,typ:PL,tag:\"\"}]);CL.init(\"\",[{prop:\"Attr\",name:\"Attr\",embedded:false,exported:true,typ:OW,tag:\"\"},{prop:\"Value\",name:\"Value\",embedded:false,exported:true,typ:PL,tag:\"\"}]);EH.init(\"syscall\",[{prop:\"Protocol\",name:\"Protocol\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Ifindex\",name:\"Ifindex\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Hatype\",name:\"Hatype\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Pkttype\",name:\"Pkttype\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Halen\",name:\"Halen\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:QF,tag:\"\"},{prop:\"raw\",name:\"raw\",embedded:false,exported:false,typ:OA,tag:\"\"}]);EI.init(\"syscall\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Pad\",name:\"Pad\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Pid\",name:\"Pid\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Groups\",name:\"Groups\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"raw\",name:\"raw\",embedded:false,exported:false,typ:OB,tag:\"\"}]);GM.init(\"syscall\",[{prop:\"Mutex\",name:\"Mutex\",embedded:true,exported:true,typ:C.Mutex,tag:\"\"},{prop:\"active\",name:\"active\",embedded:false,exported:false,typ:RT,tag:\"\"},{prop:\"mmap\",name:\"mmap\",embedded:false,exported:false,typ:RU,tag:\"\"},{prop:\"munmap\",name:\"munmap\",embedded:false,exported:false,typ:RV,tag:\"\"}]);GV.init([{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"syscall\",typ:$funcType([],[$UnsafePointer,OE,$error],false)}]);GW.init(\"syscall\",[{prop:\"Port\",name:\"Port\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:RB,tag:\"\"},{prop:\"raw\",name:\"raw\",embedded:false,exported:false,typ:NX,tag:\"\"}]);GX.init(\"syscall\",[{prop:\"Port\",name:\"Port\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"ZoneId\",name:\"ZoneId\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:QH,tag:\"\"},{prop:\"raw\",name:\"raw\",embedded:false,exported:false,typ:NY,tag:\"\"}]);GY.init(\"syscall\",[{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"raw\",name:\"raw\",embedded:false,exported:false,typ:NZ,tag:\"\"}]);NJ.init(\"\",[{prop:\"Sec\",name:\"Sec\",embedded:false,exported:true,typ:$Int64,tag:\"\"},{prop:\"Nsec\",name:\"Nsec\",embedded:false,exported:true,typ:$Int64,tag:\"\"}]);NS.init(\"\",[{prop:\"Dev\",name:\"Dev\",embedded:false,exported:true,typ:$Uint64,tag:\"\"},{prop:\"Ino\",name:\"Ino\",embedded:false,exported:true,typ:$Uint64,tag:\"\"},{prop:\"Nlink\",name:\"Nlink\",embedded:false,exported:true,typ:$Uint64,tag:\"\"},{prop:\"Mode\",name:\"Mode\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Uid\",name:\"Uid\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Gid\",name:\"Gid\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"X__pad0\",name:\"X__pad0\",embedded:false,exported:true,typ:$Int32,tag:\"\"},{prop:\"Rdev\",name:\"Rdev\",embedded:false,exported:true,typ:$Uint64,tag:\"\"},{prop:\"Size\",name:\"Size\",embedded:false,exported:true,typ:$Int64,tag:\"\"},{prop:\"Blksize\",name:\"Blksize\",embedded:false,exported:true,typ:$Int64,tag:\"\"},{prop:\"Blocks\",name:\"Blocks\",embedded:false,exported:true,typ:$Int64,tag:\"\"},{prop:\"Atim\",name:\"Atim\",embedded:false,exported:true,typ:NJ,tag:\"\"},{prop:\"Mtim\",name:\"Mtim\",embedded:false,exported:true,typ:NJ,tag:\"\"},{prop:\"Ctim\",name:\"Ctim\",embedded:false,exported:true,typ:NJ,tag:\"\"},{prop:\"X__unused\",name:\"X__unused\",embedded:false,exported:true,typ:QU,tag:\"\"}]);NX.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Port\",name:\"Port\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:RB,tag:\"\"},{prop:\"Zero\",name:\"Zero\",embedded:false,exported:true,typ:QF,tag:\"\"}]);NY.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Port\",name:\"Port\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Flowinfo\",name:\"Flowinfo\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:QH,tag:\"\"},{prop:\"Scope_id\",name:\"Scope_id\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);NZ.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Path\",name:\"Path\",embedded:false,exported:true,typ:RA,tag:\"\"}]);OA.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Protocol\",name:\"Protocol\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Ifindex\",name:\"Ifindex\",embedded:false,exported:true,typ:$Int32,tag:\"\"},{prop:\"Hatype\",name:\"Hatype\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Pkttype\",name:\"Pkttype\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Halen\",name:\"Halen\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:QF,tag:\"\"}]);OB.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Pad\",name:\"Pad\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Pid\",name:\"Pid\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Groups\",name:\"Groups\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);OC.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Data\",name:\"Data\",embedded:false,exported:true,typ:RC,tag:\"\"}]);OD.init(\"\",[{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:OC,tag:\"\"},{prop:\"Pad\",name:\"Pad\",embedded:false,exported:true,typ:RD,tag:\"\"}]);OF.init(\"\",[{prop:\"Onoff\",name:\"Onoff\",embedded:false,exported:true,typ:$Int32,tag:\"\"},{prop:\"Linger\",name:\"Linger\",embedded:false,exported:true,typ:$Int32,tag:\"\"}]);OG.init(\"\",[{prop:\"Base\",name:\"Base\",embedded:false,exported:true,typ:PV,tag:\"\"},{prop:\"Len\",name:\"Len\",embedded:false,exported:true,typ:$Uint64,tag:\"\"}]);OH.init(\"\",[{prop:\"Multiaddr\",name:\"Multiaddr\",embedded:false,exported:true,typ:RB,tag:\"\"},{prop:\"Interface\",name:\"Interface\",embedded:false,exported:true,typ:RB,tag:\"\"}]);OI.init(\"\",[{prop:\"Multiaddr\",name:\"Multiaddr\",embedded:false,exported:true,typ:RB,tag:\"\"},{prop:\"Address\",name:\"Address\",embedded:false,exported:true,typ:RB,tag:\"\"},{prop:\"Ifindex\",name:\"Ifindex\",embedded:false,exported:true,typ:$Int32,tag:\"\"}]);OJ.init(\"\",[{prop:\"Multiaddr\",name:\"Multiaddr\",embedded:false,exported:true,typ:QH,tag:\"\"},{prop:\"Interface\",name:\"Interface\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);OK.init(\"\",[{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:PV,tag:\"\"},{prop:\"Namelen\",name:\"Namelen\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Pad_cgo_0\",name:\"Pad_cgo_0\",embedded:false,exported:true,typ:RB,tag:\"\"},{prop:\"Iov\",name:\"Iov\",embedded:false,exported:true,typ:RG,tag:\"\"},{prop:\"Iovlen\",name:\"Iovlen\",embedded:false,exported:true,typ:$Uint64,tag:\"\"},{prop:\"Control\",name:\"Control\",embedded:false,exported:true,typ:PV,tag:\"\"},{prop:\"Controllen\",name:\"Controllen\",embedded:false,exported:true,typ:$Uint64,tag:\"\"},{prop:\"Flags\",name:\"Flags\",embedded:false,exported:true,typ:$Int32,tag:\"\"},{prop:\"Pad_cgo_1\",name:\"Pad_cgo_1\",embedded:false,exported:true,typ:RB,tag:\"\"}]);OS.init(\"\",[{prop:\"Len\",name:\"Len\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Flags\",name:\"Flags\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Seq\",name:\"Seq\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Pid\",name:\"Pid\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);OU.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint8,tag:\"\"}]);OW.init(\"\",[{prop:\"Len\",name:\"Len\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:$Uint16,tag:\"\"}]);OX.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"X__ifi_pad\",name:\"X__ifi_pad\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:$Uint16,tag:\"\"},{prop:\"Index\",name:\"Index\",embedded:false,exported:true,typ:$Int32,tag:\"\"},{prop:\"Flags\",name:\"Flags\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Change\",name:\"Change\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);OY.init(\"\",[{prop:\"Family\",name:\"Family\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Prefixlen\",name:\"Prefixlen\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Flags\",name:\"Flags\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Scope\",name:\"Scope\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Index\",name:\"Index\",embedded:false,exported:true,typ:$Uint32,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}F=PL.nil;P=null;$pkg.ForkLock=new C.RWMutex.ptr(new C.Mutex.ptr(0,0),0,0,0,0);$pkg.SocketDisableIPv6=false;HR=new $Int64(0,0);E=false;Q=false;R=-1;AG=M();$pkg.Stdin=0;$pkg.Stdout=1;$pkg.Stderr=2;GO=new GN(11);GP=new GN(22);GQ=new GN(2);HW=$toNativeArray($kindString,[\"\",\"operation not permitted\",\"no such file or directory\",\"no such process\",\"interrupted system call\",\"input/output error\",\"no such device or address\",\"argument list too long\",\"exec format error\",\"bad file descriptor\",\"no child processes\",\"resource temporarily unavailable\",\"cannot allocate memory\",\"permission denied\",\"bad address\",\"block device required\",\"device or resource busy\",\"file exists\",\"invalid cross-device link\",\"no such device\",\"not a directory\",\"is a directory\",\"invalid argument\",\"too many open files in system\",\"too many open files\",\"inappropriate ioctl for device\",\"text file busy\",\"file too large\",\"no space left on device\",\"illegal seek\",\"read-only file system\",\"too many links\",\"broken pipe\",\"numerical argument out of domain\",\"numerical result out of range\",\"resource deadlock avoided\",\"file name too long\",\"no locks available\",\"function not implemented\",\"directory not empty\",\"too many levels of symbolic links\",\"\",\"no message of desired type\",\"identifier removed\",\"channel number out of range\",\"level 2 not synchronized\",\"level 3 halted\",\"level 3 reset\",\"link number out of range\",\"protocol driver not attached\",\"no CSI structure available\",\"level 2 halted\",\"invalid exchange\",\"invalid request descriptor\",\"exchange full\",\"no anode\",\"invalid request code\",\"invalid slot\",\"\",\"bad font file format\",\"device not a stream\",\"no data available\",\"timer expired\",\"out of streams resources\",\"machine is not on the network\",\"package not installed\",\"object is remote\",\"link has been severed\",\"advertise error\",\"srmount error\",\"communication error on send\",\"protocol error\",\"multihop attempted\",\"RFS specific error\",\"bad message\",\"value too large for defined data type\",\"name not unique on network\",\"file descriptor in bad state\",\"remote address changed\",\"can not access a needed shared library\",\"accessing a corrupted shared library\",\".lib section in a.out corrupted\",\"attempting to link in too many shared libraries\",\"cannot exec a shared library directly\",\"invalid or incomplete multibyte or wide character\",\"interrupted system call should be restarted\",\"streams pipe error\",\"too many users\",\"socket operation on non-socket\",\"destination address required\",\"message too long\",\"protocol wrong type for socket\",\"protocol not available\",\"protocol not supported\",\"socket type not supported\",\"operation not supported\",\"protocol family not supported\",\"address family not supported by protocol\",\"address already in use\",\"cannot assign requested address\",\"network is down\",\"network is unreachable\",\"network dropped connection on reset\",\"software caused connection abort\",\"connection reset by peer\",\"no buffer space available\",\"transport endpoint is already connected\",\"transport endpoint is not connected\",\"cannot send after transport endpoint shutdown\",\"too many references: cannot splice\",\"connection timed out\",\"connection refused\",\"host is down\",\"no route to host\",\"operation already in progress\",\"operation now in progress\",\"stale NFS file handle\",\"structure needs cleaning\",\"not a XENIX named type file\",\"no XENIX semaphores available\",\"is a named type file\",\"remote I/O error\",\"disk quota exceeded\",\"no medium found\",\"wrong medium type\",\"operation canceled\",\"required key not available\",\"key has expired\",\"key has been revoked\",\"key was rejected by service\",\"owner died\",\"state not recoverable\",\"operation not possible due to RF-kill\"]);FX=new GM.ptr(new C.Mutex.ptr(0,0),{},NB,KY);G();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/gopherjs/gopherjs/nosync\"]=(function(){var $pkg={},$init,B,E,F,J,M,N,O,P,Q;B=$pkg.Mutex=$newType(0,$kindStruct,\"nosync.Mutex\",true,\"github.com/gopherjs/gopherjs/nosync\",true,function(locked_){this.$val=this;if(arguments.length===0){this.locked=false;return;}this.locked=locked_;});E=$pkg.Once=$newType(0,$kindStruct,\"nosync.Once\",true,\"github.com/gopherjs/gopherjs/nosync\",true,function(doing_,done_){this.$val=this;if(arguments.length===0){this.doing=false;this.done=false;return;}this.doing=doing_;this.done=done_;});F=$pkg.Pool=$newType(0,$kindStruct,\"nosync.Pool\",true,\"github.com/gopherjs/gopherjs/nosync\",true,function(store_,New_){this.$val=this;if(arguments.length===0){this.store=O.nil;this.New=$throwNilPointerError;return;}this.store=store_;this.New=New_;});J=$ptrType(B);M=$funcType([],[],false);N=$ptrType(E);O=$sliceType($emptyInterface);P=$ptrType(F);Q=$funcType([],[$emptyInterface],false);B.ptr.prototype.Lock=function(){var a;a=this;if(a.locked){$panic(new $String(\"nosync: mutex is already locked\"));}a.locked=true;};B.prototype.Lock=function(){return this.$val.Lock();};B.ptr.prototype.Unlock=function(){var a;a=this;if(!a.locked){$panic(new $String(\"nosync: unlock of unlocked mutex\"));}a.locked=false;};B.prototype.Unlock=function(){return this.$val.Unlock();};E.ptr.prototype.Do=function(a){var a,b,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=[b];b[0]=this;if(b[0].done){$s=-1;return;}if(b[0].doing){$panic(new $String(\"nosync: Do called within f\"));}b[0].doing=true;$deferred.push([(function(b){return function(){b[0].doing=false;b[0].done=true;};})(b),[]]);$r=a();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:E.ptr.prototype.Do};}$f.a=a;$f.b=b;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};E.prototype.Do=function(a){return this.$val.Do(a);};F.ptr.prototype.Get=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;if(a.store.$length===0){$s=1;continue;}$s=2;continue;case 1:if(!(a.New===$throwNilPointerError)){$s=3;continue;}$s=4;continue;case 3:b=a.New();$s=5;case 5:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return b;case 4:$s=-1;return $ifaceNil;case 2:e=(c=a.store,d=a.store.$length-1>>0,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]));a.store=$subslice(a.store,0,(a.store.$length-1>>0));$s=-1;return e;}return;}if($f===undefined){$f={$blk:F.ptr.prototype.Get};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};F.prototype.Get=function(){return this.$val.Get();};F.ptr.prototype.Put=function(a){var a,b;b=this;if($interfaceIsEqual(a,$ifaceNil)){return;}b.store=$append(b.store,a);};F.prototype.Put=function(a){return this.$val.Put(a);};J.methods=[{prop:\"Lock\",name:\"Lock\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"Unlock\",name:\"Unlock\",pkg:\"\",typ:$funcType([],[],false)}];N.methods=[{prop:\"Do\",name:\"Do\",pkg:\"\",typ:$funcType([M],[],false)}];P.methods=[{prop:\"Get\",name:\"Get\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)},{prop:\"Put\",name:\"Put\",pkg:\"\",typ:$funcType([$emptyInterface],[],false)}];B.init(\"github.com/gopherjs/gopherjs/nosync\",[{prop:\"locked\",name:\"locked\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);E.init(\"github.com/gopherjs/gopherjs/nosync\",[{prop:\"doing\",name:\"doing\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"done\",name:\"done\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);F.init(\"github.com/gopherjs/gopherjs/nosync\",[{prop:\"store\",name:\"store\",embedded:false,exported:false,typ:O,tag:\"\"},{prop:\"New\",name:\"New\",embedded:false,exported:true,typ:Q,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"time\"]=(function(){var $pkg={},$init,C,B,E,A,D,G,AE,AX,BI,BL,BM,BO,BS,CJ,CK,CL,DK,DL,DM,DO,DQ,DR,DS,DT,DU,DV,DX,EA,EB,EC,ED,EE,EF,EG,O,Q,T,U,V,W,AA,AD,AR,BN,BP,BZ,CB,CM,DI,CN,DJ,CO,CQ,CY,h,F,H,I,J,L,M,P,R,S,X,Y,Z,AB,AC,AF,AG,AH,AI,AJ,AK,AM,AN,AO,AP,AQ,AS,AW,AY,AZ,BJ,BQ,BR,BT,BU,BV,BX,BY,CA,CC,CD,CE,CF,CG,CH,CI,CP;C=$packages[\"errors\"];B=$packages[\"github.com/gopherjs/gopherjs/js\"];E=$packages[\"github.com/gopherjs/gopherjs/nosync\"];A=$packages[\"runtime\"];D=$packages[\"syscall\"];G=$pkg.runtimeTimer=$newType(0,$kindStruct,\"time.runtimeTimer\",true,\"time\",false,function(i_,when_,period_,f_,arg_,timeout_,active_){this.$val=this;if(arguments.length===0){this.i=0;this.when=new $Int64(0,0);this.period=new $Int64(0,0);this.f=$throwNilPointerError;this.arg=$ifaceNil;this.timeout=null;this.active=false;return;}this.i=i_;this.when=when_;this.period=period_;this.f=f_;this.arg=arg_;this.timeout=timeout_;this.active=active_;});AE=$pkg.ParseError=$newType(0,$kindStruct,\"time.ParseError\",true,\"time\",true,function(Layout_,Value_,LayoutElem_,ValueElem_,Message_){this.$val=this;if(arguments.length===0){this.Layout=\"\";this.Value=\"\";this.LayoutElem=\"\";this.ValueElem=\"\";this.Message=\"\";return;}this.Layout=Layout_;this.Value=Value_;this.LayoutElem=LayoutElem_;this.ValueElem=ValueElem_;this.Message=Message_;});AX=$pkg.Timer=$newType(0,$kindStruct,\"time.Timer\",true,\"time\",true,function(C_,r_){this.$val=this;if(arguments.length===0){this.C=$chanNil;this.r=new G.ptr(0,new $Int64(0,0),new $Int64(0,0),$throwNilPointerError,$ifaceNil,null,false);return;}this.C=C_;this.r=r_;});BI=$pkg.Ticker=$newType(0,$kindStruct,\"time.Ticker\",true,\"time\",true,function(C_,r_){this.$val=this;if(arguments.length===0){this.C=$chanNil;this.r=new G.ptr(0,new $Int64(0,0),new $Int64(0,0),$throwNilPointerError,$ifaceNil,null,false);return;}this.C=C_;this.r=r_;});BL=$pkg.Time=$newType(0,$kindStruct,\"time.Time\",true,\"time\",true,function(wall_,ext_,loc_){this.$val=this;if(arguments.length===0){this.wall=new $Uint64(0,0);this.ext=new $Int64(0,0);this.loc=DU.nil;return;}this.wall=wall_;this.ext=ext_;this.loc=loc_;});BM=$pkg.Month=$newType(4,$kindInt,\"time.Month\",true,\"time\",true,null);BO=$pkg.Weekday=$newType(4,$kindInt,\"time.Weekday\",true,\"time\",true,null);BS=$pkg.Duration=$newType(8,$kindInt64,\"time.Duration\",true,\"time\",true,null);CJ=$pkg.Location=$newType(0,$kindStruct,\"time.Location\",true,\"time\",true,function(name_,zone_,tx_,cacheStart_,cacheEnd_,cacheZone_){this.$val=this;if(arguments.length===0){this.name=\"\";this.zone=DK.nil;this.tx=DL.nil;this.cacheStart=new $Int64(0,0);this.cacheEnd=new $Int64(0,0);this.cacheZone=DM.nil;return;}this.name=name_;this.zone=zone_;this.tx=tx_;this.cacheStart=cacheStart_;this.cacheEnd=cacheEnd_;this.cacheZone=cacheZone_;});CK=$pkg.zone=$newType(0,$kindStruct,\"time.zone\",true,\"time\",false,function(name_,offset_,isDST_){this.$val=this;if(arguments.length===0){this.name=\"\";this.offset=0;this.isDST=false;return;}this.name=name_;this.offset=offset_;this.isDST=isDST_;});CL=$pkg.zoneTrans=$newType(0,$kindStruct,\"time.zoneTrans\",true,\"time\",false,function(when_,index_,isstd_,isutc_){this.$val=this;if(arguments.length===0){this.when=new $Int64(0,0);this.index=0;this.isstd=false;this.isutc=false;return;}this.when=when_;this.index=index_;this.isstd=isstd_;this.isutc=isutc_;});DK=$sliceType(CK);DL=$sliceType(CL);DM=$ptrType(CK);DO=$sliceType($String);DQ=$arrayType($Uint8,20);DR=$sliceType($Uint8);DS=$arrayType($Uint8,9);DT=$arrayType($Uint8,64);DU=$ptrType(CJ);DV=$chanType(BL,false,false);DX=$arrayType($Uint8,32);EA=$funcType([$emptyInterface,$Uintptr],[],false);EB=$ptrType(B.Object);EC=$ptrType(AE);ED=$ptrType(AX);EE=$chanType(BL,false,true);EF=$ptrType(BI);EG=$ptrType(BL);F=function(){$unused(CE(new $Int64(0,0),new $Int64(0,0)));};H=function(){var i,j,k,l;i=new($global.Date)();j=$internalize(i,$String);k=P(j,40);l=P(j,41);if((k===-1)||(l===-1)){CN.name=\"UTC\";return;}CN.name=$substring(j,(k+1>>0),l);CN.zone=new DK([new CK.ptr(CN.name,$imul(($parseInt(i.getTimezoneOffset())>>0),-60),false)]);};I=function(){return $mul64($internalize(new($global.Date)().getTime(),$Int64),new $Int64(0,1000000));};J=function(){var i,j,k,l,m,n,o,p;i=new $Int64(0,0);j=0;k=new $Int64(0,0);l=I();m=$div64(l,new $Int64(0,1000000000),false);n=(((o=$div64(l,new $Int64(0,1000000000),true),o.$low+((o.$high>>31)*4294967296))>>0));p=l;i=m;j=n;k=p;return[i,j,k];};L=function(i){var i,j,k,l;i.active=true;l=$div64(((j=i.when,k=I(),new $Int64(j.$high-k.$high,j.$low-k.$low))),new $Int64(0,1000000),false);if((l.$high>0||(l.$high===0&&l.$low>2147483647))){return;}if((l.$high<0||(l.$high===0&&l.$low<0))){l=new $Int64(0,0);}i.timeout=$setTimeout((function(){var m,n,o;i.active=false;if(!((m=i.period,(m.$high===0&&m.$low===0)))){i.when=(n=i.when,o=i.period,new $Int64(n.$high+o.$high,n.$low+o.$low));L(i);}$go(i.f,[i.arg,0]);}),$externalize(new $Int64(l.$high+0,l.$low+1),$Int64));};M=function(i){var i,j;$global.clearTimeout(i.timeout);j=i.active;i.active=false;return j;};P=function(i,j){var i,j;return $parseInt(i.indexOf($global.String.fromCharCode(j)))>>0;};R=function(i){var i,j;if(i.length===0){return false;}j=i.charCodeAt(0);return 97<=j&&j<=122;};S=function(i){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,da,db,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;j=\"\";k=0;l=\"\";m=0;while(true){if(!(m<i.length)){break;}n=((i.charCodeAt(m)>>0));o=n;if(o===(74)){if(i.length>=(m+3>>0)&&$substring(i,m,(m+3>>0))===\"Jan\"){if(i.length>=(m+7>>0)&&$substring(i,m,(m+7>>0))===\"January\"){p=$substring(i,0,m);q=257;r=$substring(i,(m+7>>0));j=p;k=q;l=r;return[j,k,l];}if(!R($substring(i,(m+3>>0)))){s=$substring(i,0,m);t=258;u=$substring(i,(m+3>>0));j=s;k=t;l=u;return[j,k,l];}}}else if(o===(77)){if(i.length>=(m+3>>0)){if($substring(i,m,(m+3>>0))===\"Mon\"){if(i.length>=(m+6>>0)&&$substring(i,m,(m+6>>0))===\"Monday\"){v=$substring(i,0,m);w=261;x=$substring(i,(m+6>>0));j=v;k=w;l=x;return[j,k,l];}if(!R($substring(i,(m+3>>0)))){y=$substring(i,0,m);z=262;aa=$substring(i,(m+3>>0));j=y;k=z;l=aa;return[j,k,l];}}if($substring(i,m,(m+3>>0))===\"MST\"){ab=$substring(i,0,m);ac=21;ad=$substring(i,(m+3>>0));j=ab;k=ac;l=ad;return[j,k,l];}}}else if(o===(48)){if(i.length>=(m+2>>0)&&49<=i.charCodeAt((m+1>>0))&&i.charCodeAt((m+1>>0))<=54){ae=$substring(i,0,m);af=(ag=i.charCodeAt((m+1>>0))-49<<24>>>24,((ag<0||ag>=Q.length)?($throwRuntimeError(\"index out of range\"),undefined):Q[ag]));ah=$substring(i,(m+2>>0));j=ae;k=af;l=ah;return[j,k,l];}}else if(o===(49)){if(i.length>=(m+2>>0)&&(i.charCodeAt((m+1>>0))===53)){ai=$substring(i,0,m);aj=522;ak=$substring(i,(m+2>>0));j=ai;k=aj;l=ak;return[j,k,l];}al=$substring(i,0,m);am=259;an=$substring(i,(m+1>>0));j=al;k=am;l=an;return[j,k,l];}else if(o===(50)){if(i.length>=(m+4>>0)&&$substring(i,m,(m+4>>0))===\"2006\"){ao=$substring(i,0,m);ap=273;aq=$substring(i,(m+4>>0));j=ao;k=ap;l=aq;return[j,k,l];}ar=$substring(i,0,m);as=263;at=$substring(i,(m+1>>0));j=ar;k=as;l=at;return[j,k,l];}else if(o===(95)){if(i.length>=(m+2>>0)&&(i.charCodeAt((m+1>>0))===50)){if(i.length>=(m+5>>0)&&$substring(i,(m+1>>0),(m+5>>0))===\"2006\"){au=$substring(i,0,(m+1>>0));av=273;aw=$substring(i,(m+5>>0));j=au;k=av;l=aw;return[j,k,l];}ax=$substring(i,0,m);ay=264;az=$substring(i,(m+2>>0));j=ax;k=ay;l=az;return[j,k,l];}}else if(o===(51)){ba=$substring(i,0,m);bb=523;bc=$substring(i,(m+1>>0));j=ba;k=bb;l=bc;return[j,k,l];}else if(o===(52)){bd=$substring(i,0,m);be=525;bf=$substring(i,(m+1>>0));j=bd;k=be;l=bf;return[j,k,l];}else if(o===(53)){bg=$substring(i,0,m);bh=527;bi=$substring(i,(m+1>>0));j=bg;k=bh;l=bi;return[j,k,l];}else if(o===(80)){if(i.length>=(m+2>>0)&&(i.charCodeAt((m+1>>0))===77)){bj=$substring(i,0,m);bk=531;bl=$substring(i,(m+2>>0));j=bj;k=bk;l=bl;return[j,k,l];}}else if(o===(112)){if(i.length>=(m+2>>0)&&(i.charCodeAt((m+1>>0))===109)){bm=$substring(i,0,m);bn=532;bo=$substring(i,(m+2>>0));j=bm;k=bn;l=bo;return[j,k,l];}}else if(o===(45)){if(i.length>=(m+7>>0)&&$substring(i,m,(m+7>>0))===\"-070000\"){bp=$substring(i,0,m);bq=28;br=$substring(i,(m+7>>0));j=bp;k=bq;l=br;return[j,k,l];}if(i.length>=(m+9>>0)&&$substring(i,m,(m+9>>0))===\"-07:00:00\"){bs=$substring(i,0,m);bt=31;bu=$substring(i,(m+9>>0));j=bs;k=bt;l=bu;return[j,k,l];}if(i.length>=(m+5>>0)&&$substring(i,m,(m+5>>0))===\"-0700\"){bv=$substring(i,0,m);bw=27;bx=$substring(i,(m+5>>0));j=bv;k=bw;l=bx;return[j,k,l];}if(i.length>=(m+6>>0)&&$substring(i,m,(m+6>>0))===\"-07:00\"){by=$substring(i,0,m);bz=30;ca=$substring(i,(m+6>>0));j=by;k=bz;l=ca;return[j,k,l];}if(i.length>=(m+3>>0)&&$substring(i,m,(m+3>>0))===\"-07\"){cb=$substring(i,0,m);cc=29;cd=$substring(i,(m+3>>0));j=cb;k=cc;l=cd;return[j,k,l];}}else if(o===(90)){if(i.length>=(m+7>>0)&&$substring(i,m,(m+7>>0))===\"Z070000\"){ce=$substring(i,0,m);cf=23;cg=$substring(i,(m+7>>0));j=ce;k=cf;l=cg;return[j,k,l];}if(i.length>=(m+9>>0)&&$substring(i,m,(m+9>>0))===\"Z07:00:00\"){ch=$substring(i,0,m);ci=26;cj=$substring(i,(m+9>>0));j=ch;k=ci;l=cj;return[j,k,l];}if(i.length>=(m+5>>0)&&$substring(i,m,(m+5>>0))===\"Z0700\"){ck=$substring(i,0,m);cl=22;cm=$substring(i,(m+5>>0));j=ck;k=cl;l=cm;return[j,k,l];}if(i.length>=(m+6>>0)&&$substring(i,m,(m+6>>0))===\"Z07:00\"){cn=$substring(i,0,m);co=25;cp=$substring(i,(m+6>>0));j=cn;k=co;l=cp;return[j,k,l];}if(i.length>=(m+3>>0)&&$substring(i,m,(m+3>>0))===\"Z07\"){cq=$substring(i,0,m);cr=24;cs=$substring(i,(m+3>>0));j=cq;k=cr;l=cs;return[j,k,l];}}else if(o===(46)){if((m+1>>0)<i.length&&((i.charCodeAt((m+1>>0))===48)||(i.charCodeAt((m+1>>0))===57))){ct=i.charCodeAt((m+1>>0));cu=m+1>>0;while(true){if(!(cu<i.length&&(i.charCodeAt(cu)===ct))){break;}cu=cu+(1)>>0;}if(!AG(i,cu)){cv=32;if(i.charCodeAt((m+1>>0))===57){cv=33;}cv=cv|((((cu-((m+1>>0))>>0))<<16>>0));cw=$substring(i,0,m);cx=cv;cy=$substring(i,cu);j=cw;k=cx;l=cy;return[j,k,l];}}}m=m+(1)>>0;}cz=i;da=0;db=\"\";j=cz;k=da;l=db;return[j,k,l];};X=function(i,j){var i,j,k,l,m;k=0;while(true){if(!(k<i.length)){break;}l=i.charCodeAt(k);m=j.charCodeAt(k);if(!((l===m))){l=(l|(32))>>>0;m=(m|(32))>>>0;if(!((l===m))||l<97||l>122){return false;}}k=k+(1)>>0;}return true;};Y=function(i,j){var i,j,k,l,m,n;k=i;l=0;while(true){if(!(l<k.$length)){break;}m=l;n=((l<0||l>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+l]);if(j.length>=n.length&&X($substring(j,0,n.length),n)){return[m,$substring(j,n.length),$ifaceNil];}l++;}return[-1,j,AD];};Z=function(i,j,k){var i,j,k,l,m,n,o,p,q;l=((j>>>0));if(j<0){i=$append(i,45);l=((-j>>>0));}m=DQ.zero();n=20;while(true){if(!(l>=10)){break;}n=n-(1)>>0;p=(o=l/10,(o===o&&o!==1/0&&o!==-1/0)?o>>>0:$throwRuntimeError(\"integer divide by zero\"));((n<0||n>=m.length)?($throwRuntimeError(\"index out of range\"),undefined):m[n]=((((48+l>>>0)-(p*10>>>0)>>>0)<<24>>>24)));l=p;}n=n-(1)>>0;((n<0||n>=m.length)?($throwRuntimeError(\"index out of range\"),undefined):m[n]=(((48+l>>>0)<<24>>>24)));q=20-n>>0;while(true){if(!(q<k)){break;}i=$append(i,48);q=q+(1)>>0;}return $appendSlice(i,$subslice(new DR(m),n));};AB=function(i){var i,j,k,l,m,n,o,p,q,r,s;j=0;k=$ifaceNil;l=false;if(!(i===\"\")&&((i.charCodeAt(0)===45)||(i.charCodeAt(0)===43))){l=i.charCodeAt(0)===45;i=$substring(i,1);}m=AS(i);n=m[0];o=m[1];k=m[2];j=(((n.$low+((n.$high>>31)*4294967296))>>0));if(!($interfaceIsEqual(k,$ifaceNil))||!(o===\"\")){p=0;q=AA;j=p;k=q;return[j,k];}if(l){j=-j;}r=j;s=$ifaceNil;j=r;k=s;return[j,k];};AC=function(i,j,k,l){var i,j,k,l,m,n,o,p,q,r;m=j;n=DS.zero();o=9;while(true){if(!(o>0)){break;}o=o-(1)>>0;((o<0||o>=n.length)?($throwRuntimeError(\"index out of range\"),undefined):n[o]=((((p=m%10,p===p?p:$throwRuntimeError(\"integer divide by zero\"))+48>>>0)<<24>>>24)));m=(q=m/(10),(q===q&&q!==1/0&&q!==-1/0)?q>>>0:$throwRuntimeError(\"integer divide by zero\"));}if(k>9){k=9;}if(l){while(true){if(!(k>0&&((r=k-1>>0,((r<0||r>=n.length)?($throwRuntimeError(\"index out of range\"),undefined):n[r]))===48))){break;}k=k-(1)>>0;}if(k===0){return i;}}i=$append(i,46);return $appendSlice(i,$subslice(new DR(n),0,k));};BL.ptr.prototype.String=function(){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=$clone(i,BL).Format(\"2006-01-02 15:04:05.999999999 -0700 MST\");$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;if(!((l=(m=i.wall,new $Uint64(m.$high&2147483648,(m.$low&0)>>>0)),(l.$high===0&&l.$low===0)))){o=((n=i.ext,new $Uint64(n.$high,n.$low)));p=43;if((q=i.ext,(q.$high<0||(q.$high===0&&q.$low<0)))){p=45;o=new $Uint64(-o.$high,-o.$low);}r=$div64(o,new $Uint64(0,1000000000),false);s=$div64(o,new $Uint64(0,1000000000),true);t=r;o=s;u=$div64(t,new $Uint64(0,1000000000),false);v=$div64(t,new $Uint64(0,1000000000),true);w=u;t=v;x=DR.nil;x=$appendSlice(x,\" m=\");x=$append(x,p);y=0;if(!((w.$high===0&&w.$low===0))){x=Z(x,((w.$low>>0)),0);y=9;}x=Z(x,((t.$low>>0)),y);x=$append(x,46);x=Z(x,((o.$low>>0)),9);k=k+(($bytesToString(x)));}$s=-1;return k;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.String};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.String=function(){return this.$val.String();};BL.ptr.prototype.Format=function(i){var i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=this;k=DR.nil;l=i.length+10>>0;if(l<64){m=DT.zero();k=$subslice(new DR(m),0,0);}else{k=$makeSlice(DR,0,l);}n=$clone(j,BL).AppendFormat(k,i);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}k=n;$s=-1;return($bytesToString(k));}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Format};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Format=function(i){return this.$val.Format(i);};BL.ptr.prototype.AppendFormat=function(i,j){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:k=this;m=$clone(k,BL).locabs();$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;n=l[0];o=l[1];p=l[2];q=-1;r=0;s=0;t=-1;u=0;v=0;while(true){if(!(!(j===\"\"))){break;}w=S(j);x=w[0];y=w[1];z=w[2];if(!(x===\"\")){i=$appendSlice(i,x);}if(y===0){break;}j=z;if(q<0&&!(((y&256)===0))){aa=BY(p,true);q=aa[0];r=aa[1];s=aa[2];}if(t<0&&!(((y&512)===0))){ab=BR(p);t=ab[0];u=ab[1];v=ab[2];}switch(0){default:ac=y&65535;if(ac===(274)){ad=q;if(ad<0){ad=-ad;}i=Z(i,(ae=ad%100,ae===ae?ae:$throwRuntimeError(\"integer divide by zero\")),2);}else if(ac===(273)){i=Z(i,q,4);}else if(ac===(258)){i=$appendSlice(i,$substring(new BM(r).String(),0,3));}else if(ac===(257)){af=new BM(r).String();i=$appendSlice(i,af);}else if(ac===(259)){i=Z(i,((r>>0)),0);}else if(ac===(260)){i=Z(i,((r>>0)),2);}else if(ac===(262)){i=$appendSlice(i,$substring(new BO(BQ(p)).String(),0,3));}else if(ac===(261)){ag=new BO(BQ(p)).String();i=$appendSlice(i,ag);}else if(ac===(263)){i=Z(i,s,0);}else if(ac===(264)){if(s<10){i=$append(i,32);}i=Z(i,s,0);}else if(ac===(265)){i=Z(i,s,2);}else if(ac===(522)){i=Z(i,t,2);}else if(ac===(523)){ai=(ah=t%12,ah===ah?ah:$throwRuntimeError(\"integer divide by zero\"));if(ai===0){ai=12;}i=Z(i,ai,0);}else if(ac===(524)){ak=(aj=t%12,aj===aj?aj:$throwRuntimeError(\"integer divide by zero\"));if(ak===0){ak=12;}i=Z(i,ak,2);}else if(ac===(525)){i=Z(i,u,0);}else if(ac===(526)){i=Z(i,u,2);}else if(ac===(527)){i=Z(i,v,0);}else if(ac===(528)){i=Z(i,v,2);}else if(ac===(531)){if(t>=12){i=$appendSlice(i,\"PM\");}else{i=$appendSlice(i,\"AM\");}}else if(ac===(532)){if(t>=12){i=$appendSlice(i,\"pm\");}else{i=$appendSlice(i,\"am\");}}else if((ac===(22))||(ac===(25))||(ac===(23))||(ac===(24))||(ac===(26))||(ac===(27))||(ac===(30))||(ac===(28))||(ac===(29))||(ac===(31))){if((o===0)&&((y===22)||(y===25)||(y===23)||(y===24)||(y===26))){i=$append(i,90);break;}am=(al=o/60,(al===al&&al!==1/0&&al!==-1/0)?al>>0:$throwRuntimeError(\"integer divide by zero\"));an=o;if(am<0){i=$append(i,45);am=-am;an=-an;}else{i=$append(i,43);}i=Z(i,(ao=am/60,(ao===ao&&ao!==1/0&&ao!==-1/0)?ao>>0:$throwRuntimeError(\"integer divide by zero\")),2);if((y===25)||(y===30)||(y===26)||(y===31)){i=$append(i,58);}if(!((y===29))&&!((y===24))){i=Z(i,(ap=am%60,ap===ap?ap:$throwRuntimeError(\"integer divide by zero\")),2);}if((y===23)||(y===28)||(y===31)||(y===26)){if((y===31)||(y===26)){i=$append(i,58);}i=Z(i,(aq=an%60,aq===aq?aq:$throwRuntimeError(\"integer divide by zero\")),2);}}else if(ac===(21)){if(!(n===\"\")){i=$appendSlice(i,n);break;}as=(ar=o/60,(ar===ar&&ar!==1/0&&ar!==-1/0)?ar>>0:$throwRuntimeError(\"integer divide by zero\"));if(as<0){i=$append(i,45);as=-as;}else{i=$append(i,43);}i=Z(i,(at=as/60,(at===at&&at!==1/0&&at!==-1/0)?at>>0:$throwRuntimeError(\"integer divide by zero\")),2);i=Z(i,(au=as%60,au===au?au:$throwRuntimeError(\"integer divide by zero\")),2);}else if((ac===(32))||(ac===(33))){i=AC(i,(($clone(k,BL).Nanosecond()>>>0)),y>>16>>0,(y&65535)===33);}}}$s=-1;return i;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.AppendFormat};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.AppendFormat=function(i,j){return this.$val.AppendFormat(i,j);};AF=function(i){var i;return\"\\\"\"+i+\"\\\"\";};AE.ptr.prototype.Error=function(){var i;i=this;if(i.Message===\"\"){return\"parsing time \"+AF(i.Value)+\" as \"+AF(i.Layout)+\": cannot parse \"+AF(i.ValueElem)+\" as \"+AF(i.LayoutElem);}return\"parsing time \"+AF(i.Value)+i.Message;};AE.prototype.Error=function(){return this.$val.Error();};AG=function(i,j){var i,j,k;if(i.length<=j){return false;}k=i.charCodeAt(j);return 48<=k&&k<=57;};AH=function(i,j){var i,j;if(!AG(i,0)){return[0,i,AD];}if(!AG(i,1)){if(j){return[0,i,AD];}return[(((i.charCodeAt(0)-48<<24>>>24)>>0)),$substring(i,1),$ifaceNil];}return[($imul((((i.charCodeAt(0)-48<<24>>>24)>>0)),10))+(((i.charCodeAt(1)-48<<24>>>24)>>0))>>0,$substring(i,2),$ifaceNil];};AI=function(i){var i;while(true){if(!(i.length>0&&(i.charCodeAt(0)===32))){break;}i=$substring(i,1);}return i;};AJ=function(i,j){var i,j;while(true){if(!(j.length>0)){break;}if(j.charCodeAt(0)===32){if(i.length>0&&!((i.charCodeAt(0)===32))){return[i,AD];}j=AI(j);i=AI(i);continue;}if((i.length===0)||!((i.charCodeAt(0)===j.charCodeAt(0)))){return[i,AD];}j=$substring(j,1);i=$substring(i,1);}return[i,$ifaceNil];};AK=function(i,j){var i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:k=AM(i,j,$pkg.UTC,$pkg.Local);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$s=-1;return k;}return;}if($f===undefined){$f={$blk:AK};}$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Parse=AK;AM=function(i,j,k,l){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz,da,db,dc,dd,de,df,dg,dh,di,dj,dk,dl,dm,dn,dp,dq,dr,ds,dt,du,dv,dw,dx,dy,dz,ea,eb,ec,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;bu=$f.bu;bv=$f.bv;bw=$f.bw;bx=$f.bx;by=$f.by;bz=$f.bz;ca=$f.ca;cb=$f.cb;cc=$f.cc;cd=$f.cd;ce=$f.ce;cf=$f.cf;cg=$f.cg;ch=$f.ch;ci=$f.ci;cj=$f.cj;ck=$f.ck;cl=$f.cl;cm=$f.cm;cn=$f.cn;co=$f.co;cp=$f.cp;cq=$f.cq;cr=$f.cr;cs=$f.cs;ct=$f.ct;cu=$f.cu;cv=$f.cv;cw=$f.cw;cx=$f.cx;cy=$f.cy;cz=$f.cz;da=$f.da;db=$f.db;dc=$f.dc;dd=$f.dd;de=$f.de;df=$f.df;dg=$f.dg;dh=$f.dh;di=$f.di;dj=$f.dj;dk=$f.dk;dl=$f.dl;dm=$f.dm;dn=$f.dn;dp=$f.dp;dq=$f.dq;dr=$f.dr;ds=$f.ds;dt=$f.dt;du=$f.du;dv=$f.dv;dw=$f.dw;dx=$f.dx;dy=$f.dy;dz=$f.dz;ea=$f.ea;eb=$f.eb;ec=$f.ec;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:m=i;n=j;o=m;p=n;q=\"\";r=false;s=false;t=0;u=1;v=1;w=0;x=0;y=0;z=0;aa=DU.nil;ab=-1;ac=\"\";while(true){ad=$ifaceNil;ae=S(i);af=ae[0];ag=ae[1];ah=ae[2];ai=$substring(i,af.length,(i.length-ah.length>>0));aj=AJ(j,af);j=aj[0];ad=aj[1];if(!($interfaceIsEqual(ad,$ifaceNil))){$s=-1;return[new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil),new AE.ptr(o,p,af,j,\"\")];}if(ag===0){if(!((j.length===0))){$s=-1;return[new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil),new AE.ptr(o,p,\"\",j,\": extra text: \"+j)];}break;}i=ah;ak=\"\";switch(0){default:al=ag&65535;if(al===(274)){if(j.length<2){ad=AD;break;}am=$substring(j,0,2);an=$substring(j,2);ak=am;j=an;ao=AB(ak);t=ao[0];ad=ao[1];if(t>=69){t=t+(1900)>>0;}else{t=t+(2000)>>0;}}else if(al===(273)){if(j.length<4||!AG(j,0)){ad=AD;break;}ap=$substring(j,0,4);aq=$substring(j,4);ak=ap;j=aq;ar=AB(ak);t=ar[0];ad=ar[1];}else if(al===(258)){as=Y(V,j);u=as[0];j=as[1];ad=as[2];u=u+(1)>>0;}else if(al===(257)){at=Y(W,j);u=at[0];j=at[1];ad=at[2];u=u+(1)>>0;}else if((al===(259))||(al===(260))){au=AH(j,ag===260);u=au[0];j=au[1];ad=au[2];if(u<=0||12<u){q=\"month\";}}else if(al===(262)){av=Y(U,j);j=av[1];ad=av[2];}else if(al===(261)){aw=Y(T,j);j=aw[1];ad=aw[2];}else if((al===(263))||(al===(264))||(al===(265))){if((ag===264)&&j.length>0&&(j.charCodeAt(0)===32)){j=$substring(j,1);}ax=AH(j,ag===265);v=ax[0];j=ax[1];ad=ax[2];if(v<0){q=\"day\";}}else if(al===(522)){ay=AH(j,false);w=ay[0];j=ay[1];ad=ay[2];if(w<0||24<=w){q=\"hour\";}}else if((al===(523))||(al===(524))){az=AH(j,ag===524);w=az[0];j=az[1];ad=az[2];if(w<0||12<w){q=\"hour\";}}else if((al===(525))||(al===(526))){ba=AH(j,ag===526);x=ba[0];j=ba[1];ad=ba[2];if(x<0||60<=x){q=\"minute\";}}else if((al===(527))||(al===(528))){bb=AH(j,ag===528);y=bb[0];j=bb[1];ad=bb[2];if(y<0||60<=y){q=\"second\";break;}if(j.length>=2&&(j.charCodeAt(0)===46)&&AG(j,1)){bc=S(i);ag=bc[1];ag=ag&(65535);if((ag===32)||(ag===33)){break;}bd=2;while(true){if(!(bd<j.length&&AG(j,bd))){break;}bd=bd+(1)>>0;}be=AQ(j,bd);z=be[0];q=be[1];ad=be[2];j=$substring(j,bd);}}else if(al===(531)){if(j.length<2){ad=AD;break;}bf=$substring(j,0,2);bg=$substring(j,2);ak=bf;j=bg;bh=ak;if(bh===(\"PM\")){s=true;}else if(bh===(\"AM\")){r=true;}else{ad=AD;}}else if(al===(532)){if(j.length<2){ad=AD;break;}bi=$substring(j,0,2);bj=$substring(j,2);ak=bi;j=bj;bk=ak;if(bk===(\"pm\")){s=true;}else if(bk===(\"am\")){r=true;}else{ad=AD;}}else if((al===(22))||(al===(25))||(al===(23))||(al===(24))||(al===(26))||(al===(27))||(al===(29))||(al===(30))||(al===(28))||(al===(31))){if(((ag===22)||(ag===24)||(ag===25))&&j.length>=1&&(j.charCodeAt(0)===90)){j=$substring(j,1);aa=$pkg.UTC;break;}bl=\"\";bm=\"\";bn=\"\";bo=\"\";bp=bl;bq=bm;br=bn;bs=bo;if((ag===25)||(ag===30)){if(j.length<6){ad=AD;break;}if(!((j.charCodeAt(3)===58))){ad=AD;break;}bt=$substring(j,0,1);bu=$substring(j,1,3);bv=$substring(j,4,6);bw=\"00\";bx=$substring(j,6);bp=bt;bq=bu;br=bv;bs=bw;j=bx;}else if((ag===29)||(ag===24)){if(j.length<3){ad=AD;break;}by=$substring(j,0,1);bz=$substring(j,1,3);ca=\"00\";cb=\"00\";cc=$substring(j,3);bp=by;bq=bz;br=ca;bs=cb;j=cc;}else if((ag===26)||(ag===31)){if(j.length<9){ad=AD;break;}if(!((j.charCodeAt(3)===58))||!((j.charCodeAt(6)===58))){ad=AD;break;}cd=$substring(j,0,1);ce=$substring(j,1,3);cf=$substring(j,4,6);cg=$substring(j,7,9);ch=$substring(j,9);bp=cd;bq=ce;br=cf;bs=cg;j=ch;}else if((ag===23)||(ag===28)){if(j.length<7){ad=AD;break;}ci=$substring(j,0,1);cj=$substring(j,1,3);ck=$substring(j,3,5);cl=$substring(j,5,7);cm=$substring(j,7);bp=ci;bq=cj;br=ck;bs=cl;j=cm;}else{if(j.length<5){ad=AD;break;}cn=$substring(j,0,1);co=$substring(j,1,3);cp=$substring(j,3,5);cq=\"00\";cr=$substring(j,5);bp=cn;bq=co;br=cp;bs=cq;j=cr;}cs=0;ct=0;cu=0;cv=cs;cw=ct;cx=cu;cy=AB(bq);cv=cy[0];ad=cy[1];if($interfaceIsEqual(ad,$ifaceNil)){cz=AB(br);cw=cz[0];ad=cz[1];}if($interfaceIsEqual(ad,$ifaceNil)){da=AB(bs);cx=da[0];ad=da[1];}ab=($imul(((($imul(cv,60))+cw>>0)),60))+cx>>0;db=bp.charCodeAt(0);if(db===(43)){}else if(db===(45)){ab=-ab;}else{ad=AD;}}else if(al===(21)){if(j.length>=3&&$substring(j,0,3)===\"UTC\"){aa=$pkg.UTC;j=$substring(j,3);break;}dc=AN(j);dd=dc[0];de=dc[1];if(!de){ad=AD;break;}df=$substring(j,0,dd);dg=$substring(j,dd);ac=df;j=dg;}else if(al===(32)){dh=1+((ag>>16>>0))>>0;if(j.length<dh){ad=AD;break;}di=AQ(j,dh);z=di[0];q=di[1];ad=di[2];j=$substring(j,dh);}else if(al===(33)){if(j.length<2||!((j.charCodeAt(0)===46))||j.charCodeAt(1)<48||57<j.charCodeAt(1)){break;}dj=0;while(true){if(!(dj<9&&(dj+1>>0)<j.length&&48<=j.charCodeAt((dj+1>>0))&&j.charCodeAt((dj+1>>0))<=57)){break;}dj=dj+(1)>>0;}dk=AQ(j,1+dj>>0);z=dk[0];q=dk[1];ad=dk[2];j=$substring(j,(1+dj>>0));}}if(!(q===\"\")){$s=-1;return[new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil),new AE.ptr(o,p,ai,j,\": \"+q+\" out of range\")];}if(!($interfaceIsEqual(ad,$ifaceNil))){$s=-1;return[new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil),new AE.ptr(o,p,ai,j,\"\")];}}if(s&&w<12){w=w+(12)>>0;}else if(r&&(w===12)){w=0;}if(v<1||v>CA(((u>>0)),t)){$s=-1;return[new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil),new AE.ptr(o,p,\"\",j,\": day out of range\")];}if(!(aa===DU.nil)){$s=1;continue;}$s=2;continue;case 1:dl=CH(t,((u>>0)),v,w,x,y,z,aa);$s=3;case 3:if($c){$c=false;dl=dl.$blk();}if(dl&&dl.$blk!==undefined){break s;}$s=-1;return[dl,$ifaceNil];case 2:if(!((ab===-1))){$s=4;continue;}$s=5;continue;case 4:dm=CH(t,((u>>0)),v,w,x,y,z,$pkg.UTC);$s=6;case 6:if($c){$c=false;dm=dm.$blk();}if(dm&&dm.$blk!==undefined){break s;}dn=$clone(dm,BL);dn.addSec((dp=(new $Int64(0,ab)),new $Int64(-dp.$high,-dp.$low)));dr=l.lookup(dn.unixSec());$s=7;case 7:if($c){$c=false;dr=dr.$blk();}if(dr&&dr.$blk!==undefined){break s;}dq=dr;ds=dq[0];dt=dq[1];if((dt===ab)&&(ac===\"\"||ds===ac)){dn.setLoc(l);$s=-1;return[dn,$ifaceNil];}dn.setLoc(CP(ac,ab));$s=-1;return[dn,$ifaceNil];case 5:if(!(ac===\"\")){$s=8;continue;}$s=9;continue;case 8:du=CH(t,((u>>0)),v,w,x,y,z,$pkg.UTC);$s=10;case 10:if($c){$c=false;du=du.$blk();}if(du&&du.$blk!==undefined){break s;}dv=$clone(du,BL);dx=l.lookupName(ac,dv.unixSec());$s=11;case 11:if($c){$c=false;dx=dx.$blk();}if(dx&&dx.$blk!==undefined){break s;}dw=dx;dy=dw[0];dz=dw[1];if(dz){dv.addSec((ea=(new $Int64(0,dy)),new $Int64(-ea.$high,-ea.$low)));dv.setLoc(l);$s=-1;return[dv,$ifaceNil];}if(ac.length>3&&$substring(ac,0,3)===\"GMT\"){eb=AB($substring(ac,3));dy=eb[0];dy=$imul(dy,(3600));}dv.setLoc(CP(ac,dy));$s=-1;return[dv,$ifaceNil];case 9:ec=CH(t,((u>>0)),v,w,x,y,z,k);$s=12;case 12:if($c){$c=false;ec=ec.$blk();}if(ec&&ec.$blk!==undefined){break s;}$s=-1;return[ec,$ifaceNil];}return;}if($f===undefined){$f={$blk:AM};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.bu=bu;$f.bv=bv;$f.bw=bw;$f.bx=bx;$f.by=by;$f.bz=bz;$f.ca=ca;$f.cb=cb;$f.cc=cc;$f.cd=cd;$f.ce=ce;$f.cf=cf;$f.cg=cg;$f.ch=ch;$f.ci=ci;$f.cj=cj;$f.ck=ck;$f.cl=cl;$f.cm=cm;$f.cn=cn;$f.co=co;$f.cp=cp;$f.cq=cq;$f.cr=cr;$f.cs=cs;$f.ct=ct;$f.cu=cu;$f.cv=cv;$f.cw=cw;$f.cx=cx;$f.cy=cy;$f.cz=cz;$f.da=da;$f.db=db;$f.dc=dc;$f.dd=dd;$f.de=de;$f.df=df;$f.dg=dg;$f.dh=dh;$f.di=di;$f.dj=dj;$f.dk=dk;$f.dl=dl;$f.dm=dm;$f.dn=dn;$f.dp=dp;$f.dq=dq;$f.dr=dr;$f.ds=ds;$f.dt=dt;$f.du=du;$f.dv=dv;$f.dw=dw;$f.dx=dx;$f.dy=dy;$f.dz=dz;$f.ea=ea;$f.eb=eb;$f.ec=ec;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AN=function(i){var aa,ab,ac,ad,ae,af,ag,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;j=0;k=false;if(i.length<3){l=0;m=false;j=l;k=m;return[j,k];}if(i.length>=4&&($substring(i,0,4)===\"ChST\"||$substring(i,0,4)===\"MeST\")){n=4;o=true;j=n;k=o;return[j,k];}if($substring(i,0,3)===\"GMT\"){j=AO(i);p=j;q=true;j=p;k=q;return[j,k];}if((i.charCodeAt(0)===43)||(i.charCodeAt(0)===45)){j=AP(i);r=j>0;s=j;t=r;j=s;k=t;return[j,k];}u=0;u=0;while(true){if(!(u<6)){break;}if(u>=i.length){break;}v=i.charCodeAt(u);if(v<65||90<v){break;}u=u+(1)>>0;}w=u;if((w===(0))||(w===(1))||(w===(2))||(w===(6))){x=0;y=false;j=x;k=y;return[j,k];}else if(w===(5)){if(i.charCodeAt(4)===84){z=5;aa=true;j=z;k=aa;return[j,k];}}else if(w===(4)){if((i.charCodeAt(3)===84)||$substring(i,0,4)===\"WITA\"){ab=4;ac=true;j=ab;k=ac;return[j,k];}}else if(w===(3)){ad=3;ae=true;j=ad;k=ae;return[j,k];}af=0;ag=false;j=af;k=ag;return[j,k];};AO=function(i){var i;i=$substring(i,3);if(i.length===0){return 3;}return 3+AP(i)>>0;};AP=function(i){var i,j,k,l,m,n;j=i.charCodeAt(0);if(!((j===45))&&!((j===43))){return 0;}k=AS($substring(i,1));l=k[0];m=k[1];n=k[2];if(!($interfaceIsEqual(n,$ifaceNil))||$substring(i,1)===m){return 0;}if(j===45){l=new $Int64(-l.$high,-l.$low);}if((l.$high<-1||(l.$high===-1&&l.$low<4294967273))||(0<l.$high||(0===l.$high&&23<l.$low))){return 0;}return i.length-m.length>>0;};AQ=function(i,j){var i,j,k,l,m,n,o,p;k=0;l=\"\";m=$ifaceNil;if(!((i.charCodeAt(0)===46))){m=AD;return[k,l,m];}n=AB($substring(i,1,j));k=n[0];m=n[1];if(!($interfaceIsEqual(m,$ifaceNil))){return[k,l,m];}if(k<0||1000000000<=k){l=\"fractional second\";return[k,l,m];}o=10-j>>0;p=0;while(true){if(!(p<o)){break;}k=$imul(k,(10));p=p+(1)>>0;}return[k,l,m];};AS=function(i){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;j=new $Int64(0,0);k=\"\";l=$ifaceNil;m=0;while(true){if(!(m<i.length)){break;}n=i.charCodeAt(m);if(n<48||n>57){break;}if((j.$high>214748364||(j.$high===214748364&&j.$low>3435973836))){o=new $Int64(0,0);p=\"\";q=AR;j=o;k=p;l=q;return[j,k,l];}j=(r=(s=$mul64(j,new $Int64(0,10)),t=(new $Int64(0,n)),new $Int64(s.$high+t.$high,s.$low+t.$low)),new $Int64(r.$high-0,r.$low-48));if((j.$high<0||(j.$high===0&&j.$low<0))){u=new $Int64(0,0);v=\"\";w=AR;j=u;k=v;l=w;return[j,k,l];}m=m+(1)>>0;}x=j;y=$substring(i,m);z=$ifaceNil;j=x;k=y;l=z;return[j,k,l];};AW=function(i){var i,j,k,l;if((i.$high<0||(i.$high===0&&i.$low<=0))){return I();}l=(j=I(),k=(new $Int64(i.$high,i.$low)),new $Int64(j.$high+k.$high,j.$low+k.$low));if((l.$high<0||(l.$high===0&&l.$low<0))){l=new $Int64(2147483647,4294967295);}return l;};AX.ptr.prototype.Stop=function(){var i;i=this;if(i.r.f===$throwNilPointerError){$panic(new $String(\"time: Stop called on uninitialized Timer\"));}return M(i.r);};AX.prototype.Stop=function(){return this.$val.Stop();};AY=function(i){var i,j,k;j=new $Chan(BL,1);k=new AX.ptr(j,new G.ptr(0,AW(i),new $Int64(0,0),AZ,new DV(j),null,false));L(k.r);return k;};$pkg.NewTimer=AY;AX.ptr.prototype.Reset=function(i){var i,j,k,l;j=this;if(j.r.f===$throwNilPointerError){$panic(new $String(\"time: Reset called on uninitialized Timer\"));}k=AW(i);l=M(j.r);j.r.when=k;L(j.r);return l;};AX.prototype.Reset=function(i){return this.$val.Reset(i);};AZ=function(i,j){var i,j,k,$r;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;$r=$f.$r;}k=$select([[$assertType(i,DV),$clone(CC(),BL)],[]]);if(k[0]===0){}else if(k[0]===1){}if($f===undefined){$f={$blk:AZ};}$f.i=i;$f.j=j;$f.k=k;$f.$r=$r;return $f;};BJ=function(i){var i,j,k;if((i.$high<0||(i.$high===0&&i.$low<=0))){$panic(C.New(\"non-positive interval for NewTicker\"));}j=new $Chan(BL,1);k=new BI.ptr(j,new G.ptr(0,AW(i),(new $Int64(i.$high,i.$low)),AZ,new DV(j),null,false));L(k.r);return k;};$pkg.NewTicker=BJ;BI.ptr.prototype.Stop=function(){var i;i=this;M(i.r);};BI.prototype.Stop=function(){return this.$val.Stop();};BL.ptr.prototype.nsec=function(){var i,j;i=this;return(((j=i.wall,new $Uint64(j.$high&0,(j.$low&1073741823)>>>0)).$low>>0));};BL.prototype.nsec=function(){return this.$val.nsec();};BL.ptr.prototype.sec=function(){var i,j,k,l,m;i=this;if(!((j=(k=i.wall,new $Uint64(k.$high&2147483648,(k.$low&0)>>>0)),(j.$high===0&&j.$low===0)))){return(l=((m=$shiftRightUint64($shiftLeft64(i.wall,1),31),new $Int64(m.$high,m.$low))),new $Int64(13+l.$high,3618733952+l.$low));}return i.ext;};BL.prototype.sec=function(){return this.$val.sec();};BL.ptr.prototype.unixSec=function(){var i,j;i=this;return(j=i.sec(),new $Int64(j.$high+-15,j.$low+2288912640));};BL.prototype.unixSec=function(){return this.$val.unixSec();};BL.ptr.prototype.addSec=function(i){var i,j,k,l,m,n,o,p,q,r,s,t,u;j=this;if(!((k=(l=j.wall,new $Uint64(l.$high&2147483648,(l.$low&0)>>>0)),(k.$high===0&&k.$low===0)))){n=((m=$shiftRightUint64($shiftLeft64(j.wall,1),31),new $Int64(m.$high,m.$low)));o=new $Int64(n.$high+i.$high,n.$low+i.$low);if((0<o.$high||(0===o.$high&&0<=o.$low))&&(o.$high<1||(o.$high===1&&o.$low<=4294967295))){j.wall=(p=(q=(r=j.wall,new $Uint64(r.$high&0,(r.$low&1073741823)>>>0)),s=$shiftLeft64((new $Uint64(o.$high,o.$low)),30),new $Uint64(q.$high|s.$high,(q.$low|s.$low)>>>0)),new $Uint64(p.$high|2147483648,(p.$low|0)>>>0));return;}j.stripMono();}j.ext=(t=j.ext,u=i,new $Int64(t.$high+u.$high,t.$low+u.$low));};BL.prototype.addSec=function(i){return this.$val.addSec(i);};BL.ptr.prototype.setLoc=function(i){var i,j;j=this;if(i===CM){i=DU.nil;}j.stripMono();j.loc=i;};BL.prototype.setLoc=function(i){return this.$val.setLoc(i);};BL.ptr.prototype.stripMono=function(){var i,j,k,l,m;i=this;if(!((j=(k=i.wall,new $Uint64(k.$high&2147483648,(k.$low&0)>>>0)),(j.$high===0&&j.$low===0)))){i.ext=i.sec();i.wall=(l=i.wall,m=new $Uint64(0,1073741823),new $Uint64(l.$high&m.$high,(l.$low&m.$low)>>>0));}};BL.prototype.stripMono=function(){return this.$val.stripMono();};BL.ptr.prototype.After=function(i){var i,j,k,l,m,n,o,p,q,r;j=this;if(!((k=(l=(m=j.wall,n=i.wall,new $Uint64(m.$high&n.$high,(m.$low&n.$low)>>>0)),new $Uint64(l.$high&2147483648,(l.$low&0)>>>0)),(k.$high===0&&k.$low===0)))){return(o=j.ext,p=i.ext,(o.$high>p.$high||(o.$high===p.$high&&o.$low>p.$low)));}q=j.sec();r=i.sec();return(q.$high>r.$high||(q.$high===r.$high&&q.$low>r.$low))||(q.$high===r.$high&&q.$low===r.$low)&&j.nsec()>i.nsec();};BL.prototype.After=function(i){return this.$val.After(i);};BL.ptr.prototype.Before=function(i){var i,j,k,l,m,n,o,p,q,r,s,t;j=this;if(!((k=(l=(m=j.wall,n=i.wall,new $Uint64(m.$high&n.$high,(m.$low&n.$low)>>>0)),new $Uint64(l.$high&2147483648,(l.$low&0)>>>0)),(k.$high===0&&k.$low===0)))){return(o=j.ext,p=i.ext,(o.$high<p.$high||(o.$high===p.$high&&o.$low<p.$low)));}return(q=j.sec(),r=i.sec(),(q.$high<r.$high||(q.$high===r.$high&&q.$low<r.$low)))||(s=j.sec(),t=i.sec(),(s.$high===t.$high&&s.$low===t.$low))&&j.nsec()<i.nsec();};BL.prototype.Before=function(i){return this.$val.Before(i);};BL.ptr.prototype.Equal=function(i){var i,j,k,l,m,n,o,p,q,r;j=this;if(!((k=(l=(m=j.wall,n=i.wall,new $Uint64(m.$high&n.$high,(m.$low&n.$low)>>>0)),new $Uint64(l.$high&2147483648,(l.$low&0)>>>0)),(k.$high===0&&k.$low===0)))){return(o=j.ext,p=i.ext,(o.$high===p.$high&&o.$low===p.$low));}return(q=j.sec(),r=i.sec(),(q.$high===r.$high&&q.$low===r.$low))&&(j.nsec()===i.nsec());};BL.prototype.Equal=function(i){return this.$val.Equal(i);};BM.prototype.String=function(){var i,j,k,l;i=this.$val;if(1<=i&&i<=12){return(j=i-1>>0,((j<0||j>=BN.length)?($throwRuntimeError(\"index out of range\"),undefined):BN[j]));}k=$makeSlice(DR,20);l=BU(k,(new $Uint64(0,i)));return\"%!Month(\"+($bytesToString($subslice(k,l)))+\")\";};$ptrType(BM).prototype.String=function(){return new BM(this.$get()).String();};BO.prototype.String=function(){var i,j,k;i=this.$val;if(0<=i&&i<=6){return((i<0||i>=BP.length)?($throwRuntimeError(\"index out of range\"),undefined):BP[i]);}j=$makeSlice(DR,20);k=BU(j,(new $Uint64(0,i)));return\"%!Weekday(\"+($bytesToString($subslice(j,k)))+\")\";};$ptrType(BO).prototype.String=function(){return new BO(this.$get()).String();};BL.ptr.prototype.IsZero=function(){var i,j;i=this;return(j=i.sec(),(j.$high===0&&j.$low===0))&&(i.nsec()===0);};BL.prototype.IsZero=function(){return this.$val.IsZero();};BL.ptr.prototype.abs=function(){var i,j,k,l,m,n,o,p,q,r,s,t,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=i.loc;if(j===DU.nil||j===CN){$s=1;continue;}$s=2;continue;case 1:k=j.get();$s=3;case 3:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;case 2:l=i.unixSec();if(!(j===CM)){$s=4;continue;}$s=5;continue;case 4:if(!(j.cacheZone===DM.nil)&&(m=j.cacheStart,(m.$high<l.$high||(m.$high===l.$high&&m.$low<=l.$low)))&&(n=j.cacheEnd,(l.$high<n.$high||(l.$high===n.$high&&l.$low<n.$low)))){$s=6;continue;}$s=7;continue;case 6:l=(o=(new $Int64(0,j.cacheZone.offset)),new $Int64(l.$high+o.$high,l.$low+o.$low));$s=8;continue;case 7:q=j.lookup(l);$s=9;case 9:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;r=p[1];l=(s=(new $Int64(0,r)),new $Int64(l.$high+s.$high,l.$low+s.$low));case 8:case 5:$s=-1;return((t=new $Int64(l.$high+2147483646,l.$low+450480384),new $Uint64(t.$high,t.$low)));}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.abs};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.abs=function(){return this.$val.abs();};BL.ptr.prototype.locabs=function(){var i,j,k,l,m,n,o,p,q,r,s,t,u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=\"\";j=0;k=new $Uint64(0,0);l=this;m=l.loc;if(m===DU.nil||m===CN){$s=1;continue;}$s=2;continue;case 1:n=m.get();$s=3;case 3:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;case 2:o=l.unixSec();if(!(m===CM)){$s=4;continue;}$s=5;continue;case 4:if(!(m.cacheZone===DM.nil)&&(p=m.cacheStart,(p.$high<o.$high||(p.$high===o.$high&&p.$low<=o.$low)))&&(q=m.cacheEnd,(o.$high<q.$high||(o.$high===q.$high&&o.$low<q.$low)))){$s=7;continue;}$s=8;continue;case 7:i=m.cacheZone.name;j=m.cacheZone.offset;$s=9;continue;case 8:s=m.lookup(o);$s=10;case 10:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}r=s;i=r[0];j=r[1];case 9:o=(t=(new $Int64(0,j)),new $Int64(o.$high+t.$high,o.$low+t.$low));$s=6;continue;case 5:i=\"UTC\";case 6:k=((u=new $Int64(o.$high+2147483646,o.$low+450480384),new $Uint64(u.$high,u.$low)));$s=-1;return[i,j,k];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.locabs};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.locabs=function(){return this.$val.locabs();};BL.ptr.prototype.Date=function(){var i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=0;j=0;k=0;l=this;n=$clone(l,BL).date(true);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;i=m[0];j=m[1];k=m[2];$s=-1;return[i,j,k];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Date};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Date=function(){return this.$val.Date();};BL.ptr.prototype.Year=function(){var i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;k=$clone(i,BL).date(false);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[0];$s=-1;return l;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Year};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Year=function(){return this.$val.Year();};BL.ptr.prototype.Month=function(){var i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;k=$clone(i,BL).date(true);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[1];$s=-1;return l;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Month};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Month=function(){return this.$val.Month();};BL.ptr.prototype.Day=function(){var i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;k=$clone(i,BL).date(true);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[2];$s=-1;return l;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Day};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Day=function(){return this.$val.Day();};BL.ptr.prototype.Weekday=function(){var i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=$clone(i,BL).abs();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=BQ(j);$s=2;case 2:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$s=-1;return k;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Weekday};}$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Weekday=function(){return this.$val.Weekday();};BQ=function(i){var i,j,k;j=$div64((new $Uint64(i.$high+0,i.$low+86400)),new $Uint64(0,604800),true);return(((k=((j.$low>>0))/86400,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\"))>>0));};BL.ptr.prototype.ISOWeek=function(){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=0;j=0;k=this;m=$clone(k,BL).date(true);$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;i=l[0];n=l[1];o=l[2];p=l[3];r=$clone(k,BL).Weekday();$s=2;case 2:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}s=(q=(((r+6>>0)>>0))%7,q===q?q:$throwRuntimeError(\"integer divide by zero\"));j=(t=(((p-s>>0)+7>>0))/7,(t===t&&t!==1/0&&t!==-1/0)?t>>0:$throwRuntimeError(\"integer divide by zero\"));v=(u=(((s-p>>0)+371>>0))%7,u===u?u:$throwRuntimeError(\"integer divide by zero\"));if(1<=v&&v<=3){j=j+(1)>>0;}if(j===0){i=i-(1)>>0;j=52;if((v===4)||((v===5)&&CF(i))){j=j+(1)>>0;}}if((n===12)&&o>=29&&s<3){x=(w=(((s+31>>0)-o>>0))%7,w===w?w:$throwRuntimeError(\"integer divide by zero\"));if(0<=x&&x<=2){i=i+(1)>>0;j=1;}}$s=-1;return[i,j];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.ISOWeek};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.ISOWeek=function(){return this.$val.ISOWeek();};BL.ptr.prototype.Clock=function(){var i,j,k,l,m,n,o,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=0;j=0;k=0;l=this;n=$clone(l,BL).abs();$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=BR(n);$s=2;case 2:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}m=o;i=m[0];j=m[1];k=m[2];$s=-1;return[i,j,k];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Clock};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Clock=function(){return this.$val.Clock();};BR=function(i){var i,j,k,l,m,n;j=0;k=0;l=0;l=(($div64(i,new $Uint64(0,86400),true).$low>>0));j=(m=l/3600,(m===m&&m!==1/0&&m!==-1/0)?m>>0:$throwRuntimeError(\"integer divide by zero\"));l=l-(($imul(j,3600)))>>0;k=(n=l/60,(n===n&&n!==1/0&&n!==-1/0)?n>>0:$throwRuntimeError(\"integer divide by zero\"));l=l-(($imul(k,60)))>>0;return[j,k,l];};BL.ptr.prototype.Hour=function(){var i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;k=$clone(i,BL).abs();$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$s=-1;return(j=(($div64(k,new $Uint64(0,86400),true).$low>>0))/3600,(j===j&&j!==1/0&&j!==-1/0)?j>>0:$throwRuntimeError(\"integer divide by zero\"));}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Hour};}$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Hour=function(){return this.$val.Hour();};BL.ptr.prototype.Minute=function(){var i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;k=$clone(i,BL).abs();$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$s=-1;return(j=(($div64(k,new $Uint64(0,3600),true).$low>>0))/60,(j===j&&j!==1/0&&j!==-1/0)?j>>0:$throwRuntimeError(\"integer divide by zero\"));}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Minute};}$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Minute=function(){return this.$val.Minute();};BL.ptr.prototype.Second=function(){var i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=$clone(i,BL).abs();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}$s=-1;return(($div64(j,new $Uint64(0,60),true).$low>>0));}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Second};}$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Second=function(){return this.$val.Second();};BL.ptr.prototype.Nanosecond=function(){var i;i=this;return((i.nsec()>>0));};BL.prototype.Nanosecond=function(){return this.$val.Nanosecond();};BL.ptr.prototype.YearDay=function(){var i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;k=$clone(i,BL).date(false);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[3];$s=-1;return l+1>>0;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.YearDay};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.YearDay=function(){return this.$val.YearDay();};BS.prototype.String=function(){var i,j,k,l,m,n,o,p;i=this;j=DX.zero();k=32;l=(new $Uint64(i.$high,i.$low));m=(i.$high<0||(i.$high===0&&i.$low<0));if(m){l=new $Uint64(-l.$high,-l.$low);}if((l.$high<0||(l.$high===0&&l.$low<1000000000))){n=0;k=k-(1)>>0;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=115);k=k-(1)>>0;if((l.$high===0&&l.$low===0)){return\"0s\";}else if((l.$high<0||(l.$high===0&&l.$low<1000))){n=0;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=110);}else if((l.$high<0||(l.$high===0&&l.$low<1000000))){n=3;k=k-(1)>>0;$copyString($subslice(new DR(j),k),\"\\xC2\\xB5\");}else{n=6;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=109);}o=BT($subslice(new DR(j),0,k),l,n);k=o[0];l=o[1];k=BU($subslice(new DR(j),0,k),l);}else{k=k-(1)>>0;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=115);p=BT($subslice(new DR(j),0,k),l,9);k=p[0];l=p[1];k=BU($subslice(new DR(j),0,k),$div64(l,new $Uint64(0,60),true));l=$div64(l,(new $Uint64(0,60)),false);if((l.$high>0||(l.$high===0&&l.$low>0))){k=k-(1)>>0;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=109);k=BU($subslice(new DR(j),0,k),$div64(l,new $Uint64(0,60),true));l=$div64(l,(new $Uint64(0,60)),false);if((l.$high>0||(l.$high===0&&l.$low>0))){k=k-(1)>>0;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=104);k=BU($subslice(new DR(j),0,k),l);}}}if(m){k=k-(1)>>0;((k<0||k>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[k]=45);}return($bytesToString($subslice(new DR(j),k)));};$ptrType(BS).prototype.String=function(){return this.$get().String();};BT=function(i,j,k){var i,j,k,l,m,n,o,p,q,r,s;l=0;m=new $Uint64(0,0);n=i.$length;o=false;p=0;while(true){if(!(p<k)){break;}q=$div64(j,new $Uint64(0,10),true);o=o||!((q.$high===0&&q.$low===0));if(o){n=n-(1)>>0;((n<0||n>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+n]=(((q.$low<<24>>>24))+48<<24>>>24));}j=$div64(j,(new $Uint64(0,10)),false);p=p+(1)>>0;}if(o){n=n-(1)>>0;((n<0||n>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+n]=46);}r=n;s=j;l=r;m=s;return[l,m];};BU=function(i,j){var i,j,k;k=i.$length;if((j.$high===0&&j.$low===0)){k=k-(1)>>0;((k<0||k>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+k]=48);}else{while(true){if(!((j.$high>0||(j.$high===0&&j.$low>0)))){break;}k=k-(1)>>0;((k<0||k>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+k]=((($div64(j,new $Uint64(0,10),true).$low<<24>>>24))+48<<24>>>24));j=$div64(j,(new $Uint64(0,10)),false);}}return k;};BS.prototype.Nanoseconds=function(){var i;i=this;return(new $Int64(i.$high,i.$low));};$ptrType(BS).prototype.Nanoseconds=function(){return this.$get().Nanoseconds();};BS.prototype.Seconds=function(){var i,j,k;i=this;j=$div64(i,new BS(0,1000000000),false);k=$div64(i,new BS(0,1000000000),true);return($flatten64(j))+($flatten64(k))/1e+09;};$ptrType(BS).prototype.Seconds=function(){return this.$get().Seconds();};BS.prototype.Minutes=function(){var i,j,k;i=this;j=$div64(i,new BS(13,4165425152),false);k=$div64(i,new BS(13,4165425152),true);return($flatten64(j))+($flatten64(k))/6e+10;};$ptrType(BS).prototype.Minutes=function(){return this.$get().Minutes();};BS.prototype.Hours=function(){var i,j,k;i=this;j=$div64(i,new BS(838,817405952),false);k=$div64(i,new BS(838,817405952),true);return($flatten64(j))+($flatten64(k))/3.6e+12;};$ptrType(BS).prototype.Hours=function(){return this.$get().Hours();};BS.prototype.Truncate=function(i){var i,j,k;j=this;if((i.$high<0||(i.$high===0&&i.$low<=0))){return j;}return(k=$div64(j,i,true),new BS(j.$high-k.$high,j.$low-k.$low));};$ptrType(BS).prototype.Truncate=function(i){return this.$get().Truncate(i);};BV=function(i,j){var i,j,k,l,m,n;return(k=(l=(new $Uint64(i.$high,i.$low)),m=(new $Uint64(i.$high,i.$low)),new $Uint64(l.$high+m.$high,l.$low+m.$low)),n=(new $Uint64(j.$high,j.$low)),(k.$high<n.$high||(k.$high===n.$high&&k.$low<n.$low)));};BS.prototype.Round=function(i){var i,j,k,l,m,n,o;j=this;if((i.$high<0||(i.$high===0&&i.$low<=0))){return j;}k=$div64(j,i,true);if((j.$high<0||(j.$high===0&&j.$low<0))){k=new BS(-k.$high,-k.$low);if(BV(k,i)){return new BS(j.$high+k.$high,j.$low+k.$low);}m=(l=new BS(j.$high-i.$high,j.$low-i.$low),new BS(l.$high+k.$high,l.$low+k.$low));if((m.$high<j.$high||(m.$high===j.$high&&m.$low<j.$low))){return m;}return new BS(-2147483648,0);}if(BV(k,i)){return new BS(j.$high-k.$high,j.$low-k.$low);}o=(n=new BS(j.$high+i.$high,j.$low+i.$low),new BS(n.$high-k.$high,n.$low-k.$low));if((o.$high>j.$high||(o.$high===j.$high&&o.$low>j.$low))){return o;}return new BS(2147483647,4294967295);};$ptrType(BS).prototype.Round=function(i){return this.$get().Round(i);};BL.ptr.prototype.Add=function(i){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;j=this;l=((k=$div64(i,new BS(0,1000000000),false),new $Int64(k.$high,k.$low)));n=j.nsec()+(((m=$div64(i,new BS(0,1000000000),true),m.$low+((m.$high>>31)*4294967296))>>0))>>0;if(n>=1000000000){l=(o=new $Int64(0,1),new $Int64(l.$high+o.$high,l.$low+o.$low));n=n-(1000000000)>>0;}else if(n<0){l=(p=new $Int64(0,1),new $Int64(l.$high-p.$high,l.$low-p.$low));n=n+(1000000000)>>0;}j.wall=(q=(r=j.wall,new $Uint64(r.$high&~0,(r.$low&~1073741823)>>>0)),s=(new $Uint64(0,n)),new $Uint64(q.$high|s.$high,(q.$low|s.$low)>>>0));j.addSec(l);if(!((t=(u=j.wall,new $Uint64(u.$high&2147483648,(u.$low&0)>>>0)),(t.$high===0&&t.$low===0)))){x=(v=j.ext,w=(new $Int64(i.$high,i.$low)),new $Int64(v.$high+w.$high,v.$low+w.$low));if((i.$high<0||(i.$high===0&&i.$low<0))&&(y=j.ext,(x.$high>y.$high||(x.$high===y.$high&&x.$low>y.$low)))||(i.$high>0||(i.$high===0&&i.$low>0))&&(z=j.ext,(x.$high<z.$high||(x.$high===z.$high&&x.$low<z.$low)))){j.stripMono();}else{j.ext=x;}}return j;};BL.prototype.Add=function(i){return this.$val.Add(i);};BL.ptr.prototype.Sub=function(i){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;j=this;if(!((k=(l=(m=j.wall,n=i.wall,new $Uint64(m.$high&n.$high,(m.$low&n.$low)>>>0)),new $Uint64(l.$high&2147483648,(l.$low&0)>>>0)),(k.$high===0&&k.$low===0)))){o=j.ext;p=i.ext;r=((q=new $Int64(o.$high-p.$high,o.$low-p.$low),new BS(q.$high,q.$low)));if((r.$high<0||(r.$high===0&&r.$low<0))&&(o.$high>p.$high||(o.$high===p.$high&&o.$low>p.$low))){return new BS(2147483647,4294967295);}if((r.$high>0||(r.$high===0&&r.$low>0))&&(o.$high<p.$high||(o.$high===p.$high&&o.$low<p.$low))){return new BS(-2147483648,0);}return r;}x=(s=$mul64(((t=(u=j.sec(),v=i.sec(),new $Int64(u.$high-v.$high,u.$low-v.$low)),new BS(t.$high,t.$low))),new BS(0,1000000000)),w=(new BS(0,(j.nsec()-i.nsec()>>0))),new BS(s.$high+w.$high,s.$low+w.$low));if($clone($clone(i,BL).Add(x),BL).Equal($clone(j,BL))){return x;}else if($clone(j,BL).Before($clone(i,BL))){return new BS(-2147483648,0);}else{return new BS(2147483647,4294967295);}};BL.prototype.Sub=function(i){return this.$val.Sub(i);};BX=function(i){var i,j,k,l,m;j=new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil);if(!((k=(l=i.wall,new $Uint64(l.$high&2147483648,(l.$low&0)>>>0)),(k.$high===0&&k.$low===0)))){BL.copy(j,new BL.ptr(new $Uint64(2147483648,0),(m=I(),new $Int64(m.$high-CB.$high,m.$low-CB.$low)),DU.nil));}else{BL.copy(j,CC());}return $clone(i,BL).Sub($clone(j,BL));};$pkg.Until=BX;BL.ptr.prototype.AddDate=function(i,j,k){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;n=$clone(l,BL).Date();$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];q=m[2];s=$clone(l,BL).Clock();$s=2;case 2:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}r=s;t=r[0];u=r[1];v=r[2];w=CH(o+i>>0,p+((j>>0))>>0,q+k>>0,t,u,v,((l.nsec()>>0)),$clone(l,BL).Location());$s=3;case 3:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}$s=-1;return w;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.AddDate};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.AddDate=function(i,j,k){return this.$val.AddDate(i,j,k);};BL.ptr.prototype.date=function(i){var i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=0;k=0;l=0;m=0;n=this;p=$clone(n,BL).abs();$s=1;case 1:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=BY(p,i);$s=2;case 2:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}o=q;j=o[0];k=o[1];l=o[2];m=o[3];$s=-1;return[j,k,l,m];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.date};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.date=function(i){return this.$val.date(i);};BY=function(i,j){var aa,ab,ac,ad,ae,af,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;k=0;l=0;m=0;n=0;o=$div64(i,new $Uint64(0,86400),false);p=$div64(o,new $Uint64(0,146097),false);q=$mul64(new $Uint64(0,400),p);o=(r=$mul64(new $Uint64(0,146097),p),new $Uint64(o.$high-r.$high,o.$low-r.$low));p=$div64(o,new $Uint64(0,36524),false);p=(s=$shiftRightUint64(p,2),new $Uint64(p.$high-s.$high,p.$low-s.$low));q=(t=$mul64(new $Uint64(0,100),p),new $Uint64(q.$high+t.$high,q.$low+t.$low));o=(u=$mul64(new $Uint64(0,36524),p),new $Uint64(o.$high-u.$high,o.$low-u.$low));p=$div64(o,new $Uint64(0,1461),false);q=(v=$mul64(new $Uint64(0,4),p),new $Uint64(q.$high+v.$high,q.$low+v.$low));o=(w=$mul64(new $Uint64(0,1461),p),new $Uint64(o.$high-w.$high,o.$low-w.$low));p=$div64(o,new $Uint64(0,365),false);p=(x=$shiftRightUint64(p,2),new $Uint64(p.$high-x.$high,p.$low-x.$low));q=(y=p,new $Uint64(q.$high+y.$high,q.$low+y.$low));o=(z=$mul64(new $Uint64(0,365),p),new $Uint64(o.$high-z.$high,o.$low-z.$low));k=(((aa=(ab=(new $Int64(q.$high,q.$low)),new $Int64(ab.$high+-69,ab.$low+4075721025)),aa.$low+((aa.$high>>31)*4294967296))>>0));n=((o.$low>>0));if(!j){return[k,l,m,n];}m=n;if(CF(k)){if(m>59){m=m-(1)>>0;}else if((m===59)){l=2;m=29;return[k,l,m,n];}}l=(((ac=m/31,(ac===ac&&ac!==1/0&&ac!==-1/0)?ac>>0:$throwRuntimeError(\"integer divide by zero\"))>>0));ae=(((ad=l+1>>0,((ad<0||ad>=BZ.length)?($throwRuntimeError(\"index out of range\"),undefined):BZ[ad]))>>0));af=0;if(m>=ae){l=l+(1)>>0;af=ae;}else{af=((((l<0||l>=BZ.length)?($throwRuntimeError(\"index out of range\"),undefined):BZ[l])>>0));}l=l+(1)>>0;m=(m-af>>0)+1>>0;return[k,l,m,n];};CA=function(i,j){var i,j,k;if((i===2)&&CF(j)){return 29;}return(((((i<0||i>=BZ.length)?($throwRuntimeError(\"index out of range\"),undefined):BZ[i])-(k=i-1>>0,((k<0||k>=BZ.length)?($throwRuntimeError(\"index out of range\"),undefined):BZ[k]))>>0)>>0));};CC=function(){var i,j,k,l,m,n,o,p,q,r;i=J();j=i[0];k=i[1];l=i[2];l=(m=CB,new $Int64(l.$high-m.$high,l.$low-m.$low));j=(n=new $Int64(0,2682288000),new $Int64(j.$high+n.$high,j.$low+n.$low));if(!((o=$shiftRightUint64((new $Uint64(j.$high,j.$low)),33),(o.$high===0&&o.$low===0)))){return new BL.ptr((new $Uint64(0,k)),new $Int64(j.$high+13,j.$low+3618733952),$pkg.Local);}return new BL.ptr((p=(q=$shiftLeft64((new $Uint64(j.$high,j.$low)),30),new $Uint64(2147483648|q.$high,(0|q.$low)>>>0)),r=(new $Uint64(0,k)),new $Uint64(p.$high|r.$high,(p.$low|r.$low)>>>0)),l,$pkg.Local);};$pkg.Now=CC;CD=function(i,j){var i,j;return new BL.ptr((new $Uint64(0,j)),new $Int64(i.$high+14,i.$low+2006054656),$pkg.Local);};BL.ptr.prototype.UTC=function(){var i;i=this;i.setLoc(CM);return i;};BL.prototype.UTC=function(){return this.$val.UTC();};BL.ptr.prototype.Local=function(){var i;i=this;i.setLoc($pkg.Local);return i;};BL.prototype.Local=function(){return this.$val.Local();};BL.ptr.prototype.In=function(i){var i,j;j=this;if(i===DU.nil){$panic(new $String(\"time: missing Location in call to Time.In\"));}j.setLoc(i);return j;};BL.prototype.In=function(i){return this.$val.In(i);};BL.ptr.prototype.Location=function(){var i,j;i=this;j=i.loc;if(j===DU.nil){j=$pkg.UTC;}return j;};BL.prototype.Location=function(){return this.$val.Location();};BL.ptr.prototype.Zone=function(){var i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=\"\";j=0;k=this;m=k.loc.lookup(k.unixSec());$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;i=l[0];j=l[1];$s=-1;return[i,j];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.Zone};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.Zone=function(){return this.$val.Zone();};BL.ptr.prototype.Unix=function(){var i;i=this;return i.unixSec();};BL.prototype.Unix=function(){return this.$val.Unix();};BL.ptr.prototype.UnixNano=function(){var i,j,k;i=this;return(j=$mul64((i.unixSec()),new $Int64(0,1000000000)),k=(new $Int64(0,i.nsec())),new $Int64(j.$high+k.$high,j.$low+k.$low));};BL.prototype.UnixNano=function(){return this.$val.UnixNano();};BL.ptr.prototype.MarshalBinary=function(){var i,j,k,l,m,n,o,p,q,r,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=0;if($clone(i,BL).Location()===$pkg.UTC){$s=1;continue;}$s=2;continue;case 1:j=-1;$s=3;continue;case 2:l=$clone(i,BL).Zone();$s=4;case 4:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}k=l;m=k[1];if(!(((n=m%60,n===n?n:$throwRuntimeError(\"integer divide by zero\"))===0))){$s=-1;return[DR.nil,C.New(\"Time.MarshalBinary: zone offset has fractional minute\")];}m=(o=m/(60),(o===o&&o!==1/0&&o!==-1/0)?o>>0:$throwRuntimeError(\"integer divide by zero\"));if(m<-32768||(m===-1)||m>32767){$s=-1;return[DR.nil,C.New(\"Time.MarshalBinary: unexpected zone offset\")];}j=((m<<16>>16));case 3:p=i.sec();q=i.nsec();r=new DR([1,(($shiftRightInt64(p,56).$low<<24>>>24)),(($shiftRightInt64(p,48).$low<<24>>>24)),(($shiftRightInt64(p,40).$low<<24>>>24)),(($shiftRightInt64(p,32).$low<<24>>>24)),(($shiftRightInt64(p,24).$low<<24>>>24)),(($shiftRightInt64(p,16).$low<<24>>>24)),(($shiftRightInt64(p,8).$low<<24>>>24)),((p.$low<<24>>>24)),(((q>>24>>0)<<24>>>24)),(((q>>16>>0)<<24>>>24)),(((q>>8>>0)<<24>>>24)),((q<<24>>>24)),(((j>>8<<16>>16)<<24>>>24)),((j<<24>>>24))]);$s=-1;return[r,$ifaceNil];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.MarshalBinary};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.MarshalBinary=function(){return this.$val.MarshalBinary();};BL.ptr.prototype.UnmarshalBinary=function(i){var aa,ab,ac,ad,ae,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=this;k=i;if(k.$length===0){$s=-1;return C.New(\"Time.UnmarshalBinary: no data\");}if(!(((0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])===1))){$s=-1;return C.New(\"Time.UnmarshalBinary: unsupported version\");}if(!((k.$length===15))){$s=-1;return C.New(\"Time.UnmarshalBinary: invalid length\");}k=$subslice(k,1);z=(l=(m=(n=(o=(p=(q=(r=(new $Int64(0,(7>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+7]))),s=$shiftLeft64((new $Int64(0,(6>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+6]))),8),new $Int64(r.$high|s.$high,(r.$low|s.$low)>>>0)),t=$shiftLeft64((new $Int64(0,(5>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+5]))),16),new $Int64(q.$high|t.$high,(q.$low|t.$low)>>>0)),u=$shiftLeft64((new $Int64(0,(4>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+4]))),24),new $Int64(p.$high|u.$high,(p.$low|u.$low)>>>0)),v=$shiftLeft64((new $Int64(0,(3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3]))),32),new $Int64(o.$high|v.$high,(o.$low|v.$low)>>>0)),w=$shiftLeft64((new $Int64(0,(2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2]))),40),new $Int64(n.$high|w.$high,(n.$low|w.$low)>>>0)),x=$shiftLeft64((new $Int64(0,(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]))),48),new $Int64(m.$high|x.$high,(m.$low|x.$low)>>>0)),y=$shiftLeft64((new $Int64(0,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]))),56),new $Int64(l.$high|y.$high,(l.$low|y.$low)>>>0));k=$subslice(k,8);aa=(((((3>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+3])>>0))|((((2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2])>>0))<<8>>0))|((((1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1])>>0))<<16>>0))|((((0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])>>0))<<24>>0);k=$subslice(k,4);ab=$imul(((((((1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1])<<16>>16))|((((0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])<<16>>16))<<8<<16>>16))>>0)),60);BL.copy(j,new BL.ptr(new $Uint64(0,0),new $Int64(0,0),DU.nil));j.wall=(new $Uint64(0,aa));j.ext=z;if(ab===-60){$s=1;continue;}$s=2;continue;case 1:j.setLoc(CM);$s=3;continue;case 2:ad=$pkg.Local.lookup(j.unixSec());$s=4;case 4:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ac=ad;ae=ac[1];if(ab===ae){j.setLoc($pkg.Local);}else{j.setLoc(CP(\"\",ab));}case 3:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.UnmarshalBinary};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.UnmarshalBinary=function(i){return this.$val.UnmarshalBinary(i);};BL.ptr.prototype.GobEncode=function(){var i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=$clone(i,BL).MarshalBinary();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}$s=-1;return j;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.GobEncode};}$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.GobEncode=function(){return this.$val.GobEncode();};BL.ptr.prototype.GobDecode=function(i){var i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=this;k=j.UnmarshalBinary(i);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$s=-1;return k;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.GobDecode};}$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.GobDecode=function(i){return this.$val.GobDecode(i);};BL.ptr.prototype.MarshalJSON=function(){var i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=$clone(i,BL).Year();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;if(k<0||k>=10000){$s=-1;return[DR.nil,C.New(\"Time.MarshalJSON: year outside of range [0,9999]\")];}l=$makeSlice(DR,0,37);l=$append(l,34);m=$clone(i,BL).AppendFormat(l,\"2006-01-02T15:04:05.999999999Z07:00\");$s=2;case 2:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;l=$append(l,34);$s=-1;return[l,$ifaceNil];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.MarshalJSON};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.MarshalJSON=function(){return this.$val.MarshalJSON();};BL.ptr.prototype.UnmarshalJSON=function(i){var i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=this;if(($bytesToString(i))===\"null\"){$s=-1;return $ifaceNil;}k=$ifaceNil;m=AK(\"\\\"2006-01-02T15:04:05Z07:00\\\"\",($bytesToString(i)));$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;BL.copy(j,l[0]);k=l[1];$s=-1;return k;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.UnmarshalJSON};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.UnmarshalJSON=function(i){return this.$val.UnmarshalJSON(i);};BL.ptr.prototype.MarshalText=function(){var i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=$clone(i,BL).Year();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;if(k<0||k>=10000){$s=-1;return[DR.nil,C.New(\"Time.MarshalText: year outside of range [0,9999]\")];}l=$makeSlice(DR,0,35);m=$clone(i,BL).AppendFormat(l,\"2006-01-02T15:04:05.999999999Z07:00\");$s=2;case 2:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}$s=-1;return[m,$ifaceNil];}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.MarshalText};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.MarshalText=function(){return this.$val.MarshalText();};BL.ptr.prototype.UnmarshalText=function(i){var i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=this;k=$ifaceNil;m=AK(\"2006-01-02T15:04:05Z07:00\",($bytesToString(i)));$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;BL.copy(j,l[0]);k=l[1];$s=-1;return k;}return;}if($f===undefined){$f={$blk:BL.ptr.prototype.UnmarshalText};}$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};BL.prototype.UnmarshalText=function(i){return this.$val.UnmarshalText(i);};CE=function(i,j){var i,j,k,l,m,n,o;if((j.$high<0||(j.$high===0&&j.$low<0))||(j.$high>0||(j.$high===0&&j.$low>=1000000000))){k=$div64(j,new $Int64(0,1000000000),false);i=(l=k,new $Int64(i.$high+l.$high,i.$low+l.$low));j=(m=$mul64(k,new $Int64(0,1000000000)),new $Int64(j.$high-m.$high,j.$low-m.$low));if((j.$high<0||(j.$high===0&&j.$low<0))){j=(n=new $Int64(0,1000000000),new $Int64(j.$high+n.$high,j.$low+n.$low));i=(o=new $Int64(0,1),new $Int64(i.$high-o.$high,i.$low-o.$low));}}return CD(i,(((j.$low+((j.$high>>31)*4294967296))>>0)));};$pkg.Unix=CE;CF=function(i){var i,j,k,l;return((j=i%4,j===j?j:$throwRuntimeError(\"integer divide by zero\"))===0)&&(!(((k=i%100,k===k?k:$throwRuntimeError(\"integer divide by zero\"))===0))||((l=i%400,l===l?l:$throwRuntimeError(\"integer divide by zero\"))===0));};CG=function(i,j,k){var i,j,k,l,m,n,o,p,q,r,s;l=0;m=0;if(j<0){o=(n=((-j-1>>0))/k,(n===n&&n!==1/0&&n!==-1/0)?n>>0:$throwRuntimeError(\"integer divide by zero\"))+1>>0;i=i-(o)>>0;j=j+(($imul(o,k)))>>0;}if(j>=k){q=(p=j/k,(p===p&&p!==1/0&&p!==-1/0)?p>>0:$throwRuntimeError(\"integer divide by zero\"));i=i+(q)>>0;j=j-(($imul(q,k)))>>0;}r=i;s=j;l=r;m=s;return[l,m];};CH=function(i,j,k,l,m,n,o,p){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(p===DU.nil){$panic(new $String(\"time: missing Location in call to Date\"));}q=((j>>0))-1>>0;r=CG(i,q,12);i=r[0];q=r[1];j=((q>>0))+1>>0;s=CG(n,o,1000000000);n=s[0];o=s[1];t=CG(m,n,60);m=t[0];n=t[1];u=CG(l,m,60);l=u[0];m=u[1];v=CG(k,l,24);k=v[0];l=v[1];y=((w=(x=(new $Int64(0,i)),new $Int64(x.$high- -69,x.$low-4075721025)),new $Uint64(w.$high,w.$low)));z=$div64(y,new $Uint64(0,400),false);y=(aa=$mul64(new $Uint64(0,400),z),new $Uint64(y.$high-aa.$high,y.$low-aa.$low));ab=$mul64(new $Uint64(0,146097),z);z=$div64(y,new $Uint64(0,100),false);y=(ac=$mul64(new $Uint64(0,100),z),new $Uint64(y.$high-ac.$high,y.$low-ac.$low));ab=(ad=$mul64(new $Uint64(0,36524),z),new $Uint64(ab.$high+ad.$high,ab.$low+ad.$low));z=$div64(y,new $Uint64(0,4),false);y=(ae=$mul64(new $Uint64(0,4),z),new $Uint64(y.$high-ae.$high,y.$low-ae.$low));ab=(af=$mul64(new $Uint64(0,1461),z),new $Uint64(ab.$high+af.$high,ab.$low+af.$low));z=y;ab=(ag=$mul64(new $Uint64(0,365),z),new $Uint64(ab.$high+ag.$high,ab.$low+ag.$low));ab=(ah=(new $Uint64(0,(ai=j-1>>0,((ai<0||ai>=BZ.length)?($throwRuntimeError(\"index out of range\"),undefined):BZ[ai])))),new $Uint64(ab.$high+ah.$high,ab.$low+ah.$low));if(CF(i)&&j>=3){ab=(aj=new $Uint64(0,1),new $Uint64(ab.$high+aj.$high,ab.$low+aj.$low));}ab=(ak=(new $Uint64(0,(k-1>>0))),new $Uint64(ab.$high+ak.$high,ab.$low+ak.$low));al=$mul64(ab,new $Uint64(0,86400));al=(am=(new $Uint64(0,((($imul(l,3600))+($imul(m,60))>>0)+n>>0))),new $Uint64(al.$high+am.$high,al.$low+am.$low));ao=(an=(new $Int64(al.$high,al.$low)),new $Int64(an.$high+-2147483647,an.$low+3844486912));aq=p.lookup(ao);$s=1;case 1:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ap=aq;ar=ap[1];as=ap[2];at=ap[3];if(!((ar===0))){$s=2;continue;}$s=3;continue;case 2:av=(au=(new $Int64(0,ar)),new $Int64(ao.$high-au.$high,ao.$low-au.$low));if((av.$high<as.$high||(av.$high===as.$high&&av.$low<as.$low))){$s=5;continue;}if((av.$high>at.$high||(av.$high===at.$high&&av.$low>=at.$low))){$s=6;continue;}$s=7;continue;case 5:ax=p.lookup(new $Int64(as.$high-0,as.$low-1));$s=8;case 8:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}aw=ax;ar=aw[1];$s=7;continue;case 6:az=p.lookup(at);$s=9;case 9:if($c){$c=false;az=az.$blk();}if(az&&az.$blk!==undefined){break s;}ay=az;ar=ay[1];case 7:case 4:ao=(ba=(new $Int64(0,ar)),new $Int64(ao.$high-ba.$high,ao.$low-ba.$low));case 3:bb=$clone(CD(ao,((o>>0))),BL);bb.setLoc(p);$s=-1;return bb;}return;}if($f===undefined){$f={$blk:CH};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Date=CH;BL.ptr.prototype.Truncate=function(i){var i,j,k,l;j=this;j.stripMono();if((i.$high<0||(i.$high===0&&i.$low<=0))){return j;}k=CI($clone(j,BL),i);l=k[1];return $clone(j,BL).Add(new BS(-l.$high,-l.$low));};BL.prototype.Truncate=function(i){return this.$val.Truncate(i);};BL.ptr.prototype.Round=function(i){var i,j,k,l;j=this;j.stripMono();if((i.$high<0||(i.$high===0&&i.$low<=0))){return j;}k=CI($clone(j,BL),i);l=k[1];if(BV(l,i)){return $clone(j,BL).Add(new BS(-l.$high,-l.$low));}return $clone(j,BL).Add(new BS(i.$high-l.$high,i.$low-l.$low));};BL.prototype.Round=function(i){return this.$val.Round(i);};CI=function(i,j){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;k=0;l=new BS(0,0);m=false;n=i.nsec();o=i.sec();if((o.$high<0||(o.$high===0&&o.$low<0))){m=true;o=new $Int64(-o.$high,-o.$low);n=-n;if(n<0){n=n+(1000000000)>>0;o=(p=new $Int64(0,1),new $Int64(o.$high-p.$high,o.$low-p.$low));}}if((j.$high<0||(j.$high===0&&j.$low<1000000000))&&(q=$div64(new BS(0,1000000000),(new BS(j.$high+j.$high,j.$low+j.$low)),true),(q.$high===0&&q.$low===0))){k=(((s=n/(((j.$low+((j.$high>>31)*4294967296))>>0)),(s===s&&s!==1/0&&s!==-1/0)?s>>0:$throwRuntimeError(\"integer divide by zero\"))>>0))&1;l=(new BS(0,(t=n%(((j.$low+((j.$high>>31)*4294967296))>>0)),t===t?t:$throwRuntimeError(\"integer divide by zero\"))));}else if((r=$div64(j,new BS(0,1000000000),true),(r.$high===0&&r.$low===0))){v=((u=$div64(j,new BS(0,1000000000),false),new $Int64(u.$high,u.$low)));k=(((w=$div64(o,v,false),w.$low+((w.$high>>31)*4294967296))>>0))&1;l=(x=$mul64(((y=$div64(o,v,true),new BS(y.$high,y.$low))),new BS(0,1000000000)),z=(new BS(0,n)),new BS(x.$high+z.$high,x.$low+z.$low));}else{aa=(new $Uint64(o.$high,o.$low));ab=$mul64(($shiftRightUint64(aa,32)),new $Uint64(0,1000000000));ac=$shiftRightUint64(ab,32);ad=$shiftLeft64(ab,32);ab=$mul64((new $Uint64(aa.$high&0,(aa.$low&4294967295)>>>0)),new $Uint64(0,1000000000));ae=ad;af=new $Uint64(ad.$high+ab.$high,ad.$low+ab.$low);ag=ae;ad=af;if((ad.$high<ag.$high||(ad.$high===ag.$high&&ad.$low<ag.$low))){ac=(ah=new $Uint64(0,1),new $Uint64(ac.$high+ah.$high,ac.$low+ah.$low));}ai=ad;aj=(ak=(new $Uint64(0,n)),new $Uint64(ad.$high+ak.$high,ad.$low+ak.$low));ag=ai;ad=aj;if((ad.$high<ag.$high||(ad.$high===ag.$high&&ad.$low<ag.$low))){ac=(al=new $Uint64(0,1),new $Uint64(ac.$high+al.$high,ac.$low+al.$low));}am=(new $Uint64(j.$high,j.$low));while(true){if(!(!((an=$shiftRightUint64(am,63),(an.$high===0&&an.$low===1))))){break;}am=$shiftLeft64(am,(1));}ao=new $Uint64(0,0);while(true){k=0;if((ac.$high>am.$high||(ac.$high===am.$high&&ac.$low>am.$low))||(ac.$high===am.$high&&ac.$low===am.$low)&&(ad.$high>ao.$high||(ad.$high===ao.$high&&ad.$low>=ao.$low))){k=1;ap=ad;aq=new $Uint64(ad.$high-ao.$high,ad.$low-ao.$low);ag=ap;ad=aq;if((ad.$high>ag.$high||(ad.$high===ag.$high&&ad.$low>ag.$low))){ac=(ar=new $Uint64(0,1),new $Uint64(ac.$high-ar.$high,ac.$low-ar.$low));}ac=(as=am,new $Uint64(ac.$high-as.$high,ac.$low-as.$low));}if((am.$high===0&&am.$low===0)&&(at=(new $Uint64(j.$high,j.$low)),(ao.$high===at.$high&&ao.$low===at.$low))){break;}ao=$shiftRightUint64(ao,(1));ao=(au=$shiftLeft64((new $Uint64(am.$high&0,(am.$low&1)>>>0)),63),new $Uint64(ao.$high|au.$high,(ao.$low|au.$low)>>>0));am=$shiftRightUint64(am,(1));}l=(new BS(ad.$high,ad.$low));}if(m&&!((l.$high===0&&l.$low===0))){k=(k^(1))>>0;l=new BS(j.$high-l.$high,j.$low-l.$low);}return[k,l];};CJ.ptr.prototype.get=function(){var i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;if(i===DU.nil){$s=-1;return CM;}if(i===CN){$s=1;continue;}$s=2;continue;case 1:$r=CO.Do(H);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$s=-1;return i;}return;}if($f===undefined){$f={$blk:CJ.ptr.prototype.get};}$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};CJ.prototype.get=function(){return this.$val.get();};CJ.ptr.prototype.String=function(){var i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:i=this;j=i.get();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}$s=-1;return j.name;}return;}if($f===undefined){$f={$blk:CJ.ptr.prototype.String};}$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};CJ.prototype.String=function(){return this.$val.String();};CP=function(i,j){var i,j,k,l;k=new CJ.ptr(i,new DK([new CK.ptr(i,j,false)]),new DL([new CL.ptr(new $Int64(-2147483648,0),0,false,false)]),new $Int64(-2147483648,0),new $Int64(2147483647,4294967295),DM.nil);k.cacheZone=(l=k.zone,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0]));return k;};$pkg.FixedZone=CP;CJ.ptr.prototype.lookup=function(i){var aa,ab,ac,ad,ae,af,ag,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:j=\"\";k=0;l=new $Int64(0,0);m=new $Int64(0,0);n=this;o=n.get();$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;if(n.zone.$length===0){j=\"UTC\";k=0;l=new $Int64(-2147483648,0);m=new $Int64(2147483647,4294967295);$s=-1;return[j,k,l,m];}p=n.cacheZone;if(!(p===DM.nil)&&(q=n.cacheStart,(q.$high<i.$high||(q.$high===i.$high&&q.$low<=i.$low)))&&(r=n.cacheEnd,(i.$high<r.$high||(i.$high===r.$high&&i.$low<r.$low)))){j=p.name;k=p.offset;l=n.cacheStart;m=n.cacheEnd;$s=-1;return[j,k,l,m];}if((n.tx.$length===0)||(s=(t=n.tx,(0>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+0])).when,(i.$high<s.$high||(i.$high===s.$high&&i.$low<s.$low)))){w=(u=n.zone,v=n.lookupFirstZone(),((v<0||v>=u.$length)?($throwRuntimeError(\"index out of range\"),undefined):u.$array[u.$offset+v]));j=w.name;k=w.offset;l=new $Int64(-2147483648,0);if(n.tx.$length>0){m=(x=n.tx,(0>=x.$length?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+0])).when;}else{m=new $Int64(2147483647,4294967295);}$s=-1;return[j,k,l,m];}y=n.tx;m=new $Int64(2147483647,4294967295);z=0;aa=y.$length;while(true){if(!((aa-z>>0)>1)){break;}ac=z+(ab=((aa-z>>0))/2,(ab===ab&&ab!==1/0&&ab!==-1/0)?ab>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;ad=((ac<0||ac>=y.$length)?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+ac]).when;if((i.$high<ad.$high||(i.$high===ad.$high&&i.$low<ad.$low))){m=ad;aa=ac;}else{z=ac;}}ag=(ae=n.zone,af=((z<0||z>=y.$length)?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+z]).index,((af<0||af>=ae.$length)?($throwRuntimeError(\"index out of range\"),undefined):ae.$array[ae.$offset+af]));j=ag.name;k=ag.offset;l=((z<0||z>=y.$length)?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+z]).when;$s=-1;return[j,k,l,m];}return;}if($f===undefined){$f={$blk:CJ.ptr.prototype.lookup};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};CJ.prototype.lookup=function(i){return this.$val.lookup(i);};CJ.ptr.prototype.lookupFirstZone=function(){var i,j,k,l,m,n,o,p,q,r,s;i=this;if(!i.firstZoneUsed()){return 0;}if(i.tx.$length>0&&(j=i.zone,k=(l=i.tx,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])).index,((k<0||k>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+k])).isDST){n=(((m=i.tx,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0])).index>>0))-1>>0;while(true){if(!(n>=0)){break;}if(!(o=i.zone,((n<0||n>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+n])).isDST){return n;}n=n-(1)>>0;}}p=i.zone;q=0;while(true){if(!(q<p.$length)){break;}r=q;if(!(s=i.zone,((r<0||r>=s.$length)?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+r])).isDST){return r;}q++;}return 0;};CJ.prototype.lookupFirstZone=function(){return this.$val.lookupFirstZone();};CJ.ptr.prototype.firstZoneUsed=function(){var i,j,k,l;i=this;j=i.tx;k=0;while(true){if(!(k<j.$length)){break;}l=$clone(((k<0||k>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+k]),CL);if(l.index===0){return true;}k++;}return false;};CJ.prototype.firstZoneUsed=function(){return this.$val.firstZoneUsed();};CJ.ptr.prototype.lookupName=function(i,j){var aa,ab,ac,ad,ae,af,ag,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:k=0;l=false;m=this;n=m.get();$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m.zone;p=0;case 2:if(!(p<o.$length)){$s=3;continue;}q=p;s=(r=m.zone,((q<0||q>=r.$length)?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+q]));if(s.name===i){$s=4;continue;}$s=5;continue;case 4:v=m.lookup((u=(new $Int64(0,s.offset)),new $Int64(j.$high-u.$high,j.$low-u.$low)));$s=6;case 6:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}t=v;w=t[0];x=t[1];if(w===s.name){y=x;z=true;k=y;l=z;$s=-1;return[k,l];}case 5:p++;$s=2;continue;case 3:aa=m.zone;ab=0;while(true){if(!(ab<aa.$length)){break;}ac=ab;ae=(ad=m.zone,((ac<0||ac>=ad.$length)?($throwRuntimeError(\"index out of range\"),undefined):ad.$array[ad.$offset+ac]));if(ae.name===i){af=ae.offset;ag=true;k=af;l=ag;$s=-1;return[k,l];}ab++;}$s=-1;return[k,l];}return;}if($f===undefined){$f={$blk:CJ.ptr.prototype.lookupName};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};CJ.prototype.lookupName=function(i,j){return this.$val.lookupName(i,j);};EC.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];ED.methods=[{prop:\"Stop\",name:\"Stop\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Reset\",name:\"Reset\",pkg:\"\",typ:$funcType([BS],[$Bool],false)}];EF.methods=[{prop:\"Stop\",name:\"Stop\",pkg:\"\",typ:$funcType([],[],false)}];BL.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Format\",name:\"Format\",pkg:\"\",typ:$funcType([$String],[$String],false)},{prop:\"AppendFormat\",name:\"AppendFormat\",pkg:\"\",typ:$funcType([DR,$String],[DR],false)},{prop:\"After\",name:\"After\",pkg:\"\",typ:$funcType([BL],[$Bool],false)},{prop:\"Before\",name:\"Before\",pkg:\"\",typ:$funcType([BL],[$Bool],false)},{prop:\"Equal\",name:\"Equal\",pkg:\"\",typ:$funcType([BL],[$Bool],false)},{prop:\"IsZero\",name:\"IsZero\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"abs\",name:\"abs\",pkg:\"time\",typ:$funcType([],[$Uint64],false)},{prop:\"locabs\",name:\"locabs\",pkg:\"time\",typ:$funcType([],[$String,$Int,$Uint64],false)},{prop:\"Date\",name:\"Date\",pkg:\"\",typ:$funcType([],[$Int,BM,$Int],false)},{prop:\"Year\",name:\"Year\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Month\",name:\"Month\",pkg:\"\",typ:$funcType([],[BM],false)},{prop:\"Day\",name:\"Day\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Weekday\",name:\"Weekday\",pkg:\"\",typ:$funcType([],[BO],false)},{prop:\"ISOWeek\",name:\"ISOWeek\",pkg:\"\",typ:$funcType([],[$Int,$Int],false)},{prop:\"Clock\",name:\"Clock\",pkg:\"\",typ:$funcType([],[$Int,$Int,$Int],false)},{prop:\"Hour\",name:\"Hour\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Minute\",name:\"Minute\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Second\",name:\"Second\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Nanosecond\",name:\"Nanosecond\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"YearDay\",name:\"YearDay\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Add\",name:\"Add\",pkg:\"\",typ:$funcType([BS],[BL],false)},{prop:\"Sub\",name:\"Sub\",pkg:\"\",typ:$funcType([BL],[BS],false)},{prop:\"AddDate\",name:\"AddDate\",pkg:\"\",typ:$funcType([$Int,$Int,$Int],[BL],false)},{prop:\"date\",name:\"date\",pkg:\"time\",typ:$funcType([$Bool],[$Int,BM,$Int,$Int],false)},{prop:\"UTC\",name:\"UTC\",pkg:\"\",typ:$funcType([],[BL],false)},{prop:\"Local\",name:\"Local\",pkg:\"\",typ:$funcType([],[BL],false)},{prop:\"In\",name:\"In\",pkg:\"\",typ:$funcType([DU],[BL],false)},{prop:\"Location\",name:\"Location\",pkg:\"\",typ:$funcType([],[DU],false)},{prop:\"Zone\",name:\"Zone\",pkg:\"\",typ:$funcType([],[$String,$Int],false)},{prop:\"Unix\",name:\"Unix\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"UnixNano\",name:\"UnixNano\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"MarshalBinary\",name:\"MarshalBinary\",pkg:\"\",typ:$funcType([],[DR,$error],false)},{prop:\"GobEncode\",name:\"GobEncode\",pkg:\"\",typ:$funcType([],[DR,$error],false)},{prop:\"MarshalJSON\",name:\"MarshalJSON\",pkg:\"\",typ:$funcType([],[DR,$error],false)},{prop:\"MarshalText\",name:\"MarshalText\",pkg:\"\",typ:$funcType([],[DR,$error],false)},{prop:\"Truncate\",name:\"Truncate\",pkg:\"\",typ:$funcType([BS],[BL],false)},{prop:\"Round\",name:\"Round\",pkg:\"\",typ:$funcType([BS],[BL],false)}];EG.methods=[{prop:\"nsec\",name:\"nsec\",pkg:\"time\",typ:$funcType([],[$Int32],false)},{prop:\"sec\",name:\"sec\",pkg:\"time\",typ:$funcType([],[$Int64],false)},{prop:\"unixSec\",name:\"unixSec\",pkg:\"time\",typ:$funcType([],[$Int64],false)},{prop:\"addSec\",name:\"addSec\",pkg:\"time\",typ:$funcType([$Int64],[],false)},{prop:\"setLoc\",name:\"setLoc\",pkg:\"time\",typ:$funcType([DU],[],false)},{prop:\"stripMono\",name:\"stripMono\",pkg:\"time\",typ:$funcType([],[],false)},{prop:\"setMono\",name:\"setMono\",pkg:\"time\",typ:$funcType([$Int64],[],false)},{prop:\"mono\",name:\"mono\",pkg:\"time\",typ:$funcType([],[$Int64],false)},{prop:\"UnmarshalBinary\",name:\"UnmarshalBinary\",pkg:\"\",typ:$funcType([DR],[$error],false)},{prop:\"GobDecode\",name:\"GobDecode\",pkg:\"\",typ:$funcType([DR],[$error],false)},{prop:\"UnmarshalJSON\",name:\"UnmarshalJSON\",pkg:\"\",typ:$funcType([DR],[$error],false)},{prop:\"UnmarshalText\",name:\"UnmarshalText\",pkg:\"\",typ:$funcType([DR],[$error],false)}];BM.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];BO.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];BS.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Nanoseconds\",name:\"Nanoseconds\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Seconds\",name:\"Seconds\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Minutes\",name:\"Minutes\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Hours\",name:\"Hours\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Truncate\",name:\"Truncate\",pkg:\"\",typ:$funcType([BS],[BS],false)},{prop:\"Round\",name:\"Round\",pkg:\"\",typ:$funcType([BS],[BS],false)}];DU.methods=[{prop:\"get\",name:\"get\",pkg:\"time\",typ:$funcType([],[DU],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"lookup\",name:\"lookup\",pkg:\"time\",typ:$funcType([$Int64],[$String,$Int,$Int64,$Int64],false)},{prop:\"lookupFirstZone\",name:\"lookupFirstZone\",pkg:\"time\",typ:$funcType([],[$Int],false)},{prop:\"firstZoneUsed\",name:\"firstZoneUsed\",pkg:\"time\",typ:$funcType([],[$Bool],false)},{prop:\"lookupName\",name:\"lookupName\",pkg:\"time\",typ:$funcType([$String,$Int64],[$Int,$Bool],false)}];G.init(\"time\",[{prop:\"i\",name:\"i\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"when\",name:\"when\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"period\",name:\"period\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"f\",name:\"f\",embedded:false,exported:false,typ:EA,tag:\"\"},{prop:\"arg\",name:\"arg\",embedded:false,exported:false,typ:$emptyInterface,tag:\"\"},{prop:\"timeout\",name:\"timeout\",embedded:false,exported:false,typ:EB,tag:\"\"},{prop:\"active\",name:\"active\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);AE.init(\"\",[{prop:\"Layout\",name:\"Layout\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Value\",name:\"Value\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"LayoutElem\",name:\"LayoutElem\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"ValueElem\",name:\"ValueElem\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Message\",name:\"Message\",embedded:false,exported:true,typ:$String,tag:\"\"}]);AX.init(\"time\",[{prop:\"C\",name:\"C\",embedded:false,exported:true,typ:EE,tag:\"\"},{prop:\"r\",name:\"r\",embedded:false,exported:false,typ:G,tag:\"\"}]);BI.init(\"time\",[{prop:\"C\",name:\"C\",embedded:false,exported:true,typ:EE,tag:\"\"},{prop:\"r\",name:\"r\",embedded:false,exported:false,typ:G,tag:\"\"}]);BL.init(\"time\",[{prop:\"wall\",name:\"wall\",embedded:false,exported:false,typ:$Uint64,tag:\"\"},{prop:\"ext\",name:\"ext\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"loc\",name:\"loc\",embedded:false,exported:false,typ:DU,tag:\"\"}]);CJ.init(\"time\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"zone\",name:\"zone\",embedded:false,exported:false,typ:DK,tag:\"\"},{prop:\"tx\",name:\"tx\",embedded:false,exported:false,typ:DL,tag:\"\"},{prop:\"cacheStart\",name:\"cacheStart\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"cacheEnd\",name:\"cacheEnd\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"cacheZone\",name:\"cacheZone\",embedded:false,exported:false,typ:DM,tag:\"\"}]);CK.init(\"time\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"offset\",name:\"offset\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"isDST\",name:\"isDST\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);CL.init(\"time\",[{prop:\"when\",name:\"when\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"index\",name:\"index\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"isstd\",name:\"isstd\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"isutc\",name:\"isutc\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=C.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}CN=new CJ.ptr(\"\",DK.nil,DL.nil,new $Int64(0,0),new $Int64(0,0),DM.nil);CO=new E.Once.ptr(false,false);O=new DO([A.GOROOT()+\"/lib/time/zoneinfo.zip\"]);Q=$toNativeArray($kindInt,[260,265,524,526,528,274]);T=new DO([\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);U=new DO([\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"]);V=new DO([\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]);W=new DO([\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"]);AA=C.New(\"time: invalid number\");AD=C.New(\"bad value for field\");AR=C.New(\"time: bad [0-9]*\");BN=$toNativeArray($kindString,[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"]);BP=$toNativeArray($kindString,[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"]);BZ=$toNativeArray($kindInt32,[0,31,59,90,120,151,181,212,243,273,304,334,365]);CB=(h=I(),new $Int64(h.$high-0,h.$low-1));CM=new CJ.ptr(\"UTC\",DK.nil,DL.nil,new $Int64(0,0),new $Int64(0,0),DM.nil);$pkg.UTC=CM;$pkg.Local=CN;CQ=C.New(\"time: invalid location name\");CY=C.New(\"malformed time zone information\");$unused(new DO([\"/usr/share/zoneinfo/\",\"/usr/share/lib/zoneinfo/\",\"/usr/lib/locale/TZ/\",A.GOROOT()+\"/lib/time/zoneinfo.zip\"]));F();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/poll\"]=(function(){var $pkg={},$init,B,E,F,D,C,A,G,M,P,Q,AG,AH,AI,AJ,AK,AM,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,K,R,AE,I,J,L,N,O,S,T,U,W;B=$packages[\"errors\"];E=$packages[\"io\"];F=$packages[\"runtime\"];D=$packages[\"sync/atomic\"];C=$packages[\"syscall\"];A=$packages[\"time\"];G=$pkg.pollDesc=$newType(0,$kindStruct,\"poll.pollDesc\",true,\"internal/poll\",false,function(closing_){this.$val=this;if(arguments.length===0){this.closing=false;return;}this.closing=closing_;});M=$pkg.TimeoutError=$newType(0,$kindStruct,\"poll.TimeoutError\",true,\"internal/poll\",true,function(){this.$val=this;if(arguments.length===0){return;}});P=$pkg.fdMutex=$newType(0,$kindStruct,\"poll.fdMutex\",true,\"internal/poll\",false,function(state_,rsema_,wsema_){this.$val=this;if(arguments.length===0){this.state=new $Uint64(0,0);this.rsema=0;this.wsema=0;return;}this.state=state_;this.rsema=rsema_;this.wsema=wsema_;});Q=$pkg.FD=$newType(0,$kindStruct,\"poll.FD\",true,\"internal/poll\",true,function(fdmu_,Sysfd_,pd_,iovecs_,csema_,isBlocking_,IsStream_,ZeroReadIsEOF_,isFile_){this.$val=this;if(arguments.length===0){this.fdmu=new P.ptr(new $Uint64(0,0),0,0);this.Sysfd=0;this.pd=new G.ptr(false);this.iovecs=AS.nil;this.csema=0;this.isBlocking=0;this.IsStream=false;this.ZeroReadIsEOF=false;this.isFile=false;return;}this.fdmu=fdmu_;this.Sysfd=Sysfd_;this.pd=pd_;this.iovecs=iovecs_;this.csema=csema_;this.isBlocking=isBlocking_;this.IsStream=IsStream_;this.ZeroReadIsEOF=ZeroReadIsEOF_;this.isFile=isFile_;});AG=$ptrType($Uint32);AH=$chanType($Bool,false,false);AI=$sliceType(AH);AJ=$ptrType($Uint64);AK=$ptrType($Int32);AM=$arrayType($Uint8,4);AR=$sliceType(C.Iovec);AS=$ptrType(AR);AT=$ptrType($Uint8);AU=$ptrType(Q);AV=$ptrType(G);AW=$ptrType(M);AX=$ptrType(P);AY=$sliceType($Uint8);AZ=$ptrType(C.Stat_t);BA=$funcType([$Uintptr],[],false);BB=$funcType([$Uintptr],[$Bool],false);BC=$ptrType(C.Linger);BD=$ptrType(C.IPMreqn);BE=$ptrType(C.IPMreq);BF=$ptrType(C.IPv6Mreq);BG=$sliceType(AY);BH=$ptrType(BG);G.ptr.prototype.init=function(c){var c,d;d=this;return $ifaceNil;};G.prototype.init=function(c){return this.$val.init(c);};G.ptr.prototype.close=function(){var c;c=this;};G.prototype.close=function(){return this.$val.close();};G.ptr.prototype.evict=function(){var c;c=this;c.closing=true;};G.prototype.evict=function(){return this.$val.evict();};G.ptr.prototype.prepare=function(c,d){var c,d,e;e=this;if(e.closing){return L(d);}return $ifaceNil;};G.prototype.prepare=function(c,d){return this.$val.prepare(c,d);};G.ptr.prototype.prepareRead=function(c){var c,d;d=this;return d.prepare(114,c);};G.prototype.prepareRead=function(c){return this.$val.prepareRead(c);};G.ptr.prototype.prepareWrite=function(c){var c,d;d=this;return d.prepare(119,c);};G.prototype.prepareWrite=function(c){return this.$val.prepareWrite(c);};G.ptr.prototype.wait=function(c,d){var c,d,e;e=this;if(e.closing){return L(d);}return $pkg.ErrTimeout;};G.prototype.wait=function(c,d){return this.$val.wait(c,d);};G.ptr.prototype.waitRead=function(c){var c,d;d=this;return d.wait(114,c);};G.prototype.waitRead=function(c){return this.$val.waitRead(c);};G.ptr.prototype.waitWrite=function(c){var c,d;d=this;return d.wait(119,c);};G.prototype.waitWrite=function(c){return this.$val.waitWrite(c);};G.ptr.prototype.pollable=function(){return true;};G.prototype.pollable=function(){return this.$val.pollable();};Q.ptr.prototype.SetDeadline=function(c){var c;return $ifaceNil;};Q.prototype.SetDeadline=function(c){return this.$val.SetDeadline(c);};Q.ptr.prototype.SetReadDeadline=function(c){var c;return $ifaceNil;};Q.prototype.SetReadDeadline=function(c){return this.$val.SetReadDeadline(c);};Q.ptr.prototype.SetWriteDeadline=function(c){var c;return $ifaceNil;};Q.prototype.SetWriteDeadline=function(c){return this.$val.SetWriteDeadline(c);};I=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(c.$get()===0){$s=1;continue;}$s=2;continue;case 1:d=new $Chan($Bool,0);e=c;(K||$throwRuntimeError(\"assignment to entry in nil map\"))[AG.keyFor(e)]={k:e,v:$append((f=K[AG.keyFor(c)],f!==undefined?f.v:AI.nil),d)};g=$recv(d);$s=3;case 3:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}g[0];case 2:c.$set(c.$get()-(1)>>>0);$s=-1;return;}return;}if($f===undefined){$f={$blk:I};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};J=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c.$set(c.$get()+(1)>>>0);e=(d=K[AG.keyFor(c)],d!==undefined?d.v:AI.nil);if(e.$length===0){$s=-1;return;}f=(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]);e=$subslice(e,1);g=c;(K||$throwRuntimeError(\"assignment to entry in nil map\"))[AG.keyFor(g)]={k:g,v:e};if(e.$length===0){delete K[AG.keyFor(c)];}$r=$send(f,true);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:J};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};L=function(c){var c;if(c){return $pkg.ErrFileClosing;}return $pkg.ErrNetClosing;};M.ptr.prototype.Error=function(){var c;c=this;return\"i/o timeout\";};M.prototype.Error=function(){return this.$val.Error();};M.ptr.prototype.Timeout=function(){var c;c=this;return true;};M.prototype.Timeout=function(){return this.$val.Timeout();};M.ptr.prototype.Temporary=function(){var c;c=this;return true;};M.prototype.Temporary=function(){return this.$val.Temporary();};N=function(c,d){var c,d,e,f,g,h,i;while(true){if(!(c.$get().$length>0)){break;}f=(new $Int64(0,(e=c.$get(),(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0])).$length));if((f.$high>d.$high||(f.$high===d.$high&&f.$low>d.$low))){(h=c.$get(),(0>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+0]=$subslice((g=c.$get(),(0>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+0])),$flatten64(d))));return;}d=(i=f,new $Int64(d.$high-i.$high,d.$low-i.$low));c.$set($subslice((c.$get()),1));}};Q.ptr.prototype.Fsync=function(){var c,d,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=this;d=c.incref();if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return d;}$deferred.push([$methodVal(c,\"decref\"),[]]);$s=-1;return C.Fsync(c.Sysfd);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Fsync};}$f.c=c;$f.d=d;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Fsync=function(){return this.$val.Fsync();};O=function(c,d,e){var c,d,e,f,g,h;f=C.Syscall(72,((c>>>0)),((d>>>0)),((e>>>0)));g=f[0];h=f[2];if(!((h===0))){return[((g>>0)),new C.Errno((h))];}return[((g>>0)),$ifaceNil];};P.ptr.prototype.incref=function(){var c,d,e,f,g;c=this;while(true){d=D.LoadUint64((c.$ptr_state||(c.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},c))));if(!((e=new $Uint64(d.$high&0,(d.$low&1)>>>0),(e.$high===0&&e.$low===0)))){return false;}f=new $Uint64(d.$high+0,d.$low+8);if((g=new $Uint64(f.$high&0,(f.$low&8388600)>>>0),(g.$high===0&&g.$low===0))){$panic(new $String(\"too many concurrent operations on a single file or socket (max 1048575)\"));}if(D.CompareAndSwapUint64((c.$ptr_state||(c.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},c))),d,f)){return true;}}};P.prototype.incref=function(){return this.$val.incref();};P.ptr.prototype.increfAndClose=function(){var c,d,e,f,g,h,i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;case 1:d=D.LoadUint64((c.$ptr_state||(c.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},c))));if(!((e=new $Uint64(d.$high&0,(d.$low&1)>>>0),(e.$high===0&&e.$low===0)))){$s=-1;return false;}g=(f=new $Uint64(d.$high|0,(d.$low|1)>>>0),new $Uint64(f.$high+0,f.$low+8));if((h=new $Uint64(g.$high&0,(g.$low&8388600)>>>0),(h.$high===0&&h.$low===0))){$panic(new $String(\"too many concurrent operations on a single file or socket (max 1048575)\"));}g=(i=new $Uint64(2147483647,4286578688),new $Uint64(g.$high&~i.$high,(g.$low&~i.$low)>>>0));if(D.CompareAndSwapUint64((c.$ptr_state||(c.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},c))),d,g)){$s=3;continue;}$s=4;continue;case 3:case 5:if(!(!((j=new $Uint64(d.$high&2047,(d.$low&4286578688)>>>0),(j.$high===0&&j.$low===0))))){$s=6;continue;}d=(k=new $Uint64(0,8388608),new $Uint64(d.$high-k.$high,d.$low-k.$low));$r=J((c.$ptr_rsema||(c.$ptr_rsema=new AG(function(){return this.$target.rsema;},function($v){this.$target.rsema=$v;},c))));$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=5;continue;case 6:case 8:if(!(!((l=new $Uint64(d.$high&2147481600,(d.$low&0)>>>0),(l.$high===0&&l.$low===0))))){$s=9;continue;}d=(m=new $Uint64(2048,0),new $Uint64(d.$high-m.$high,d.$low-m.$low));$r=J((c.$ptr_wsema||(c.$ptr_wsema=new AG(function(){return this.$target.wsema;},function($v){this.$target.wsema=$v;},c))));$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=8;continue;case 9:$s=-1;return true;case 4:$s=1;continue;case 2:$s=-1;return false;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.increfAndClose};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.increfAndClose=function(){return this.$val.increfAndClose();};P.ptr.prototype.decref=function(){var c,d,e,f,g;c=this;while(true){d=D.LoadUint64((c.$ptr_state||(c.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},c))));if((e=new $Uint64(d.$high&0,(d.$low&8388600)>>>0),(e.$high===0&&e.$low===0))){$panic(new $String(\"inconsistent poll.fdMutex\"));}f=new $Uint64(d.$high-0,d.$low-8);if(D.CompareAndSwapUint64((c.$ptr_state||(c.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},c))),d,f)){return(g=new $Uint64(f.$high&0,(f.$low&8388601)>>>0),(g.$high===0&&g.$low===1));}}};P.prototype.decref=function(){return this.$val.decref();};P.ptr.prototype.rwlock=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=new $Uint64(0,0);f=new $Uint64(0,0);g=new $Uint64(0,0);h=e;i=f;j=g;k=AG.nil;if(c){h=new $Uint64(0,2);i=new $Uint64(0,8388608);j=new $Uint64(2047,4286578688);k=(d.$ptr_rsema||(d.$ptr_rsema=new AG(function(){return this.$target.rsema;},function($v){this.$target.rsema=$v;},d)));}else{h=new $Uint64(0,4);i=new $Uint64(2048,0);j=new $Uint64(2147481600,0);k=(d.$ptr_wsema||(d.$ptr_wsema=new AG(function(){return this.$target.wsema;},function($v){this.$target.wsema=$v;},d)));}case 1:l=D.LoadUint64((d.$ptr_state||(d.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},d))));if(!((m=new $Uint64(l.$high&0,(l.$low&1)>>>0),(m.$high===0&&m.$low===0)))){$s=-1;return false;}n=new $Uint64(0,0);if((o=new $Uint64(l.$high&h.$high,(l.$low&h.$low)>>>0),(o.$high===0&&o.$low===0))){n=(p=new $Uint64(l.$high|h.$high,(l.$low|h.$low)>>>0),new $Uint64(p.$high+0,p.$low+8));if((q=new $Uint64(n.$high&0,(n.$low&8388600)>>>0),(q.$high===0&&q.$low===0))){$panic(new $String(\"too many concurrent operations on a single file or socket (max 1048575)\"));}}else{n=new $Uint64(l.$high+i.$high,l.$low+i.$low);if((r=new $Uint64(n.$high&j.$high,(n.$low&j.$low)>>>0),(r.$high===0&&r.$low===0))){$panic(new $String(\"too many concurrent operations on a single file or socket (max 1048575)\"));}}if(D.CompareAndSwapUint64((d.$ptr_state||(d.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},d))),l,n)){$s=3;continue;}$s=4;continue;case 3:if((s=new $Uint64(l.$high&h.$high,(l.$low&h.$low)>>>0),(s.$high===0&&s.$low===0))){$s=-1;return true;}$r=I(k);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 4:$s=1;continue;case 2:$s=-1;return false;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.rwlock};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.rwlock=function(c){return this.$val.rwlock(c);};P.ptr.prototype.rwunlock=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=new $Uint64(0,0);f=new $Uint64(0,0);g=new $Uint64(0,0);h=e;i=f;j=g;k=AG.nil;if(c){h=new $Uint64(0,2);i=new $Uint64(0,8388608);j=new $Uint64(2047,4286578688);k=(d.$ptr_rsema||(d.$ptr_rsema=new AG(function(){return this.$target.rsema;},function($v){this.$target.rsema=$v;},d)));}else{h=new $Uint64(0,4);i=new $Uint64(2048,0);j=new $Uint64(2147481600,0);k=(d.$ptr_wsema||(d.$ptr_wsema=new AG(function(){return this.$target.wsema;},function($v){this.$target.wsema=$v;},d)));}case 1:l=D.LoadUint64((d.$ptr_state||(d.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},d))));if((m=new $Uint64(l.$high&h.$high,(l.$low&h.$low)>>>0),(m.$high===0&&m.$low===0))||(n=new $Uint64(l.$high&0,(l.$low&8388600)>>>0),(n.$high===0&&n.$low===0))){$panic(new $String(\"inconsistent poll.fdMutex\"));}p=(o=new $Uint64(l.$high&~h.$high,(l.$low&~h.$low)>>>0),new $Uint64(o.$high-0,o.$low-8));if(!((q=new $Uint64(l.$high&j.$high,(l.$low&j.$low)>>>0),(q.$high===0&&q.$low===0)))){p=(r=i,new $Uint64(p.$high-r.$high,p.$low-r.$low));}if(D.CompareAndSwapUint64((d.$ptr_state||(d.$ptr_state=new AJ(function(){return this.$target.state;},function($v){this.$target.state=$v;},d))),l,p)){$s=3;continue;}$s=4;continue;case 3:if(!((s=new $Uint64(l.$high&j.$high,(l.$low&j.$low)>>>0),(s.$high===0&&s.$low===0)))){$s=5;continue;}$s=6;continue;case 5:$r=J(k);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 6:$s=-1;return(t=new $Uint64(p.$high&0,(p.$low&8388601)>>>0),(t.$high===0&&t.$low===1));case 4:$s=1;continue;case 2:$s=-1;return false;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.rwunlock};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.rwunlock=function(c){return this.$val.rwunlock(c);};Q.ptr.prototype.incref=function(){var c;c=this;if(!c.fdmu.incref()){return L(c.isFile);}return $ifaceNil;};Q.prototype.incref=function(){return this.$val.incref();};Q.ptr.prototype.decref=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(c.fdmu.decref()){$s=1;continue;}$s=2;continue;case 1:d=c.destroy();$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.decref};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.decref=function(){return this.$val.decref();};Q.ptr.prototype.readLock=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.fdmu.rwlock(true);$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}if(!d){$s=1;continue;}$s=2;continue;case 1:$s=-1;return L(c.isFile);case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.readLock};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.readLock=function(){return this.$val.readLock();};Q.ptr.prototype.readUnlock=function(){var c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.fdmu.rwunlock(true);$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}if(d){$s=1;continue;}$s=2;continue;case 1:e=c.destroy();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.readUnlock};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.readUnlock=function(){return this.$val.readUnlock();};Q.ptr.prototype.writeLock=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.fdmu.rwlock(false);$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}if(!d){$s=1;continue;}$s=2;continue;case 1:$s=-1;return L(c.isFile);case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.writeLock};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.writeLock=function(){return this.$val.writeLock();};Q.ptr.prototype.writeUnlock=function(){var c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.fdmu.rwunlock(false);$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}if(d){$s=1;continue;}$s=2;continue;case 1:e=c.destroy();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.writeUnlock};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.writeUnlock=function(){return this.$val.writeUnlock();};Q.ptr.prototype.eofError=function(c,d){var c,d,e;e=this;if((c===0)&&$interfaceIsEqual(d,$ifaceNil)&&e.ZeroReadIsEOF){return E.EOF;}return d;};Q.prototype.eofError=function(c,d){return this.$val.eofError(c,d);};Q.ptr.prototype.Fchmod=function(c){var c,d,e,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.incref();if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}$deferred.push([$methodVal(d,\"decref\"),[]]);$s=-1;return C.Fchmod(d.Sysfd,c);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Fchmod};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Fchmod=function(c){return this.$val.Fchmod(c);};Q.ptr.prototype.Fchown=function(c,d){var c,d,e,f,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);e=this;f=e.incref();if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return f;}$deferred.push([$methodVal(e,\"decref\"),[]]);$s=-1;return C.Fchown(e.Sysfd,c,d);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Fchown};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Fchown=function(c,d){return this.$val.Fchown(c,d);};Q.ptr.prototype.Ftruncate=function(c){var c,d,e,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.incref();if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}$deferred.push([$methodVal(d,\"decref\"),[]]);$s=-1;return C.Ftruncate(d.Sysfd,c);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Ftruncate};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Ftruncate=function(c){return this.$val.Ftruncate(c);};Q.ptr.prototype.Init=function(c,d){var c,d,e,f;e=this;if(c===\"file\"){e.isFile=true;}if(!d){e.isBlocking=1;return $ifaceNil;}f=e.pd.init(e);if(!($interfaceIsEqual(f,$ifaceNil))){e.isBlocking=1;}return f;};Q.prototype.Init=function(c,d){return this.$val.Init(c,d);};Q.ptr.prototype.destroy=function(){var c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;c.pd.close();d=$pkg.CloseFunc(c.Sysfd);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;c.Sysfd=-1;$r=J((c.$ptr_csema||(c.$ptr_csema=new AG(function(){return this.$target.csema;},function($v){this.$target.csema=$v;},c))));$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.destroy};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.destroy=function(){return this.$val.destroy();};Q.ptr.prototype.Close=function(){var c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.fdmu.increfAndClose();$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}if(!d){$s=1;continue;}$s=2;continue;case 1:$s=-1;return L(c.isFile);case 2:c.pd.evict();e=c.decref();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(c.isBlocking===0){$s=5;continue;}$s=6;continue;case 5:$r=I((c.$ptr_csema||(c.$ptr_csema=new AG(function(){return this.$target.csema;},function($v){this.$target.csema=$v;},c))));$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 6:$s=-1;return f;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.Close};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.Close=function(){return this.$val.Close();};Q.ptr.prototype.Shutdown=function(c){var c,d,e,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.incref();if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}$deferred.push([$methodVal(d,\"decref\"),[]]);$s=-1;return C.Shutdown(d.Sysfd,c);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Shutdown};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Shutdown=function(c){return this.$val.Shutdown(c);};Q.ptr.prototype.SetBlocking=function(){var c,d,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=this;d=c.incref();if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return d;}$deferred.push([$methodVal(c,\"decref\"),[]]);D.StoreUint32((c.$ptr_isBlocking||(c.$ptr_isBlocking=new AG(function(){return this.$target.isBlocking;},function($v){this.$target.isBlocking=$v;},c))),1);$s=-1;return C.SetNonblock(c.Sysfd,false);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetBlocking};}$f.c=c;$f.d=d;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetBlocking=function(){return this.$val.SetBlocking();};Q.ptr.prototype.Read=function(c){var c,d,e,f,g,h,i,j,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.readLock();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[0,f];}$deferred.push([$methodVal(d,\"readUnlock\"),[]]);if(c.$length===0){$s=-1;return[0,$ifaceNil];}g=d.pd.prepareRead(d.isFile);if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[0,g];}if(d.IsStream&&c.$length>1073741824){c=$subslice(c,0,1073741824);}while(true){h=C.Read(d.Sysfd,c);i=h[0];j=h[1];if(!($interfaceIsEqual(j,$ifaceNil))){i=0;if($interfaceIsEqual(j,new C.Errno(11))&&d.pd.pollable()){j=d.pd.waitRead(d.isFile);if($interfaceIsEqual(j,$ifaceNil)){continue;}}if(false&&$interfaceIsEqual(j,new C.Errno(4))){continue;}}j=d.eofError(i,j);$s=-1;return[i,j];}$s=-1;return[0,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Read};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Read=function(c){return this.$val.Read(c);};Q.ptr.prototype.Pread=function(c,d){var c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=e.incref();if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[0,f];}if(e.IsStream&&c.$length>1073741824){c=$subslice(c,0,1073741824);}g=C.Pread(e.Sysfd,c,d);h=g[0];i=g[1];if(!($interfaceIsEqual(i,$ifaceNil))){h=0;}j=e.decref();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}j;i=e.eofError(h,i);$s=-1;return[h,i];}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.Pread};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.Pread=function(c,d){return this.$val.Pread(c,d);};Q.ptr.prototype.ReadFrom=function(c){var c,d,e,f,g,h,i,j,k,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.readLock();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[0,$ifaceNil,f];}$deferred.push([$methodVal(d,\"readUnlock\"),[]]);g=d.pd.prepareRead(d.isFile);if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[0,$ifaceNil,g];}while(true){h=C.Recvfrom(d.Sysfd,c,0);i=h[0];j=h[1];k=h[2];if(!($interfaceIsEqual(k,$ifaceNil))){i=0;if($interfaceIsEqual(k,new C.Errno(11))&&d.pd.pollable()){k=d.pd.waitRead(d.isFile);if($interfaceIsEqual(k,$ifaceNil)){continue;}}}k=d.eofError(i,k);$s=-1;return[i,j,k];}$s=-1;return[0,$ifaceNil,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.ReadFrom};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.ReadFrom=function(c){return this.$val.ReadFrom(c);};Q.ptr.prototype.ReadMsg=function(c,d){var c,d,e,f,g,h,i,j,k,l,m,n,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);e=this;f=e.readLock();$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[0,0,0,$ifaceNil,g];}$deferred.push([$methodVal(e,\"readUnlock\"),[]]);h=e.pd.prepareRead(e.isFile);if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[0,0,0,$ifaceNil,h];}while(true){i=C.Recvmsg(e.Sysfd,c,d,0);j=i[0];k=i[1];l=i[2];m=i[3];n=i[4];if(!($interfaceIsEqual(n,$ifaceNil))){if($interfaceIsEqual(n,new C.Errno(11))&&e.pd.pollable()){n=e.pd.waitRead(e.isFile);if($interfaceIsEqual(n,$ifaceNil)){continue;}}}n=e.eofError(j,n);$s=-1;return[j,k,l,m,n];}$s=-1;return[0,0,0,$ifaceNil,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,0,0,$ifaceNil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.ReadMsg};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.ReadMsg=function(c,d){return this.$val.ReadMsg(c,d);};Q.ptr.prototype.Write=function(c){var c,d,e,f,g,h,i,j,k,l,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.writeLock();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[0,f];}$deferred.push([$methodVal(d,\"writeUnlock\"),[]]);g=d.pd.prepareWrite(d.isFile);if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[0,g];}h=0;while(true){i=c.$length;if(d.IsStream&&(i-h>>0)>1073741824){i=h+1073741824>>0;}j=C.Write(d.Sysfd,$subslice(c,h,i));k=j[0];l=j[1];if(k>0){h=h+(k)>>0;}if(h===c.$length){$s=-1;return[h,l];}if($interfaceIsEqual(l,new C.Errno(11))&&d.pd.pollable()){l=d.pd.waitWrite(d.isFile);if($interfaceIsEqual(l,$ifaceNil)){continue;}}if(!($interfaceIsEqual(l,$ifaceNil))){$s=-1;return[h,l];}if(k===0){$s=-1;return[h,E.ErrUnexpectedEOF];}}$s=-1;return[0,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Write};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Write=function(c){return this.$val.Write(c);};Q.ptr.prototype.Pwrite=function(c,d){var c,d,e,f,g,h,i,j,k,l,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);e=this;f=e.incref();if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[0,f];}$deferred.push([$methodVal(e,\"decref\"),[]]);g=0;while(true){h=c.$length;if(e.IsStream&&(h-g>>0)>1073741824){h=g+1073741824>>0;}i=C.Pwrite(e.Sysfd,$subslice(c,g,h),(j=(new $Int64(0,g)),new $Int64(d.$high+j.$high,d.$low+j.$low)));k=i[0];l=i[1];if(k>0){g=g+(k)>>0;}if(g===c.$length){$s=-1;return[g,l];}if(!($interfaceIsEqual(l,$ifaceNil))){$s=-1;return[g,l];}if(k===0){$s=-1;return[g,E.ErrUnexpectedEOF];}}$s=-1;return[0,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Pwrite};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Pwrite=function(c,d){return this.$val.Pwrite(c,d);};Q.ptr.prototype.WriteTo=function(c,d){var c,d,e,f,g,h,i,j,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);e=this;f=e.writeLock();$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[0,g];}$deferred.push([$methodVal(e,\"writeUnlock\"),[]]);h=e.pd.prepareWrite(e.isFile);if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[0,h];}case 2:i=C.Sendto(e.Sysfd,c,0,d);$s=4;case 4:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}j=i;if($interfaceIsEqual(j,new C.Errno(11))&&e.pd.pollable()){j=e.pd.waitWrite(e.isFile);if($interfaceIsEqual(j,$ifaceNil)){$s=2;continue;}}if(!($interfaceIsEqual(j,$ifaceNil))){$s=-1;return[0,j];}$s=-1;return[c.$length,$ifaceNil];$s=2;continue;case 3:$s=-1;return[0,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.WriteTo};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.WriteTo=function(c,d){return this.$val.WriteTo(c,d);};Q.ptr.prototype.WriteMsg=function(c,d,e){var c,d,e,f,g,h,i,j,k,l,m,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.writeLock();$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[0,0,h];}$deferred.push([$methodVal(f,\"writeUnlock\"),[]]);i=f.pd.prepareWrite(f.isFile);if(!($interfaceIsEqual(i,$ifaceNil))){$s=-1;return[0,0,i];}case 2:k=C.SendmsgN(f.Sysfd,c,d,e,0);$s=4;case 4:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[0];m=j[1];if($interfaceIsEqual(m,new C.Errno(11))&&f.pd.pollable()){m=f.pd.waitWrite(f.isFile);if($interfaceIsEqual(m,$ifaceNil)){$s=2;continue;}}if(!($interfaceIsEqual(m,$ifaceNil))){$s=-1;return[l,0,m];}$s=-1;return[l,d.$length,m];$s=2;continue;case 3:$s=-1;return[0,0,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.WriteMsg};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.WriteMsg=function(c,d,e){return this.$val.WriteMsg(c,d,e);};Q.ptr.prototype.Accept=function(){var c,d,e,f,g,h,i,j,k,l,m,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=this;d=c.readLock();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[-1,$ifaceNil,\"\",e];}$deferred.push([$methodVal(c,\"readUnlock\"),[]]);f=c.pd.prepareRead(c.isFile);if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[-1,$ifaceNil,\"\",f];}case 2:h=W(c.Sysfd);$s=4;case 4:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;i=g[0];j=g[1];k=g[2];l=g[3];if($interfaceIsEqual(l,$ifaceNil)){$s=-1;return[i,j,\"\",l];}m=l;if($interfaceIsEqual(m,new C.Errno((11)))){if(c.pd.pollable()){l=c.pd.waitRead(c.isFile);if($interfaceIsEqual(l,$ifaceNil)){$s=2;continue;}}}else if($interfaceIsEqual(m,new C.Errno((103)))){$s=2;continue;}$s=-1;return[-1,$ifaceNil,k,l];$s=2;continue;case 3:$s=-1;return[0,$ifaceNil,\"\",$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil,\"\",$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Accept};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Accept=function(){return this.$val.Accept();};Q.ptr.prototype.Seek=function(c,d){var c,d,e,f,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);e=this;f=e.incref();if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[new $Int64(0,0),f];}$deferred.push([$methodVal(e,\"decref\"),[]]);$s=-1;return C.Seek(e.Sysfd,c,d);}return;}}catch(err){$err=err;$s=-1;return[new $Int64(0,0),$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Seek};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Seek=function(c,d){return this.$val.Seek(c,d);};Q.ptr.prototype.ReadDirent=function(c){var c,d,e,f,g,h,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.incref();if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[0,e];}$deferred.push([$methodVal(d,\"decref\"),[]]);while(true){f=C.ReadDirent(d.Sysfd,c);g=f[0];h=f[1];if(!($interfaceIsEqual(h,$ifaceNil))){g=0;if($interfaceIsEqual(h,new C.Errno(11))&&d.pd.pollable()){h=d.pd.waitRead(d.isFile);if($interfaceIsEqual(h,$ifaceNil)){continue;}}}$s=-1;return[g,h];}$s=-1;return[0,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.ReadDirent};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.ReadDirent=function(c){return this.$val.ReadDirent(c);};Q.ptr.prototype.Fchdir=function(){var c,d,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=this;d=c.incref();if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return d;}$deferred.push([$methodVal(c,\"decref\"),[]]);$s=-1;return C.Fchdir(c.Sysfd);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Fchdir};}$f.c=c;$f.d=d;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Fchdir=function(){return this.$val.Fchdir();};Q.ptr.prototype.Fstat=function(c){var c,d,e,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.incref();if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}$deferred.push([$methodVal(d,\"decref\"),[]]);$s=-1;return C.Fstat(d.Sysfd,c);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Fstat};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Fstat=function(c){return this.$val.Fstat(c);};S=function(c){var c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(D.LoadInt32((AE||(AE=new AK(function(){return R;},function($v){R=$v;}))))===1){d=O(c,1030,0);e=d[0];f=d[1];if($interfaceIsEqual(f,$ifaceNil)){$s=-1;return[e,\"\",$ifaceNil];}g=$assertType(f,C.Errno);if((g===(22))||(g===(38))){D.StoreInt32((AE||(AE=new AK(function(){return R;},function($v){R=$v;}))),0);}else{$s=-1;return[-1,\"fcntl\",f];}}h=T(c);$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}$s=-1;return h;}return;}if($f===undefined){$f={$blk:S};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};$pkg.DupCloseOnExec=S;T=function(c){var c,d,e,f,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);$r=C.ForkLock.RLock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(C.ForkLock,\"RUnlock\"),[]]);d=C.Dup(c);e=d[0];f=d[1];if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[-1,\"dup\",f];}C.CloseOnExec(e);$s=-1;return[e,\"\",$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[0,\"\",$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:T};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.ptr.prototype.Dup=function(){var c,d,e,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=this;d=c.incref();if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return[-1,\"\",d];}$deferred.push([$methodVal(c,\"decref\"),[]]);e=S(c.Sysfd);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}}catch(err){$err=err;$s=-1;return[0,\"\",$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Dup};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Dup=function(){return this.$val.Dup();};Q.ptr.prototype.WaitWrite=function(){var c;c=this;return c.pd.waitWrite(c.isFile);};Q.prototype.WaitWrite=function(){return this.$val.WaitWrite();};Q.ptr.prototype.WriteOnce=function(c){var c,d,e,f,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.writeLock();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[0,f];}$deferred.push([$methodVal(d,\"writeUnlock\"),[]]);$s=-1;return C.Write(d.Sysfd,c);}return;}}catch(err){$err=err;$s=-1;return[0,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.WriteOnce};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.WriteOnce=function(c){return this.$val.WriteOnce(c);};Q.ptr.prototype.RawControl=function(c){var c,d,e,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.incref();if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}$deferred.push([$methodVal(d,\"decref\"),[]]);$r=c(((d.Sysfd>>>0)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return $ifaceNil;}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.RawControl};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.RawControl=function(c){return this.$val.RawControl(c);};Q.ptr.prototype.RawRead=function(c){var c,d,e,f,g,h,i,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.readLock();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return f;}$deferred.push([$methodVal(d,\"readUnlock\"),[]]);g=d.pd.prepareRead(d.isFile);if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}case 2:h=c(((d.Sysfd>>>0)));$s=6;case 6:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if(h){$s=4;continue;}$s=5;continue;case 4:$s=-1;return $ifaceNil;case 5:i=d.pd.waitRead(d.isFile);if(!($interfaceIsEqual(i,$ifaceNil))){$s=-1;return i;}$s=2;continue;case 3:$s=-1;return $ifaceNil;}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.RawRead};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.RawRead=function(c){return this.$val.RawRead(c);};Q.ptr.prototype.RawWrite=function(c){var c,d,e,f,g,h,i,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=this;e=d.writeLock();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return f;}$deferred.push([$methodVal(d,\"writeUnlock\"),[]]);g=d.pd.prepareWrite(d.isFile);if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}case 2:h=c(((d.Sysfd>>>0)));$s=6;case 6:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if(h){$s=4;continue;}$s=5;continue;case 4:$s=-1;return $ifaceNil;case 5:i=d.pd.waitWrite(d.isFile);if(!($interfaceIsEqual(i,$ifaceNil))){$s=-1;return i;}$s=2;continue;case 3:$s=-1;return $ifaceNil;}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.RawWrite};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.RawWrite=function(c){return this.$val.RawWrite(c);};U=function(c,d){var c,d,e,f,g;e=C.Syscall(20,((c>>>0)),(($sliceToArray(d))),((d.$length>>>0)));f=e[0];g=e[2];if(!((g===0))){return[f,new C.Errno((g))];}return[f,$ifaceNil];};W=function(c){var c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=$pkg.Accept4Func(c,526336);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;f=d[0];g=d[1];h=d[2];i=h;if($interfaceIsEqual(i,$ifaceNil)){$s=-1;return[f,g,\"\",$ifaceNil];}else if($interfaceIsEqual(i,new C.Errno((38)))){}else if($interfaceIsEqual(i,new C.Errno((22)))){}else if($interfaceIsEqual(i,new C.Errno((13)))){}else if($interfaceIsEqual(i,new C.Errno((14)))){}else{$s=-1;return[-1,g,\"accept4\",h];}k=$pkg.AcceptFunc(c);$s=2;case 2:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;f=j[0];g=j[1];h=j[2];if($interfaceIsEqual(h,$ifaceNil)){C.CloseOnExec(f);}if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[-1,$ifaceNil,\"accept\",h];}h=C.SetNonblock(f,true);if(!($interfaceIsEqual(h,$ifaceNil))){$s=3;continue;}$s=4;continue;case 3:l=$pkg.CloseFunc(f);$s=5;case 5:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}l;$s=-1;return[-1,$ifaceNil,\"setnonblock\",h];case 4:$s=-1;return[f,g,\"\",$ifaceNil];}return;}if($f===undefined){$f={$blk:W};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};Q.ptr.prototype.SetsockoptInt=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptInt(f.Sysfd,c,d,e);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptInt};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptInt=function(c,d,e){return this.$val.SetsockoptInt(c,d,e);};Q.ptr.prototype.SetsockoptInet4Addr=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptInet4Addr(f.Sysfd,c,d,$clone(e,AM));}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptInet4Addr};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptInet4Addr=function(c,d,e){return this.$val.SetsockoptInet4Addr(c,d,e);};Q.ptr.prototype.SetsockoptLinger=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptLinger(f.Sysfd,c,d,e);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptLinger};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptLinger=function(c,d,e){return this.$val.SetsockoptLinger(c,d,e);};Q.ptr.prototype.SetsockoptIPMreqn=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptIPMreqn(f.Sysfd,c,d,e);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptIPMreqn};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptIPMreqn=function(c,d,e){return this.$val.SetsockoptIPMreqn(c,d,e);};Q.ptr.prototype.SetsockoptByte=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptByte(f.Sysfd,c,d,e);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptByte};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptByte=function(c,d,e){return this.$val.SetsockoptByte(c,d,e);};Q.ptr.prototype.SetsockoptIPMreq=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptIPMreq(f.Sysfd,c,d,e);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptIPMreq};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptIPMreq=function(c,d,e){return this.$val.SetsockoptIPMreq(c,d,e);};Q.ptr.prototype.SetsockoptIPv6Mreq=function(c,d,e){var c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);f=this;g=f.incref();if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}$deferred.push([$methodVal(f,\"decref\"),[]]);$s=-1;return C.SetsockoptIPv6Mreq(f.Sysfd,c,d,e);}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.SetsockoptIPv6Mreq};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.SetsockoptIPv6Mreq=function(c,d,e){return this.$val.SetsockoptIPv6Mreq(c,d,e);};Q.ptr.prototype.Writev=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);d=[d];e=this;f=e.writeLock();$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[new $Int64(0,0),g];}$deferred.push([$methodVal(e,\"writeUnlock\"),[]]);h=e.pd.prepareWrite(e.isFile);if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[new $Int64(0,0),h];}d[0]=AR.nil;if(!(e.iovecs===AS.nil)){d[0]=e.iovecs.$get();}i=1024;j=new $Int64(0,0);k=$ifaceNil;case 2:if(!(c.$get().$length>0)){$s=3;continue;}d[0]=$subslice(d[0],0,0);l=c.$get();m=0;case 4:if(!(m<l.$length)){$s=5;continue;}n=((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m]);if(n.$length===0){m++;$s=4;continue;}d[0]=$append(d[0],new C.Iovec.ptr($indexPtr(n.$array,n.$offset+0,AT),new $Uint64(0,0)));if(e.IsStream&&n.$length>1073741824){(o=d[0].$length-1>>0,((o<0||o>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+o])).SetLen(1073741824);$s=5;continue;}(p=d[0].$length-1>>0,((p<0||p>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+p])).SetLen(n.$length);if(d[0].$length===i){$s=5;continue;}m++;$s=4;continue;case 5:if(d[0].$length===0){$s=3;continue;}e.iovecs=(d.$ptr||(d.$ptr=new AS(function(){return this.$target[0];},function($v){this.$target[0]=$v;},d)));q=0;r=U(e.Sysfd,d[0]);q=r[0];k=r[1];if(q===4294967295){q=0;}$r=$pkg.TestHookDidWritev(((q>>0)));$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}j=(s=(new $Int64(0,q.constructor===Number?q:1)),new $Int64(j.$high+s.$high,j.$low+s.$low));N(c,(new $Int64(0,q.constructor===Number?q:1)));if(!($interfaceIsEqual(k,$ifaceNil))){if($assertType(k,C.Errno)===11){k=e.pd.waitWrite(e.isFile);if($interfaceIsEqual(k,$ifaceNil)){$s=2;continue;}}$s=3;continue;}if((j.$high===0&&j.$low===0)){k=E.ErrUnexpectedEOF;$s=3;continue;}$s=2;continue;case 3:$s=-1;return[j,k];}return;}}catch(err){$err=err;$s=-1;return[new $Int64(0,0),$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.Writev};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.Writev=function(c){return this.$val.Writev(c);};AV.methods=[{prop:\"init\",name:\"init\",pkg:\"internal/poll\",typ:$funcType([AU],[$error],false)},{prop:\"close\",name:\"close\",pkg:\"internal/poll\",typ:$funcType([],[],false)},{prop:\"evict\",name:\"evict\",pkg:\"internal/poll\",typ:$funcType([],[],false)},{prop:\"prepare\",name:\"prepare\",pkg:\"internal/poll\",typ:$funcType([$Int,$Bool],[$error],false)},{prop:\"prepareRead\",name:\"prepareRead\",pkg:\"internal/poll\",typ:$funcType([$Bool],[$error],false)},{prop:\"prepareWrite\",name:\"prepareWrite\",pkg:\"internal/poll\",typ:$funcType([$Bool],[$error],false)},{prop:\"wait\",name:\"wait\",pkg:\"internal/poll\",typ:$funcType([$Int,$Bool],[$error],false)},{prop:\"waitRead\",name:\"waitRead\",pkg:\"internal/poll\",typ:$funcType([$Bool],[$error],false)},{prop:\"waitWrite\",name:\"waitWrite\",pkg:\"internal/poll\",typ:$funcType([$Bool],[$error],false)},{prop:\"waitCanceled\",name:\"waitCanceled\",pkg:\"internal/poll\",typ:$funcType([$Int],[],false)},{prop:\"pollable\",name:\"pollable\",pkg:\"internal/poll\",typ:$funcType([],[$Bool],false)}];AW.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}];AX.methods=[{prop:\"incref\",name:\"incref\",pkg:\"internal/poll\",typ:$funcType([],[$Bool],false)},{prop:\"increfAndClose\",name:\"increfAndClose\",pkg:\"internal/poll\",typ:$funcType([],[$Bool],false)},{prop:\"decref\",name:\"decref\",pkg:\"internal/poll\",typ:$funcType([],[$Bool],false)},{prop:\"rwlock\",name:\"rwlock\",pkg:\"internal/poll\",typ:$funcType([$Bool],[$Bool],false)},{prop:\"rwunlock\",name:\"rwunlock\",pkg:\"internal/poll\",typ:$funcType([$Bool],[$Bool],false)}];AU.methods=[{prop:\"SetDeadline\",name:\"SetDeadline\",pkg:\"\",typ:$funcType([A.Time],[$error],false)},{prop:\"SetReadDeadline\",name:\"SetReadDeadline\",pkg:\"\",typ:$funcType([A.Time],[$error],false)},{prop:\"SetWriteDeadline\",name:\"SetWriteDeadline\",pkg:\"\",typ:$funcType([A.Time],[$error],false)},{prop:\"Fsync\",name:\"Fsync\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"incref\",name:\"incref\",pkg:\"internal/poll\",typ:$funcType([],[$error],false)},{prop:\"decref\",name:\"decref\",pkg:\"internal/poll\",typ:$funcType([],[$error],false)},{prop:\"readLock\",name:\"readLock\",pkg:\"internal/poll\",typ:$funcType([],[$error],false)},{prop:\"readUnlock\",name:\"readUnlock\",pkg:\"internal/poll\",typ:$funcType([],[],false)},{prop:\"writeLock\",name:\"writeLock\",pkg:\"internal/poll\",typ:$funcType([],[$error],false)},{prop:\"writeUnlock\",name:\"writeUnlock\",pkg:\"internal/poll\",typ:$funcType([],[],false)},{prop:\"eofError\",name:\"eofError\",pkg:\"internal/poll\",typ:$funcType([$Int,$error],[$error],false)},{prop:\"Fchmod\",name:\"Fchmod\",pkg:\"\",typ:$funcType([$Uint32],[$error],false)},{prop:\"Fchown\",name:\"Fchown\",pkg:\"\",typ:$funcType([$Int,$Int],[$error],false)},{prop:\"Ftruncate\",name:\"Ftruncate\",pkg:\"\",typ:$funcType([$Int64],[$error],false)},{prop:\"Init\",name:\"Init\",pkg:\"\",typ:$funcType([$String,$Bool],[$error],false)},{prop:\"destroy\",name:\"destroy\",pkg:\"internal/poll\",typ:$funcType([],[$error],false)},{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Shutdown\",name:\"Shutdown\",pkg:\"\",typ:$funcType([$Int],[$error],false)},{prop:\"SetBlocking\",name:\"SetBlocking\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)},{prop:\"Pread\",name:\"Pread\",pkg:\"\",typ:$funcType([AY,$Int64],[$Int,$error],false)},{prop:\"ReadFrom\",name:\"ReadFrom\",pkg:\"\",typ:$funcType([AY],[$Int,C.Sockaddr,$error],false)},{prop:\"ReadMsg\",name:\"ReadMsg\",pkg:\"\",typ:$funcType([AY,AY],[$Int,$Int,$Int,C.Sockaddr,$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)},{prop:\"Pwrite\",name:\"Pwrite\",pkg:\"\",typ:$funcType([AY,$Int64],[$Int,$error],false)},{prop:\"WriteTo\",name:\"WriteTo\",pkg:\"\",typ:$funcType([AY,C.Sockaddr],[$Int,$error],false)},{prop:\"WriteMsg\",name:\"WriteMsg\",pkg:\"\",typ:$funcType([AY,AY,C.Sockaddr],[$Int,$Int,$error],false)},{prop:\"Accept\",name:\"Accept\",pkg:\"\",typ:$funcType([],[$Int,C.Sockaddr,$String,$error],false)},{prop:\"Seek\",name:\"Seek\",pkg:\"\",typ:$funcType([$Int64,$Int],[$Int64,$error],false)},{prop:\"ReadDirent\",name:\"ReadDirent\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)},{prop:\"Fchdir\",name:\"Fchdir\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Fstat\",name:\"Fstat\",pkg:\"\",typ:$funcType([AZ],[$error],false)},{prop:\"Dup\",name:\"Dup\",pkg:\"\",typ:$funcType([],[$Int,$String,$error],false)},{prop:\"WaitWrite\",name:\"WaitWrite\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"WriteOnce\",name:\"WriteOnce\",pkg:\"\",typ:$funcType([AY],[$Int,$error],false)},{prop:\"RawControl\",name:\"RawControl\",pkg:\"\",typ:$funcType([BA],[$error],false)},{prop:\"RawRead\",name:\"RawRead\",pkg:\"\",typ:$funcType([BB],[$error],false)},{prop:\"RawWrite\",name:\"RawWrite\",pkg:\"\",typ:$funcType([BB],[$error],false)},{prop:\"SetsockoptInt\",name:\"SetsockoptInt\",pkg:\"\",typ:$funcType([$Int,$Int,$Int],[$error],false)},{prop:\"SetsockoptInet4Addr\",name:\"SetsockoptInet4Addr\",pkg:\"\",typ:$funcType([$Int,$Int,AM],[$error],false)},{prop:\"SetsockoptLinger\",name:\"SetsockoptLinger\",pkg:\"\",typ:$funcType([$Int,$Int,BC],[$error],false)},{prop:\"SetsockoptIPMreqn\",name:\"SetsockoptIPMreqn\",pkg:\"\",typ:$funcType([$Int,$Int,BD],[$error],false)},{prop:\"SetsockoptByte\",name:\"SetsockoptByte\",pkg:\"\",typ:$funcType([$Int,$Int,$Uint8],[$error],false)},{prop:\"SetsockoptIPMreq\",name:\"SetsockoptIPMreq\",pkg:\"\",typ:$funcType([$Int,$Int,BE],[$error],false)},{prop:\"SetsockoptIPv6Mreq\",name:\"SetsockoptIPv6Mreq\",pkg:\"\",typ:$funcType([$Int,$Int,BF],[$error],false)},{prop:\"Writev\",name:\"Writev\",pkg:\"\",typ:$funcType([BH],[$Int64,$error],false)}];G.init(\"internal/poll\",[{prop:\"closing\",name:\"closing\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);M.init(\"\",[]);P.init(\"internal/poll\",[{prop:\"state\",name:\"state\",embedded:false,exported:false,typ:$Uint64,tag:\"\"},{prop:\"rsema\",name:\"rsema\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"wsema\",name:\"wsema\",embedded:false,exported:false,typ:$Uint32,tag:\"\"}]);Q.init(\"internal/poll\",[{prop:\"fdmu\",name:\"fdmu\",embedded:false,exported:false,typ:P,tag:\"\"},{prop:\"Sysfd\",name:\"Sysfd\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"pd\",name:\"pd\",embedded:false,exported:false,typ:G,tag:\"\"},{prop:\"iovecs\",name:\"iovecs\",embedded:false,exported:false,typ:AS,tag:\"\"},{prop:\"csema\",name:\"csema\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"isBlocking\",name:\"isBlocking\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"IsStream\",name:\"IsStream\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"ZeroReadIsEOF\",name:\"ZeroReadIsEOF\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"isFile\",name:\"isFile\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}K={};$pkg.ErrNetClosing=B.New(\"use of closed network connection\");$pkg.ErrFileClosing=B.New(\"use of closed file\");$pkg.ErrNoDeadline=B.New(\"file type does not support deadline\");$pkg.ErrTimeout=new M.ptr();$pkg.TestHookDidWritev=(function(c){var c;});R=1;$pkg.Accept4Func=C.Accept4;$pkg.CloseFunc=C.Close;$pkg.AcceptFunc=C.Accept;}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/syscall/unix\"]=(function(){var $pkg={},$init,B,A,C;B=$packages[\"sync/atomic\"];A=$packages[\"syscall\"];C=function(b){var b,c,d,e,f;c=false;d=$ifaceNil;e=false;f=$ifaceNil;c=e;d=f;return[c,d];};$pkg.IsNonblock=C;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/testlog\"]=(function(){var $pkg={},$init,A,B,I,C,E,G,H;A=$packages[\"sync/atomic\"];B=$pkg.Interface=$newType(8,$kindInterface,\"testlog.Interface\",true,\"internal/testlog\",true,null);I=$ptrType(B);E=function(){var a;a=C.Load();if($interfaceIsEqual(a,$ifaceNil)){return $ifaceNil;}return $assertType(a,I).$get();};$pkg.Logger=E;G=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=E();if(!($interfaceIsEqual(b,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:$r=b.Open(a);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:G};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Open=G;H=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=E();if(!($interfaceIsEqual(b,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:$r=b.Stat(a);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:H};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Stat=H;B.init([{prop:\"Chdir\",name:\"Chdir\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"Getenv\",name:\"Getenv\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"Open\",name:\"Open\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"Stat\",name:\"Stat\",pkg:\"\",typ:$funcType([$String],[],false)}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}C=new A.Value.ptr($ifaceNil);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"os\"]=(function(){var $pkg={},$init,A,B,G,K,F,C,D,H,I,E,J,P,AC,AD,AE,BC,BZ,DC,DT,DU,DV,DX,EA,EB,EC,ED,EE,EF,EG,EH,ET,EU,EV,EW,EX,FB,FG,FH,FL,FM,FN,AZ,BJ,L,M,N,AF,AH,AK,AL,AN,BE,BG,BI,BP,BQ,BS,BT,BX,CA,CC,CD,CE,CR,CV,DB,DD,DH,DI,DJ,DK,DM,DN;A=$packages[\"errors\"];B=$packages[\"github.com/gopherjs/gopherjs/js\"];G=$packages[\"internal/poll\"];K=$packages[\"internal/syscall/unix\"];F=$packages[\"internal/testlog\"];C=$packages[\"io\"];D=$packages[\"runtime\"];H=$packages[\"sync\"];I=$packages[\"sync/atomic\"];E=$packages[\"syscall\"];J=$packages[\"time\"];P=$pkg.dirInfo=$newType(0,$kindStruct,\"os.dirInfo\",true,\"os\",false,function(buf_,nbuf_,bufp_){this.$val=this;if(arguments.length===0){this.buf=EE.nil;this.nbuf=0;this.bufp=0;return;}this.buf=buf_;this.nbuf=nbuf_;this.bufp=bufp_;});AC=$pkg.timeout=$newType(8,$kindInterface,\"os.timeout\",true,\"os\",false,null);AD=$pkg.PathError=$newType(0,$kindStruct,\"os.PathError\",true,\"os\",true,function(Op_,Path_,Err_){this.$val=this;if(arguments.length===0){this.Op=\"\";this.Path=\"\";this.Err=$ifaceNil;return;}this.Op=Op_;this.Path=Path_;this.Err=Err_;});AE=$pkg.SyscallError=$newType(0,$kindStruct,\"os.SyscallError\",true,\"os\",true,function(Syscall_,Err_){this.$val=this;if(arguments.length===0){this.Syscall=\"\";this.Err=$ifaceNil;return;}this.Syscall=Syscall_;this.Err=Err_;});BC=$pkg.LinkError=$newType(0,$kindStruct,\"os.LinkError\",true,\"os\",true,function(Op_,Old_,New_,Err_){this.$val=this;if(arguments.length===0){this.Op=\"\";this.Old=\"\";this.New=\"\";this.Err=$ifaceNil;return;}this.Op=Op_;this.Old=Old_;this.New=New_;this.Err=Err_;});BZ=$pkg.file=$newType(0,$kindStruct,\"os.file\",true,\"os\",false,function(pfd_,name_,dirinfo_,nonblock_,stdoutOrErr_){this.$val=this;if(arguments.length===0){this.pfd=new G.FD.ptr(new G.fdMutex.ptr(new $Uint64(0,0),0,0),0,new G.pollDesc.ptr(false),EU.nil,0,0,false,false,false);this.name=\"\";this.dirinfo=ED.nil;this.nonblock=false;this.stdoutOrErr=false;return;}this.pfd=pfd_;this.name=name_;this.dirinfo=dirinfo_;this.nonblock=nonblock_;this.stdoutOrErr=stdoutOrErr_;});DC=$pkg.rawConn=$newType(0,$kindStruct,\"os.rawConn\",true,\"os\",false,function(file_){this.$val=this;if(arguments.length===0){this.file=EB.nil;return;}this.file=file_;});DT=$pkg.File=$newType(0,$kindStruct,\"os.File\",true,\"os\",true,function(file_){this.$val=this;if(arguments.length===0){this.file=EW.nil;return;}this.file=file_;});DU=$pkg.FileInfo=$newType(8,$kindInterface,\"os.FileInfo\",true,\"os\",true,null);DV=$pkg.FileMode=$newType(4,$kindUint32,\"os.FileMode\",true,\"os\",true,null);DX=$pkg.fileStat=$newType(0,$kindStruct,\"os.fileStat\",true,\"os\",false,function(name_,size_,mode_,modTime_,sys_){this.$val=this;if(arguments.length===0){this.name=\"\";this.size=new $Int64(0,0);this.mode=0;this.modTime=new J.Time.ptr(new $Uint64(0,0),new $Int64(0,0),FB.nil);this.sys=new E.Stat_t.ptr(new $Uint64(0,0),new $Uint64(0,0),new $Uint64(0,0),0,0,0,0,new $Uint64(0,0),new $Int64(0,0),new $Int64(0,0),new $Int64(0,0),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),EV.zero());return;}this.name=name_;this.size=size_;this.mode=mode_;this.modTime=modTime_;this.sys=sys_;});EA=$sliceType($String);EB=$ptrType(DT);EC=$sliceType(DU);ED=$ptrType(P);EE=$sliceType($Uint8);EF=$ptrType(AD);EG=$ptrType(BC);EH=$ptrType(AE);ET=$sliceType(E.Iovec);EU=$ptrType(ET);EV=$arrayType($Int64,3);EW=$ptrType(BZ);EX=$funcType([EW],[$error],false);FB=$ptrType(J.Location);FG=$arrayType($Uint8,32);FH=$ptrType(DX);FL=$funcType([$Uintptr],[],false);FM=$funcType([$Uintptr],[$Bool],false);FN=$ptrType(DC);L=function(){return $pkg.Args;};M=function(){var c,d,e;c=$global.process;if(!(c===undefined)){d=c.argv;$pkg.Args=$makeSlice(EA,($parseInt(d.length)-1>>0));e=0;while(true){if(!(e<($parseInt(d.length)-1>>0))){break;}((e<0||e>=$pkg.Args.$length)?($throwRuntimeError(\"index out of range\"),undefined):$pkg.Args.$array[$pkg.Args.$offset+e]=$internalize(d[(e+1>>0)],$String));e=e+(1)>>0;}}if($pkg.Args.$length===0){$pkg.Args=new EA([\"?\"]);}};N=function(){};DT.ptr.prototype.Readdir=function(c){var c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;if(d===EB.nil){$s=-1;return[EC.nil,$pkg.ErrInvalid];}e=d.readdir(c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Readdir};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Readdir=function(c){return this.$val.Readdir(c);};DT.ptr.prototype.Readdirnames=function(c){var c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=EA.nil;e=$ifaceNil;f=this;if(f===EB.nil){g=EA.nil;h=$pkg.ErrInvalid;d=g;e=h;$s=-1;return[d,e];}j=f.readdirnames(c);$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;d=i[0];e=i[1];$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Readdirnames};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Readdirnames=function(c){return this.$val.Readdirnames(c);};P.ptr.prototype.close=function(){var c;c=this;};P.prototype.close=function(){return this.$val.close();};DT.ptr.prototype.readdirnames=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=EA.nil;e=$ifaceNil;f=this;if(f.file.dirinfo===ED.nil){f.file.dirinfo=new P.ptr(EE.nil,0,0);f.file.dirinfo.buf=$makeSlice(EE,8192);}g=f.file.dirinfo;h=c;if(h<=0){h=100;c=-1;}d=$makeSlice(EA,0,h);case 1:if(!(!((c===0)))){$s=2;continue;}if(g.bufp>=g.nbuf){$s=3;continue;}$s=4;continue;case 3:g.bufp=0;i=$ifaceNil;k=f.file.pfd.ReadDirent(g.buf);$s=5;case 5:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;g.nbuf=j[0];i=j[1];D.KeepAlive(f);if(!($interfaceIsEqual(i,$ifaceNil))){l=d;m=AL(\"readdirent\",i);d=l;e=m;$s=-1;return[d,e];}if(g.nbuf<=0){$s=2;continue;}case 4:n=0;o=0;p=n;q=o;r=E.ParseDirent($subslice(g.buf,g.bufp,g.nbuf),c,d);p=r[0];q=r[1];d=r[2];g.bufp=g.bufp+(p)>>0;c=c-(q)>>0;$s=1;continue;case 2:if(c>=0&&(d.$length===0)){s=d;t=C.EOF;d=s;e=t;$s=-1;return[d,e];}u=d;v=$ifaceNil;d=u;e=v;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.readdirnames};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.readdirnames=function(c){return this.$val.readdirnames(c);};AD.ptr.prototype.Error=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.Err.Error();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return c.Op+\" \"+c.Path+\": \"+d;}return;}if($f===undefined){$f={$blk:AD.ptr.prototype.Error};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AD.prototype.Error=function(){return this.$val.Error();};AD.ptr.prototype.Timeout=function(){var c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=$assertType(c.Err,AC,true);e=d[0];f=d[1];if(!(f)){g=false;$s=1;continue s;}h=e.Timeout();$s=2;case 2:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;case 1:$s=-1;return g;}return;}if($f===undefined){$f={$blk:AD.ptr.prototype.Timeout};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};AD.prototype.Timeout=function(){return this.$val.Timeout();};AE.ptr.prototype.Error=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.Err.Error();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return c.Syscall+\": \"+d;}return;}if($f===undefined){$f={$blk:AE.ptr.prototype.Error};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AE.prototype.Error=function(){return this.$val.Error();};AE.ptr.prototype.Timeout=function(){var c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=$assertType(c.Err,AC,true);e=d[0];f=d[1];if(!(f)){g=false;$s=1;continue s;}h=e.Timeout();$s=2;case 2:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;case 1:$s=-1;return g;}return;}if($f===undefined){$f={$blk:AE.ptr.prototype.Timeout};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};AE.prototype.Timeout=function(){return this.$val.Timeout();};AF=function(c,d){var c,d;if($interfaceIsEqual(d,$ifaceNil)){return $ifaceNil;}return new AE.ptr(c,d);};$pkg.NewSyscallError=AF;AH=function(c){var c;return AN(c);};$pkg.IsNotExist=AH;AK=function(c){var c,d,e,f,g;d=c;if($assertType(d,EF,true)[1]){e=d.$val;return e.Err;}else if($assertType(d,EG,true)[1]){f=d.$val;return f.Err;}else if($assertType(d,EH,true)[1]){g=d.$val;return g.Err;}return c;};AL=function(c,d){var c,d,e,f;e=$assertType(d,E.Errno,true);f=e[1];if(f){d=AF(c,d);}return d;};AN=function(c){var c;c=AK(c);return $interfaceIsEqual(c,new E.Errno(2))||$interfaceIsEqual(c,$pkg.ErrNotExist);};DT.ptr.prototype.Name=function(){var c;c=this;return c.file.name;};DT.prototype.Name=function(){return this.$val.Name();};BC.ptr.prototype.Error=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.Err.Error();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return c.Op+\" \"+c.Old+\" \"+c.New+\": \"+d;}return;}if($f===undefined){$f={$blk:BC.ptr.prototype.Error};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};BC.prototype.Error=function(){return this.$val.Error();};DT.ptr.prototype.Read=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;f=this;g=f.checkValid(\"read\");if(!($interfaceIsEqual(g,$ifaceNil))){h=0;i=g;d=h;e=i;$s=-1;return[d,e];}k=f.read(c);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;d=j[0];l=j[1];m=d;n=f.wrapErr(\"read\",l);d=m;e=n;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Read};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Read=function(c){return this.$val.Read(c);};DT.ptr.prototype.ReadAt=function(c,d){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=0;f=$ifaceNil;g=this;h=g.checkValid(\"read\");if(!($interfaceIsEqual(h,$ifaceNil))){i=0;j=h;e=i;f=j;$s=-1;return[e,f];}if((d.$high<0||(d.$high===0&&d.$low<0))){k=0;l=new AD.ptr(\"readat\",g.file.name,A.New(\"negative offset\"));e=k;f=l;$s=-1;return[e,f];}case 1:if(!(c.$length>0)){$s=2;continue;}n=g.pread(c,d);$s=3;case 3:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];if(!($interfaceIsEqual(p,$ifaceNil))){f=g.wrapErr(\"read\",p);$s=2;continue;}e=e+(o)>>0;c=$subslice(c,o);d=(q=(new $Int64(0,o)),new $Int64(d.$high+q.$high,d.$low+q.$low));$s=1;continue;case 2:$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.ReadAt};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.ReadAt=function(c,d){return this.$val.ReadAt(c,d);};DT.ptr.prototype.Write=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;f=this;g=f.checkValid(\"write\");if(!($interfaceIsEqual(g,$ifaceNil))){h=0;i=g;d=h;e=i;$s=-1;return[d,e];}k=f.write(c);$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;d=j[0];l=j[1];if(d<0){d=0;}if(!((d===c.$length))){e=C.ErrShortWrite;}CD(f,l);if(!($interfaceIsEqual(l,$ifaceNil))){e=f.wrapErr(\"write\",l);}m=d;n=e;d=m;e=n;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Write};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Write=function(c){return this.$val.Write(c);};DT.ptr.prototype.WriteAt=function(c,d){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=0;f=$ifaceNil;g=this;h=g.checkValid(\"write\");if(!($interfaceIsEqual(h,$ifaceNil))){i=0;j=h;e=i;f=j;$s=-1;return[e,f];}if((d.$high<0||(d.$high===0&&d.$low<0))){k=0;l=new AD.ptr(\"writeat\",g.file.name,A.New(\"negative offset\"));e=k;f=l;$s=-1;return[e,f];}case 1:if(!(c.$length>0)){$s=2;continue;}n=g.pwrite(c,d);$s=3;case 3:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];if(!($interfaceIsEqual(p,$ifaceNil))){f=g.wrapErr(\"write\",p);$s=2;continue;}e=e+(o)>>0;c=$subslice(c,o);d=(q=(new $Int64(0,o)),new $Int64(d.$high+q.$high,d.$low+q.$low));$s=1;continue;case 2:$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.WriteAt};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.WriteAt=function(c,d){return this.$val.WriteAt(c,d);};DT.ptr.prototype.Seek=function(c,d){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=new $Int64(0,0);f=$ifaceNil;g=this;h=g.checkValid(\"seek\");if(!($interfaceIsEqual(h,$ifaceNil))){i=new $Int64(0,0);j=h;e=i;f=j;$s=-1;return[e,f];}l=g.seek(c,d);$s=1;case 1:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}k=l;m=k[0];n=k[1];if($interfaceIsEqual(n,$ifaceNil)&&!(g.file.dirinfo===ED.nil)&&!((m.$high===0&&m.$low===0))){n=new E.Errno(21);}if(!($interfaceIsEqual(n,$ifaceNil))){o=new $Int64(0,0);p=g.wrapErr(\"seek\",n);e=o;f=p;$s=-1;return[e,f];}q=m;r=$ifaceNil;e=q;f=r;$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Seek};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Seek=function(c,d){return this.$val.Seek(c,d);};DT.ptr.prototype.WriteString=function(c){var c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;f=this;h=f.Write((new EE($stringToBytes(c))));$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;d=g[0];e=g[1];$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.WriteString};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.WriteString=function(c){return this.$val.WriteString(c);};BE=function(c){var c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=DH(c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;f=d[0];g=d[1];if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return g;}h=c;i=f.Mode();$s=2;case 2:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}j=(i|1048576)>>>0;k=BP(h,j);$s=3;case 3:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$s=-1;return k;}return;}if($f===undefined){$f={$blk:BE};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};BG=function(c){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=BI(c,0,0);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:BG};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Open=BG;BI=function(c,d,e){var c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=F.Open(c);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}f=CE(c,d,e);$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:BI};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};$pkg.OpenFile=BI;DT.ptr.prototype.wrapErr=function(c,d){var c,d,e;e=this;if($interfaceIsEqual(d,$ifaceNil)||$interfaceIsEqual(d,C.EOF)){return d;}if($interfaceIsEqual(d,G.ErrFileClosing)){d=$pkg.ErrClosed;}return new AD.ptr(c,e.file.name,d);};DT.prototype.wrapErr=function(c,d){return this.$val.wrapErr(c,d);};BP=function(c,d){var c,d;return BT(c,d);};$pkg.Chmod=BP;DT.ptr.prototype.Chmod=function(c){var c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.chmod(c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Chmod};}$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Chmod=function(c){return this.$val.Chmod(c);};DT.ptr.prototype.SetDeadline=function(c){var c,d;d=this;return d.setDeadline($clone(c,J.Time));};DT.prototype.SetDeadline=function(c){return this.$val.SetDeadline(c);};DT.ptr.prototype.SetReadDeadline=function(c){var c,d;d=this;return d.setReadDeadline($clone(c,J.Time));};DT.prototype.SetReadDeadline=function(c){return this.$val.SetReadDeadline(c);};DT.ptr.prototype.SetWriteDeadline=function(c){var c,d;d=this;return d.setWriteDeadline($clone(c,J.Time));};DT.prototype.SetWriteDeadline=function(c){return this.$val.SetWriteDeadline(c);};DT.ptr.prototype.SyscallConn=function(){var c,d,e;c=this;d=c.checkValid(\"SyscallConn\");if(!($interfaceIsEqual(d,$ifaceNil))){return[$ifaceNil,d];}e=DD(c);return[e[0],e[1]];};DT.prototype.SyscallConn=function(){return this.$val.SyscallConn();};BQ=function(){$throwRuntimeError(\"native function not implemented: os.sigpipe\");};BS=function(c){var c,d;d=0;d=(d|(((new DV(c).Perm()>>>0))))>>>0;if(!((((c&8388608)>>>0)===0))){d=(d|(2048))>>>0;}if(!((((c&4194304)>>>0)===0))){d=(d|(1024))>>>0;}if(!((((c&1048576)>>>0)===0))){d=(d|(512))>>>0;}return d;};BT=function(c,d){var c,d,e;e=E.Chmod(BX(c),BS(d));if(!($interfaceIsEqual(e,$ifaceNil))){return new AD.ptr(\"chmod\",c,e);}return $ifaceNil;};DT.ptr.prototype.chmod=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.checkValid(\"chmod\");if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}f=d.file.pfd.Fchmod(BS(c));$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return d.wrapErr(\"chmod\",g);}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.chmod};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.chmod=function(c){return this.$val.chmod(c);};DT.ptr.prototype.Chown=function(c,d){var c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=e.checkValid(\"chown\");if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return f;}g=e.file.pfd.Fchown(c,d);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return e.wrapErr(\"chown\",h);}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Chown};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Chown=function(c,d){return this.$val.Chown(c,d);};DT.ptr.prototype.Truncate=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.checkValid(\"truncate\");if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}f=d.file.pfd.Ftruncate(c);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return d.wrapErr(\"truncate\",g);}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Truncate};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Truncate=function(c){return this.$val.Truncate(c);};DT.ptr.prototype.Sync=function(){var c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.checkValid(\"sync\");if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return d;}e=c.file.pfd.Fsync();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return c.wrapErr(\"sync\",f);}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Sync};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Sync=function(){return this.$val.Sync();};DT.ptr.prototype.Chdir=function(){var c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=c.checkValid(\"chdir\");if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return d;}e=c.file.pfd.Fchdir();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return c.wrapErr(\"chdir\",f);}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Chdir};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Chdir=function(){return this.$val.Chdir();};DT.ptr.prototype.setDeadline=function(c){var c,d,e;d=this;e=d.checkValid(\"SetDeadline\");if(!($interfaceIsEqual(e,$ifaceNil))){return e;}return d.file.pfd.SetDeadline($clone(c,J.Time));};DT.prototype.setDeadline=function(c){return this.$val.setDeadline(c);};DT.ptr.prototype.setReadDeadline=function(c){var c,d,e;d=this;e=d.checkValid(\"SetReadDeadline\");if(!($interfaceIsEqual(e,$ifaceNil))){return e;}return d.file.pfd.SetReadDeadline($clone(c,J.Time));};DT.prototype.setReadDeadline=function(c){return this.$val.setReadDeadline(c);};DT.ptr.prototype.setWriteDeadline=function(c){var c,d,e;d=this;e=d.checkValid(\"SetWriteDeadline\");if(!($interfaceIsEqual(e,$ifaceNil))){return e;}return d.file.pfd.SetWriteDeadline($clone(c,J.Time));};DT.prototype.setWriteDeadline=function(c){return this.$val.setWriteDeadline(c);};DT.ptr.prototype.checkValid=function(c){var c,d;d=this;if(d===EB.nil){return $pkg.ErrInvalid;}return $ifaceNil;};DT.prototype.checkValid=function(c){return this.$val.checkValid(c);};BX=function(c){var c;return c;};DT.ptr.prototype.Fd=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(c===EB.nil){$s=-1;return 4294967295;}if(c.file.nonblock){$s=1;continue;}$s=2;continue;case 1:d=c.file.pfd.SetBlocking();$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}d;case 2:$s=-1;return((c.file.pfd.Sysfd>>>0));}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Fd};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Fd=function(){return this.$val.Fd();};CA=function(c,d){var c,d,e,f,g,h;e=0;f=K.IsNonblock(((c>>0)));g=f[0];h=f[1];if($interfaceIsEqual(h,$ifaceNil)&&g){e=3;}return CC(c,d,e);};$pkg.NewFile=CA;CC=function(c,d,e){var c,d,e,f,g,h,i,j,k,l,m,n;f=((c>>0));if(f<0){return EB.nil;}g=new DT.ptr(new BZ.ptr(new G.FD.ptr(new G.fdMutex.ptr(new $Uint64(0,0),0,0),f,new G.pollDesc.ptr(false),EU.nil,0,0,true,true,false),d,ED.nil,false,(f===1)||(f===2)));h=(e===1)||(e===2)||(e===3);if(e===1){i=new E.Stat_t.ptr(new $Uint64(0,0),new $Uint64(0,0),new $Uint64(0,0),0,0,0,0,new $Uint64(0,0),new $Int64(0,0),new $Int64(0,0),new $Int64(0,0),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),EV.zero());j=\"linux\";if(j===(\"freebsd\")){h=false;}else if(j===(\"dragonfly\")||j===(\"netbsd\")||j===(\"openbsd\")){k=E.Fstat(f,i);if($interfaceIsEqual(k,$ifaceNil)&&(((i.Mode&61440)>>>0)===32768)){h=false;}}else if(j===(\"darwin\")){l=E.Fstat(f,i);if($interfaceIsEqual(l,$ifaceNil)&&((((i.Mode&61440)>>>0)===4096)||(((i.Mode&61440)>>>0)===32768))){h=false;}}}m=g.file.pfd.Init(\"file\",h);if(!($interfaceIsEqual(m,$ifaceNil))){}else if(h){n=E.SetNonblock(f,true);if($interfaceIsEqual(n,$ifaceNil)){g.file.nonblock=true;}}D.SetFinalizer(g.file,new EX($methodExpr(EW,\"close\")));return g;};CD=function(c,d){var c,d;if($interfaceIsEqual(d,new E.Errno(32))&&c.file.stdoutOrErr){BQ();}};CE=function(c,d,e){var c,d,e,f,g,h,i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=false;if(false&&!(((d&64)===0))&&!((((e&1048576)>>>0)===0))){$s=1;continue;}$s=2;continue;case 1:h=DH(c);$s=3;case 3:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;i=g[1];if(AH(i)){f=true;}case 2:j=0;case 4:k=$ifaceNil;l=E.Open(c,d|524288,BS(e));j=l[0];k=l[1];if($interfaceIsEqual(k,$ifaceNil)){$s=5;continue;}if(false&&$interfaceIsEqual(k,new E.Errno(4))){$s=4;continue;}$s=-1;return[EB.nil,new AD.ptr(\"open\",c,k)];$s=4;continue;case 5:if(f){$s=6;continue;}$s=7;continue;case 6:m=BE(c);$s=8;case 8:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}m;case 7:if(false){E.CloseOnExec(j);}$s=-1;return[CC(((j>>>0)),c,1),$ifaceNil];}return;}if($f===undefined){$f={$blk:CE};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};DT.ptr.prototype.Close=function(){var c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(c===EB.nil){$s=-1;return $pkg.ErrInvalid;}d=c.file.close();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Close};}$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Close=function(){return this.$val.Close();};BZ.ptr.prototype.close=function(){var c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(c===EW.nil){$s=-1;return new E.Errno(22);}if(!(c.dirinfo===ED.nil)){c.dirinfo.close();}d=$ifaceNil;e=c.pfd.Close();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){if($interfaceIsEqual(f,G.ErrFileClosing)){f=$pkg.ErrClosed;}d=new AD.ptr(\"close\",c.name,f);}D.SetFinalizer(c,$ifaceNil);$s=-1;return d;}return;}if($f===undefined){$f={$blk:BZ.ptr.prototype.close};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};BZ.prototype.close=function(){return this.$val.close();};DT.ptr.prototype.read=function(c){var c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;f=this;h=f.file.pfd.Read(c);$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;d=g[0];e=g[1];D.KeepAlive(f);i=d;j=e;d=i;e=j;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.read};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.read=function(c){return this.$val.read(c);};DT.ptr.prototype.pread=function(c,d){var c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=0;f=$ifaceNil;g=this;i=g.file.pfd.Pread(c,d);$s=1;case 1:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;e=h[0];f=h[1];D.KeepAlive(g);j=e;k=f;e=j;f=k;$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.pread};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.pread=function(c,d){return this.$val.pread(c,d);};DT.ptr.prototype.write=function(c){var c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;f=this;h=f.file.pfd.Write(c);$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;d=g[0];e=g[1];D.KeepAlive(f);i=d;j=e;d=i;e=j;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.write};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.write=function(c){return this.$val.write(c);};DT.ptr.prototype.pwrite=function(c,d){var c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=0;f=$ifaceNil;g=this;i=g.file.pfd.Pwrite(c,d);$s=1;case 1:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;e=h[0];f=h[1];D.KeepAlive(g);j=e;k=f;e=j;f=k;$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.pwrite};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.pwrite=function(c,d){return this.$val.pwrite(c,d);};DT.ptr.prototype.seek=function(c,d){var c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=new $Int64(0,0);f=$ifaceNil;g=this;i=g.file.pfd.Seek(c,d);$s=1;case 1:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;e=h[0];f=h[1];D.KeepAlive(g);j=e;k=f;e=j;f=k;$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.seek};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.seek=function(c,d){return this.$val.seek(c,d);};DT.ptr.prototype.readdir=function(c){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=EC.nil;e=$ifaceNil;f=this;g=f.file.name;if(g===\"\"){g=\".\";}i=f.Readdirnames(c);$s=1;case 1:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;j=h[0];e=h[1];d=$makeSlice(EC,0,j.$length);k=j;l=0;case 2:if(!(l<k.$length)){$s=3;continue;}m=((l<0||l>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+l]);o=BJ(g+\"/\"+m);$s=4;case 4:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;p=n[0];q=n[1];if(AH(q)){l++;$s=2;continue;}if(!($interfaceIsEqual(q,$ifaceNil))){r=d;s=q;d=r;e=s;$s=-1;return[d,e];}d=$append(d,p);l++;$s=2;continue;case 3:if((d.$length===0)&&$interfaceIsEqual(e,$ifaceNil)&&c>0){e=C.EOF;}t=d;u=e;d=t;e=u;$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.readdir};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.readdir=function(c){return this.$val.readdir(c);};CR=function(c){var c,d;d=c.length-1>>0;while(true){if(!(d>0&&(c.charCodeAt(d)===47))){break;}c=$substring(c,0,d);d=d-(1)>>0;}d=d-(1)>>0;while(true){if(!(d>=0)){break;}if(c.charCodeAt(d)===47){c=$substring(c,(d+1>>0));break;}d=d-(1)>>0;}return c;};CV=function(){if(false){return;}$pkg.Args=L();};DB=function(c){var c;if(c===0){N();}E.Exit(c);};$pkg.Exit=DB;DC.ptr.prototype.Control=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.file.checkValid(\"SyscallConn.Control\");if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}f=d.file.file.pfd.RawControl(c);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;D.KeepAlive(d.file);$s=-1;return g;}return;}if($f===undefined){$f={$blk:DC.ptr.prototype.Control};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};DC.prototype.Control=function(c){return this.$val.Control(c);};DC.ptr.prototype.Read=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.file.checkValid(\"SyscallConn.Read\");if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}f=d.file.file.pfd.RawRead(c);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;D.KeepAlive(d.file);$s=-1;return g;}return;}if($f===undefined){$f={$blk:DC.ptr.prototype.Read};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};DC.prototype.Read=function(c){return this.$val.Read(c);};DC.ptr.prototype.Write=function(c){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.file.checkValid(\"SyscallConn.Write\");if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return e;}f=d.file.file.pfd.RawWrite(c);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;D.KeepAlive(d.file);$s=-1;return g;}return;}if($f===undefined){$f={$blk:DC.ptr.prototype.Write};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};DC.prototype.Write=function(c){return this.$val.Write(c);};DD=function(c){var c;return[new DC.ptr(c),$ifaceNil];};DH=function(c){var c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=F.Stat(c);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return DM(c);}return;}if($f===undefined){$f={$blk:DH};}$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Stat=DH;DI=function(c){var c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=F.Stat(c);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return DN(c);}return;}if($f===undefined){$f={$blk:DI};}$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Lstat=DI;DJ=function(c,d){var c,d,e;c.name=CR(d);c.size=c.sys.Size;J.Time.copy(c.modTime,DK($clone(c.sys.Mtim,E.Timespec)));c.mode=((((c.sys.Mode&511)>>>0)>>>0));e=(c.sys.Mode&61440)>>>0;if(e===(24576)){c.mode=(c.mode|(67108864))>>>0;}else if(e===(8192)){c.mode=(c.mode|(69206016))>>>0;}else if(e===(16384)){c.mode=(c.mode|(2147483648))>>>0;}else if(e===(4096)){c.mode=(c.mode|(33554432))>>>0;}else if(e===(40960)){c.mode=(c.mode|(134217728))>>>0;}else if(e===(32768)){}else if(e===(49152)){c.mode=(c.mode|(16777216))>>>0;}if(!((((c.sys.Mode&1024)>>>0)===0))){c.mode=(c.mode|(4194304))>>>0;}if(!((((c.sys.Mode&2048)>>>0)===0))){c.mode=(c.mode|(8388608))>>>0;}if(!((((c.sys.Mode&512)>>>0)===0))){c.mode=(c.mode|(1048576))>>>0;}};DK=function(c){var c;return J.Unix((c.Sec),(c.Nsec));};DT.ptr.prototype.Stat=function(){var c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];d=this;if(d===EB.nil){$s=-1;return[$ifaceNil,$pkg.ErrInvalid];}c[0]=new DX.ptr(\"\",new $Int64(0,0),0,new J.Time.ptr(new $Uint64(0,0),new $Int64(0,0),FB.nil),new E.Stat_t.ptr(new $Uint64(0,0),new $Uint64(0,0),new $Uint64(0,0),0,0,0,0,new $Uint64(0,0),new $Int64(0,0),new $Int64(0,0),new $Int64(0,0),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),EV.zero()));e=d.file.pfd.Fstat(c[0].sys);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[$ifaceNil,new AD.ptr(\"stat\",d.file.name,f)];}DJ(c[0],d.file.name);$s=-1;return[c[0],$ifaceNil];}return;}if($f===undefined){$f={$blk:DT.ptr.prototype.Stat};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};DT.prototype.Stat=function(){return this.$val.Stat();};DM=function(c){var c,d,e;d=new DX.ptr(\"\",new $Int64(0,0),0,new J.Time.ptr(new $Uint64(0,0),new $Int64(0,0),FB.nil),new E.Stat_t.ptr(new $Uint64(0,0),new $Uint64(0,0),new $Uint64(0,0),0,0,0,0,new $Uint64(0,0),new $Int64(0,0),new $Int64(0,0),new $Int64(0,0),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),EV.zero()));e=E.Stat(c,d.sys);if(!($interfaceIsEqual(e,$ifaceNil))){return[$ifaceNil,new AD.ptr(\"stat\",c,e)];}DJ(d,c);return[d,$ifaceNil];};DN=function(c){var c,d,e;d=new DX.ptr(\"\",new $Int64(0,0),0,new J.Time.ptr(new $Uint64(0,0),new $Int64(0,0),FB.nil),new E.Stat_t.ptr(new $Uint64(0,0),new $Uint64(0,0),new $Uint64(0,0),0,0,0,0,new $Uint64(0,0),new $Int64(0,0),new $Int64(0,0),new $Int64(0,0),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),new E.Timespec.ptr(new $Int64(0,0),new $Int64(0,0)),EV.zero()));e=E.Lstat(c,d.sys);if(!($interfaceIsEqual(e,$ifaceNil))){return[$ifaceNil,new AD.ptr(\"lstat\",c,e)];}DJ(d,c);return[d,$ifaceNil];};DV.prototype.String=function(){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;c=this.$val;d=FG.zero();e=0;f=\"dalTLDpSugct?\";g=0;while(true){if(!(g<f.length)){break;}h=$decodeRune(f,g);i=g;j=h[0];if(!((((c&(((k=(((31-i>>0)>>>0)),k<32?(1<<k):0)>>>0)))>>>0)===0))){((e<0||e>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[e]=((j<<24>>>24)));e=e+(1)>>0;}g+=h[1];}if(e===0){((e<0||e>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[e]=45);e=e+(1)>>0;}l=\"rwxrwxrwx\";m=0;while(true){if(!(m<l.length)){break;}n=$decodeRune(l,m);o=m;p=n[0];if(!((((c&(((q=(((8-o>>0)>>>0)),q<32?(1<<q):0)>>>0)))>>>0)===0))){((e<0||e>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[e]=((p<<24>>>24)));}else{((e<0||e>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[e]=45);}e=e+(1)>>0;m+=n[1];}return($bytesToString($subslice(new EE(d),0,e)));};$ptrType(DV).prototype.String=function(){return new DV(this.$get()).String();};DV.prototype.IsDir=function(){var c;c=this.$val;return!((((c&2147483648)>>>0)===0));};$ptrType(DV).prototype.IsDir=function(){return new DV(this.$get()).IsDir();};DV.prototype.IsRegular=function(){var c;c=this.$val;return((c&2401763328)>>>0)===0;};$ptrType(DV).prototype.IsRegular=function(){return new DV(this.$get()).IsRegular();};DV.prototype.Perm=function(){var c;c=this.$val;return(c&511)>>>0;};$ptrType(DV).prototype.Perm=function(){return new DV(this.$get()).Perm();};DX.ptr.prototype.Name=function(){var c;c=this;return c.name;};DX.prototype.Name=function(){return this.$val.Name();};DX.ptr.prototype.IsDir=function(){var c;c=this;return new DV(c.Mode()).IsDir();};DX.prototype.IsDir=function(){return this.$val.IsDir();};DX.ptr.prototype.Size=function(){var c;c=this;return c.size;};DX.prototype.Size=function(){return this.$val.Size();};DX.ptr.prototype.Mode=function(){var c;c=this;return c.mode;};DX.prototype.Mode=function(){return this.$val.Mode();};DX.ptr.prototype.ModTime=function(){var c;c=this;return c.modTime;};DX.prototype.ModTime=function(){return this.$val.ModTime();};DX.ptr.prototype.Sys=function(){var c;c=this;return c.sys;};DX.prototype.Sys=function(){return this.$val.Sys();};ED.methods=[{prop:\"close\",name:\"close\",pkg:\"os\",typ:$funcType([],[],false)}];EF.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)}];EH.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)}];EG.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];EW.methods=[{prop:\"close\",name:\"close\",pkg:\"os\",typ:$funcType([],[$error],false)}];FN.methods=[{prop:\"Control\",name:\"Control\",pkg:\"\",typ:$funcType([FL],[$error],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([FM],[$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([FM],[$error],false)}];EB.methods=[{prop:\"Readdir\",name:\"Readdir\",pkg:\"\",typ:$funcType([$Int],[EC,$error],false)},{prop:\"Readdirnames\",name:\"Readdirnames\",pkg:\"\",typ:$funcType([$Int],[EA,$error],false)},{prop:\"readdirnames\",name:\"readdirnames\",pkg:\"os\",typ:$funcType([$Int],[EA,$error],false)},{prop:\"Name\",name:\"Name\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([EE],[$Int,$error],false)},{prop:\"ReadAt\",name:\"ReadAt\",pkg:\"\",typ:$funcType([EE,$Int64],[$Int,$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([EE],[$Int,$error],false)},{prop:\"WriteAt\",name:\"WriteAt\",pkg:\"\",typ:$funcType([EE,$Int64],[$Int,$error],false)},{prop:\"Seek\",name:\"Seek\",pkg:\"\",typ:$funcType([$Int64,$Int],[$Int64,$error],false)},{prop:\"WriteString\",name:\"WriteString\",pkg:\"\",typ:$funcType([$String],[$Int,$error],false)},{prop:\"wrapErr\",name:\"wrapErr\",pkg:\"os\",typ:$funcType([$String,$error],[$error],false)},{prop:\"Chmod\",name:\"Chmod\",pkg:\"\",typ:$funcType([DV],[$error],false)},{prop:\"SetDeadline\",name:\"SetDeadline\",pkg:\"\",typ:$funcType([J.Time],[$error],false)},{prop:\"SetReadDeadline\",name:\"SetReadDeadline\",pkg:\"\",typ:$funcType([J.Time],[$error],false)},{prop:\"SetWriteDeadline\",name:\"SetWriteDeadline\",pkg:\"\",typ:$funcType([J.Time],[$error],false)},{prop:\"SyscallConn\",name:\"SyscallConn\",pkg:\"\",typ:$funcType([],[E.RawConn,$error],false)},{prop:\"chmod\",name:\"chmod\",pkg:\"os\",typ:$funcType([DV],[$error],false)},{prop:\"Chown\",name:\"Chown\",pkg:\"\",typ:$funcType([$Int,$Int],[$error],false)},{prop:\"Truncate\",name:\"Truncate\",pkg:\"\",typ:$funcType([$Int64],[$error],false)},{prop:\"Sync\",name:\"Sync\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Chdir\",name:\"Chdir\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"setDeadline\",name:\"setDeadline\",pkg:\"os\",typ:$funcType([J.Time],[$error],false)},{prop:\"setReadDeadline\",name:\"setReadDeadline\",pkg:\"os\",typ:$funcType([J.Time],[$error],false)},{prop:\"setWriteDeadline\",name:\"setWriteDeadline\",pkg:\"os\",typ:$funcType([J.Time],[$error],false)},{prop:\"checkValid\",name:\"checkValid\",pkg:\"os\",typ:$funcType([$String],[$error],false)},{prop:\"Fd\",name:\"Fd\",pkg:\"\",typ:$funcType([],[$Uintptr],false)},{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"read\",name:\"read\",pkg:\"os\",typ:$funcType([EE],[$Int,$error],false)},{prop:\"pread\",name:\"pread\",pkg:\"os\",typ:$funcType([EE,$Int64],[$Int,$error],false)},{prop:\"write\",name:\"write\",pkg:\"os\",typ:$funcType([EE],[$Int,$error],false)},{prop:\"pwrite\",name:\"pwrite\",pkg:\"os\",typ:$funcType([EE,$Int64],[$Int,$error],false)},{prop:\"seek\",name:\"seek\",pkg:\"os\",typ:$funcType([$Int64,$Int],[$Int64,$error],false)},{prop:\"readdir\",name:\"readdir\",pkg:\"os\",typ:$funcType([$Int],[EC,$error],false)},{prop:\"Stat\",name:\"Stat\",pkg:\"\",typ:$funcType([],[DU,$error],false)}];DV.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"IsDir\",name:\"IsDir\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsRegular\",name:\"IsRegular\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Perm\",name:\"Perm\",pkg:\"\",typ:$funcType([],[DV],false)}];FH.methods=[{prop:\"Name\",name:\"Name\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"IsDir\",name:\"IsDir\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Mode\",name:\"Mode\",pkg:\"\",typ:$funcType([],[DV],false)},{prop:\"ModTime\",name:\"ModTime\",pkg:\"\",typ:$funcType([],[J.Time],false)},{prop:\"Sys\",name:\"Sys\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)}];P.init(\"os\",[{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:EE,tag:\"\"},{prop:\"nbuf\",name:\"nbuf\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"bufp\",name:\"bufp\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);AC.init([{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)}]);AD.init(\"\",[{prop:\"Op\",name:\"Op\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Path\",name:\"Path\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$error,tag:\"\"}]);AE.init(\"\",[{prop:\"Syscall\",name:\"Syscall\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$error,tag:\"\"}]);BC.init(\"\",[{prop:\"Op\",name:\"Op\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Old\",name:\"Old\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"New\",name:\"New\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$error,tag:\"\"}]);BZ.init(\"os\",[{prop:\"pfd\",name:\"pfd\",embedded:false,exported:false,typ:G.FD,tag:\"\"},{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"dirinfo\",name:\"dirinfo\",embedded:false,exported:false,typ:ED,tag:\"\"},{prop:\"nonblock\",name:\"nonblock\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"stdoutOrErr\",name:\"stdoutOrErr\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);DC.init(\"os\",[{prop:\"file\",name:\"file\",embedded:false,exported:false,typ:EB,tag:\"\"}]);DT.init(\"os\",[{prop:\"file\",name:\"file\",embedded:true,exported:false,typ:EW,tag:\"\"}]);DU.init([{prop:\"IsDir\",name:\"IsDir\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"ModTime\",name:\"ModTime\",pkg:\"\",typ:$funcType([],[J.Time],false)},{prop:\"Mode\",name:\"Mode\",pkg:\"\",typ:$funcType([],[DV],false)},{prop:\"Name\",name:\"Name\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Sys\",name:\"Sys\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)}]);DX.init(\"os\",[{prop:\"name\",name:\"name\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"size\",name:\"size\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"mode\",name:\"mode\",embedded:false,exported:false,typ:DV,tag:\"\"},{prop:\"modTime\",name:\"modTime\",embedded:false,exported:false,typ:J.Time,tag:\"\"},{prop:\"sys\",name:\"sys\",embedded:false,exported:false,typ:E.Stat_t,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=K.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=I.$init();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=J.$init();$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.Args=EA.nil;$pkg.ErrInvalid=A.New(\"invalid argument\");$pkg.ErrPermission=A.New(\"permission denied\");$pkg.ErrExist=A.New(\"file already exists\");$pkg.ErrNotExist=A.New(\"file does not exist\");$pkg.ErrClosed=A.New(\"file already closed\");AZ=A.New(\"os: process already finished\");$pkg.Stdin=CA(((E.Stdin>>>0)),\"/dev/stdin\");$pkg.Stdout=CA(((E.Stdout>>>0)),\"/dev/stdout\");$pkg.Stderr=CA(((E.Stderr>>>0)),\"/dev/stderr\");BJ=DI;M();CV();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"fmt\"]=(function(){var $pkg={},$init,C,D,E,I,F,G,A,H,B,J,K,L,M,N,O,P,Q,AU,AV,AW,BI,BJ,BK,BL,BM,BN,BO,BP,BQ,BT,CO,CP,R,AX,BB,BD,BE,S,V,W,Z,AA,AB,AC,AD,AE,AF,AG,AH,AY,AZ,BF;C=$packages[\"errors\"];D=$packages[\"internal/fmtsort\"];E=$packages[\"io\"];I=$packages[\"math\"];F=$packages[\"os\"];G=$packages[\"reflect\"];A=$packages[\"strconv\"];H=$packages[\"sync\"];B=$packages[\"unicode/utf8\"];J=$pkg.fmtFlags=$newType(0,$kindStruct,\"fmt.fmtFlags\",true,\"fmt\",false,function(widPresent_,precPresent_,minus_,plus_,sharp_,space_,zero_,plusV_,sharpV_){this.$val=this;if(arguments.length===0){this.widPresent=false;this.precPresent=false;this.minus=false;this.plus=false;this.sharp=false;this.space=false;this.zero=false;this.plusV=false;this.sharpV=false;return;}this.widPresent=widPresent_;this.precPresent=precPresent_;this.minus=minus_;this.plus=plus_;this.sharp=sharp_;this.space=space_;this.zero=zero_;this.plusV=plusV_;this.sharpV=sharpV_;});K=$pkg.fmt=$newType(0,$kindStruct,\"fmt.fmt\",true,\"fmt\",false,function(buf_,fmtFlags_,wid_,prec_,intbuf_){this.$val=this;if(arguments.length===0){this.buf=BK.nil;this.fmtFlags=new J.ptr(false,false,false,false,false,false,false,false,false);this.wid=0;this.prec=0;this.intbuf=BL.zero();return;}this.buf=buf_;this.fmtFlags=fmtFlags_;this.wid=wid_;this.prec=prec_;this.intbuf=intbuf_;});L=$pkg.State=$newType(8,$kindInterface,\"fmt.State\",true,\"fmt\",true,null);M=$pkg.Formatter=$newType(8,$kindInterface,\"fmt.Formatter\",true,\"fmt\",true,null);N=$pkg.Stringer=$newType(8,$kindInterface,\"fmt.Stringer\",true,\"fmt\",true,null);O=$pkg.GoStringer=$newType(8,$kindInterface,\"fmt.GoStringer\",true,\"fmt\",true,null);P=$pkg.buffer=$newType(12,$kindSlice,\"fmt.buffer\",true,\"fmt\",false,null);Q=$pkg.pp=$newType(0,$kindStruct,\"fmt.pp\",true,\"fmt\",false,function(buf_,arg_,value_,fmt_,reordered_,goodArgNum_,panicking_,erroring_){this.$val=this;if(arguments.length===0){this.buf=P.nil;this.arg=$ifaceNil;this.value=new G.Value.ptr(BJ.nil,0,0);this.fmt=new K.ptr(BK.nil,new J.ptr(false,false,false,false,false,false,false,false,false),0,0,BL.zero());this.reordered=false;this.goodArgNum=false;this.panicking=false;this.erroring=false;return;}this.buf=buf_;this.arg=arg_;this.value=value_;this.fmt=fmt_;this.reordered=reordered_;this.goodArgNum=goodArgNum_;this.panicking=panicking_;this.erroring=erroring_;});AU=$pkg.scanError=$newType(0,$kindStruct,\"fmt.scanError\",true,\"fmt\",false,function(err_){this.$val=this;if(arguments.length===0){this.err=$ifaceNil;return;}this.err=err_;});AV=$pkg.ss=$newType(0,$kindStruct,\"fmt.ss\",true,\"fmt\",false,function(rs_,buf_,count_,atEOF_,ssave_){this.$val=this;if(arguments.length===0){this.rs=$ifaceNil;this.buf=P.nil;this.count=0;this.atEOF=false;this.ssave=new AW.ptr(false,false,false,0,0,0);return;}this.rs=rs_;this.buf=buf_;this.count=count_;this.atEOF=atEOF_;this.ssave=ssave_;});AW=$pkg.ssave=$newType(0,$kindStruct,\"fmt.ssave\",true,\"fmt\",false,function(validSave_,nlIsEnd_,nlIsSpace_,argLimit_,limit_,maxWid_){this.$val=this;if(arguments.length===0){this.validSave=false;this.nlIsEnd=false;this.nlIsSpace=false;this.argLimit=0;this.limit=0;this.maxWid=0;return;}this.validSave=validSave_;this.nlIsEnd=nlIsEnd_;this.nlIsSpace=nlIsSpace_;this.argLimit=argLimit_;this.limit=limit_;this.maxWid=maxWid_;});BI=$sliceType($emptyInterface);BJ=$ptrType(G.rtype);BK=$ptrType(P);BL=$arrayType($Uint8,68);BM=$arrayType($Uint16,2);BN=$sliceType(BM);BO=$sliceType($Uint8);BP=$arrayType($Uint8,5);BQ=$ptrType(Q);BT=$ptrType(AV);CO=$ptrType(K);CP=$funcType([$Int32],[$Bool],false);K.ptr.prototype.clearflags=function(){var a;a=this;J.copy(a.fmtFlags,new J.ptr(false,false,false,false,false,false,false,false,false));};K.prototype.clearflags=function(){return this.$val.clearflags();};K.ptr.prototype.init=function(a){var a,b;b=this;b.buf=a;b.clearflags();};K.prototype.init=function(a){return this.$val.init(a);};K.ptr.prototype.writePadding=function(a){var a,b,c,d,e,f,g,h,i,j;b=this;if(a<=0){return;}c=b.buf.$get();d=c.$length;e=d+a>>0;if(e>c.$capacity){c=$makeSlice(P,(($imul(c.$capacity,2))+a>>0));$copySlice(c,b.buf.$get());}f=32;if(b.fmtFlags.zero){f=48;}g=$subslice(c,d,e);h=g;i=0;while(true){if(!(i<h.$length)){break;}j=i;((j<0||j>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+j]=f);i++;}b.buf.$set($subslice(c,0,e));};K.prototype.writePadding=function(a){return this.$val.writePadding(a);};K.ptr.prototype.pad=function(a){var a,b,c;b=this;if(!b.fmtFlags.widPresent||(b.wid===0)){b.buf.Write(a);return;}c=b.wid-B.RuneCount(a)>>0;if(!b.fmtFlags.minus){b.writePadding(c);b.buf.Write(a);}else{b.buf.Write(a);b.writePadding(c);}};K.prototype.pad=function(a){return this.$val.pad(a);};K.ptr.prototype.padString=function(a){var a,b,c;b=this;if(!b.fmtFlags.widPresent||(b.wid===0)){b.buf.WriteString(a);return;}c=b.wid-B.RuneCountInString(a)>>0;if(!b.fmtFlags.minus){b.writePadding(c);b.buf.WriteString(a);}else{b.buf.WriteString(a);b.writePadding(c);}};K.prototype.padString=function(a){return this.$val.padString(a);};K.ptr.prototype.fmtBoolean=function(a){var a,b;b=this;if(a){b.padString(\"true\");}else{b.padString(\"false\");}};K.prototype.fmtBoolean=function(a){return this.$val.fmtBoolean(a);};K.ptr.prototype.fmtUnicode=function(a){var a,b,c,d,e,f,g;b=this;c=$subslice(new BO(b.intbuf),0);d=4;if(b.fmtFlags.precPresent&&b.prec>4){d=b.prec;e=(((2+d>>0)+2>>0)+4>>0)+1>>0;if(e>c.$length){c=$makeSlice(BO,e);}}f=c.$length;if(b.fmtFlags.sharp&&(a.$high<0||(a.$high===0&&a.$low<=1114111))&&A.IsPrint(((a.$low>>0)))){f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=39);f=f-(B.RuneLen(((a.$low>>0))))>>0;B.EncodeRune($subslice(c,f),((a.$low>>0)));f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=39);f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=32);}while(true){if(!((a.$high>0||(a.$high===0&&a.$low>=16)))){break;}f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=\"0123456789ABCDEFX\".charCodeAt($flatten64(new $Uint64(a.$high&0,(a.$low&15)>>>0))));d=d-(1)>>0;a=$shiftRightUint64(a,(4));}f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=\"0123456789ABCDEFX\".charCodeAt($flatten64(a)));d=d-(1)>>0;while(true){if(!(d>0)){break;}f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=48);d=d-(1)>>0;}f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=43);f=f-(1)>>0;((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=85);g=b.fmtFlags.zero;b.fmtFlags.zero=false;b.pad($subslice(c,f));b.fmtFlags.zero=g;};K.prototype.fmtUnicode=function(a){return this.$val.fmtUnicode(a);};K.ptr.prototype.fmtInteger=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;e=this;g=c&&(f=(new $Int64(a.$high,a.$low)),(f.$high<0||(f.$high===0&&f.$low<0)));if(g){a=new $Uint64(-a.$high,-a.$low);}h=$subslice(new BO(e.intbuf),0);if(e.fmtFlags.widPresent||e.fmtFlags.precPresent){i=(3+e.wid>>0)+e.prec>>0;if(i>h.$length){h=$makeSlice(BO,i);}}j=0;if(e.fmtFlags.precPresent){j=e.prec;if((j===0)&&(a.$high===0&&a.$low===0)){k=e.fmtFlags.zero;e.fmtFlags.zero=false;e.writePadding(e.wid);e.fmtFlags.zero=k;return;}}else if(e.fmtFlags.zero&&e.fmtFlags.widPresent){j=e.wid;if(g||e.fmtFlags.plus||e.fmtFlags.space){j=j-(1)>>0;}}l=h.$length;m=b;if(m===(10)){while(true){if(!((a.$high>0||(a.$high===0&&a.$low>=10)))){break;}l=l-(1)>>0;n=$div64(a,new $Uint64(0,10),false);((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=(((o=new $Uint64(0+a.$high,48+a.$low),p=$mul64(n,new $Uint64(0,10)),new $Uint64(o.$high-p.$high,o.$low-p.$low)).$low<<24>>>24)));a=n;}}else if(m===(16)){while(true){if(!((a.$high>0||(a.$high===0&&a.$low>=16)))){break;}l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=d.charCodeAt($flatten64(new $Uint64(a.$high&0,(a.$low&15)>>>0))));a=$shiftRightUint64(a,(4));}}else if(m===(8)){while(true){if(!((a.$high>0||(a.$high===0&&a.$low>=8)))){break;}l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=(((q=new $Uint64(a.$high&0,(a.$low&7)>>>0),new $Uint64(0+q.$high,48+q.$low)).$low<<24>>>24)));a=$shiftRightUint64(a,(3));}}else if(m===(2)){while(true){if(!((a.$high>0||(a.$high===0&&a.$low>=2)))){break;}l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=(((r=new $Uint64(a.$high&0,(a.$low&1)>>>0),new $Uint64(0+r.$high,48+r.$low)).$low<<24>>>24)));a=$shiftRightUint64(a,(1));}}else{$panic(new $String(\"fmt: unknown base; can't happen\"));}l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=d.charCodeAt($flatten64(a)));while(true){if(!(l>0&&j>(h.$length-l>>0))){break;}l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=48);}if(e.fmtFlags.sharp){s=b;if(s===(8)){if(!((((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l])===48))){l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=48);}}else if(s===(16)){l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=d.charCodeAt(16));l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=48);}}if(g){l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=45);}else if(e.fmtFlags.plus){l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=43);}else if(e.fmtFlags.space){l=l-(1)>>0;((l<0||l>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+l]=32);}t=e.fmtFlags.zero;e.fmtFlags.zero=false;e.pad($subslice(h,l));e.fmtFlags.zero=t;};K.prototype.fmtInteger=function(a,b,c,d){return this.$val.fmtInteger(a,b,c,d);};K.ptr.prototype.truncateString=function(a){var a,b,c,d,e,f,g;b=this;if(b.fmtFlags.precPresent){c=b.prec;d=a;e=0;while(true){if(!(e<d.length)){break;}f=$decodeRune(d,e);g=e;c=c-(1)>>0;if(c<0){return $substring(a,0,g);}e+=f[1];}}return a;};K.prototype.truncateString=function(a){return this.$val.truncateString(a);};K.ptr.prototype.truncate=function(a){var a,b,c,d,e,f;b=this;if(b.fmtFlags.precPresent){c=b.prec;d=0;while(true){if(!(d<a.$length)){break;}c=c-(1)>>0;if(c<0){return $subslice(a,0,d);}e=1;if(((d<0||d>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+d])>=128){f=B.DecodeRune($subslice(a,d));e=f[1];}d=d+(e)>>0;}}return a;};K.prototype.truncate=function(a){return this.$val.truncate(a);};K.ptr.prototype.fmtS=function(a){var a,b;b=this;a=b.truncateString(a);b.padString(a);};K.prototype.fmtS=function(a){return this.$val.fmtS(a);};K.ptr.prototype.fmtBs=function(a){var a,b;b=this;a=b.truncate(a);b.pad(a);};K.prototype.fmtBs=function(a){return this.$val.fmtBs(a);};K.ptr.prototype.fmtSbx=function(a,b,c){var a,b,c,d,e,f,g,h,i;d=this;e=b.$length;if(b===BO.nil){e=a.length;}if(d.fmtFlags.precPresent&&d.prec<e){e=d.prec;}f=$imul(2,e);if(f>0){if(d.fmtFlags.space){if(d.fmtFlags.sharp){f=$imul(f,(2));}f=f+((e-1>>0))>>0;}else if(d.fmtFlags.sharp){f=f+(2)>>0;}}else{if(d.fmtFlags.widPresent){d.writePadding(d.wid);}return;}if(d.fmtFlags.widPresent&&d.wid>f&&!d.fmtFlags.minus){d.writePadding(d.wid-f>>0);}g=d.buf.$get();if(d.fmtFlags.sharp){g=$append(g,48,c.charCodeAt(16));}h=0;i=0;while(true){if(!(i<e)){break;}if(d.fmtFlags.space&&i>0){g=$append(g,32);if(d.fmtFlags.sharp){g=$append(g,48,c.charCodeAt(16));}}if(!(b===BO.nil)){h=((i<0||i>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+i]);}else{h=a.charCodeAt(i);}g=$append(g,c.charCodeAt((h>>>4<<24>>>24)),c.charCodeAt(((h&15)>>>0)));i=i+(1)>>0;}d.buf.$set(g);if(d.fmtFlags.widPresent&&d.wid>f&&d.fmtFlags.minus){d.writePadding(d.wid-f>>0);}};K.prototype.fmtSbx=function(a,b,c){return this.$val.fmtSbx(a,b,c);};K.ptr.prototype.fmtSx=function(a,b){var a,b,c;c=this;c.fmtSbx(a,BO.nil,b);};K.prototype.fmtSx=function(a,b){return this.$val.fmtSx(a,b);};K.ptr.prototype.fmtBx=function(a,b){var a,b,c;c=this;c.fmtSbx(\"\",a,b);};K.prototype.fmtBx=function(a,b){return this.$val.fmtBx(a,b);};K.ptr.prototype.fmtQ=function(a){var a,b,c;b=this;a=b.truncateString(a);if(b.fmtFlags.sharp&&A.CanBackquote(a)){b.padString(\"`\"+a+\"`\");return;}c=$subslice(new BO(b.intbuf),0,0);if(b.fmtFlags.plus){b.pad(A.AppendQuoteToASCII(c,a));}else{b.pad(A.AppendQuote(c,a));}};K.prototype.fmtQ=function(a){return this.$val.fmtQ(a);};K.ptr.prototype.fmtC=function(a){var a,b,c,d,e;b=this;c=((a.$low>>0));if((a.$high>0||(a.$high===0&&a.$low>1114111))){c=65533;}d=$subslice(new BO(b.intbuf),0,0);e=B.EncodeRune($subslice(d,0,4),c);b.pad($subslice(d,0,e));};K.prototype.fmtC=function(a){return this.$val.fmtC(a);};K.ptr.prototype.fmtQc=function(a){var a,b,c,d;b=this;c=((a.$low>>0));if((a.$high>0||(a.$high===0&&a.$low>1114111))){c=65533;}d=$subslice(new BO(b.intbuf),0,0);if(b.fmtFlags.plus){b.pad(A.AppendQuoteRuneToASCII(d,c));}else{b.pad(A.AppendQuoteRune(d,c));}};K.prototype.fmtQc=function(a){return this.$val.fmtQc(a);};K.ptr.prototype.fmtFloat=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n;e=this;if(e.fmtFlags.precPresent){d=e.prec;}f=A.AppendFloat($subslice(new BO(e.intbuf),0,1),a,((c<<24>>>24)),d,b);if(((1>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+1])===45)||((1>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+1])===43)){f=$subslice(f,1);}else{(0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0]=43);}if(e.fmtFlags.space&&((0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0])===43)&&!e.fmtFlags.plus){(0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0]=32);}if(((1>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+1])===73)||((1>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+1])===78)){g=e.fmtFlags.zero;e.fmtFlags.zero=false;if(((1>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+1])===78)&&!e.fmtFlags.space&&!e.fmtFlags.plus){f=$subslice(f,1);}e.pad(f);e.fmtFlags.zero=g;return;}if(e.fmtFlags.sharp&&!((c===98))){h=0;i=c;if((i===(118))||(i===(103))||(i===(71))){h=d;if(h===-1){h=6;}}j=BP.zero();k=$subslice(new BO(j),0,0);l=false;m=1;while(true){if(!(m<f.$length)){break;}n=((m<0||m>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+m]);if(n===(46)){l=true;}else if((n===(101))||(n===(69))){k=$appendSlice(k,$subslice(f,m));f=$subslice(f,0,m);}else{h=h-(1)>>0;}m=m+(1)>>0;}if(!l){f=$append(f,46);}while(true){if(!(h>0)){break;}f=$append(f,48);h=h-(1)>>0;}f=$appendSlice(f,k);}if(e.fmtFlags.plus||!(((0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0])===43))){if(e.fmtFlags.zero&&e.fmtFlags.widPresent&&e.wid>f.$length){e.buf.WriteByte((0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0]));e.writePadding(e.wid-f.$length>>0);e.buf.Write($subslice(f,1));return;}e.pad(f);return;}e.pad($subslice(f,1));};K.prototype.fmtFloat=function(a,b,c,d){return this.$val.fmtFloat(a,b,c,d);};$ptrType(P).prototype.Write=function(a){var a,b;b=this;b.$set($appendSlice(b.$get(),a));};$ptrType(P).prototype.WriteString=function(a){var a,b;b=this;b.$set($appendSlice(b.$get(),a));};$ptrType(P).prototype.WriteByte=function(a){var a,b;b=this;b.$set($append(b.$get(),a));};$ptrType(P).prototype.WriteRune=function(a){var a,b,c,d,e,f;b=this;if(a<128){b.$set($append(b.$get(),((a<<24>>>24))));return;}c=b.$get();d=c.$length;while(true){if(!((d+4>>0)>c.$capacity)){break;}c=$append(c,0);}f=B.EncodeRune((e=$subslice(c,d,(d+4>>0)),$subslice(new BO(e.$array),e.$offset,e.$offset+e.$length)),a);b.$set($subslice(c,0,(d+f>>0)));};S=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=R.Get();$s=1;case 1:if($c){$c=false;a=a.$blk();}if(a&&a.$blk!==undefined){break s;}b=$assertType(a,BQ);b.panicking=false;b.erroring=false;b.fmt.init((b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))));$s=-1;return b;}return;}if($f===undefined){$f={$blk:S};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};Q.ptr.prototype.free=function(){var a;a=this;if(a.buf.$capacity>65536){return;}a.buf=$subslice(a.buf,0,0);a.arg=$ifaceNil;a.value=new G.Value.ptr(BJ.nil,0,0);R.Put(a);};Q.prototype.free=function(){return this.$val.free();};Q.ptr.prototype.Width=function(){var a,b,c,d,e;a=0;b=false;c=this;d=c.fmt.wid;e=c.fmt.fmtFlags.widPresent;a=d;b=e;return[a,b];};Q.prototype.Width=function(){return this.$val.Width();};Q.ptr.prototype.Precision=function(){var a,b,c,d,e;a=0;b=false;c=this;d=c.fmt.prec;e=c.fmt.fmtFlags.precPresent;a=d;b=e;return[a,b];};Q.prototype.Precision=function(){return this.$val.Precision();};Q.ptr.prototype.Flag=function(a){var a,b,c;b=this;c=a;if(c===(45)){return b.fmt.fmtFlags.minus;}else if(c===(43)){return b.fmt.fmtFlags.plus||b.fmt.fmtFlags.plusV;}else if(c===(35)){return b.fmt.fmtFlags.sharp||b.fmt.fmtFlags.sharpV;}else if(c===(32)){return b.fmt.fmtFlags.space;}else if(c===(48)){return b.fmt.fmtFlags.zero;}return false;};Q.prototype.Flag=function(a){return this.$val.Flag(a);};Q.ptr.prototype.Write=function(a){var a,b,c,d,e,f;b=0;c=$ifaceNil;d=this;(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).Write(a);e=a.$length;f=$ifaceNil;b=e;c=f;return[b,c];};Q.prototype.Write=function(a){return this.$val.Write(a);};Q.ptr.prototype.WriteString=function(a){var a,b,c,d,e,f;b=0;c=$ifaceNil;d=this;(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(a);e=a.length;f=$ifaceNil;b=e;c=f;return[b,c];};Q.prototype.WriteString=function(a){return this.$val.WriteString(a);};V=function(a,b){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=S();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;$r=d.doPrintf(a,b);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=($bytesToString(d.buf));d.free();$s=-1;return e;}return;}if($f===undefined){$f={$blk:V};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Sprintf=V;W=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=V(a,b);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=C.New(c);$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:W};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Errorf=W;Z=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=S();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;$r=c.doPrint(a);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=($bytesToString(c.buf));c.free();$s=-1;return d;}return;}if($f===undefined){$f={$blk:Z};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Sprint=Z;AA=function(a,b){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=0;d=$ifaceNil;e=S();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;$r=f.doPrintln(b);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=a.Write((h=f.buf,$subslice(new BO(h.$array),h.$offset,h.$offset+h.$length)));$s=3;case 3:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}g=i;c=g[0];d=g[1];f.free();$s=-1;return[c,d];}return;}if($f===undefined){$f={$blk:AA};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Fprintln=AA;AB=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;e=AA(F.Stdout,a);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;b=d[0];c=d[1];$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AB};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Println=AB;AC=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=S();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;$r=c.doPrintln(a);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=($bytesToString(c.buf));c.free();$s=-1;return d;}return;}if($f===undefined){$f={$blk:AC};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Sprintln=AC;AD=function(a,b){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=$clone(a,G.Value).Field(b);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;if(($clone(d,G.Value).Kind()===20)&&!$clone(d,G.Value).IsNil()){$s=2;continue;}$s=3;continue;case 2:e=$clone(d,G.Value).Elem();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;case 3:$s=-1;return d;}return;}if($f===undefined){$f={$blk:AD};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AE=function(a){var a;return a>1000000||a<-1000000;};AF=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l;d=0;e=false;f=0;if(b>=c){g=0;h=false;i=c;d=g;e=h;f=i;return[d,e,f];}f=b;while(true){if(!(f<c&&48<=a.charCodeAt(f)&&a.charCodeAt(f)<=57)){break;}if(AE(d)){j=0;k=false;l=c;d=j;e=k;f=l;return[d,e,f];}d=($imul(d,10))+(((a.charCodeAt(f)-48<<24>>>24)>>0))>>0;e=true;f=f+(1)>>0;}return[d,e,f];};Q.ptr.prototype.unknownType=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(!$clone(a,G.Value).IsValid()){(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"<nil>\");$s=-1;return;}(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(63);c=$clone(a,G.Value).Type().String();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$r=(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(c);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(63);$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.unknownType};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.unknownType=function(a){return this.$val.unknownType(a);};Q.ptr.prototype.badVerb=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;b.erroring=true;(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"%!\");(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteRune(a);(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(40);if(!($interfaceIsEqual(b.arg,$ifaceNil))){$s=2;continue;}if($clone(b.value,G.Value).IsValid()){$s=3;continue;}$s=4;continue;case 2:c=G.TypeOf(b.arg).String();$s=6;case 6:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$r=(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(c);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(61);$r=b.printArg(b.arg,118);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=5;continue;case 3:d=$clone(b.value,G.Value).Type().String();$s=9;case 9:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$r=(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(d);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(61);$r=b.printValue($clone(b.value,G.Value),118,0);$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=5;continue;case 4:(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"<nil>\");case 5:case 1:(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(41);b.erroring=false;$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.badVerb};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.badVerb=function(a){return this.$val.badVerb(a);};Q.ptr.prototype.fmtBool=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=b;if((d===(116))||(d===(118))){$s=2;continue;}$s=3;continue;case 2:c.fmt.fmtBoolean(a);$s=4;continue;case 3:$r=c.badVerb(b);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 4:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtBool};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtBool=function(a,b){return this.$val.fmtBool(a,b);};Q.ptr.prototype.fmt0x64=function(a,b){var a,b,c,d;c=this;d=c.fmt.fmtFlags.sharp;c.fmt.fmtFlags.sharp=b;c.fmt.fmtInteger(a,16,false,\"0123456789abcdefx\");c.fmt.fmtFlags.sharp=d;};Q.prototype.fmt0x64=function(a,b){return this.$val.fmt0x64(a,b);};Q.ptr.prototype.fmtInteger=function(a,b,c){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=c;if(e===(118)){$s=2;continue;}if(e===(100)){$s=3;continue;}if(e===(98)){$s=4;continue;}if(e===(111)){$s=5;continue;}if(e===(120)){$s=6;continue;}if(e===(88)){$s=7;continue;}if(e===(99)){$s=8;continue;}if(e===(113)){$s=9;continue;}if(e===(85)){$s=10;continue;}$s=11;continue;case 2:if(d.fmt.fmtFlags.sharpV&&!b){d.fmt0x64(a,true);}else{d.fmt.fmtInteger(a,10,b,\"0123456789abcdefx\");}$s=12;continue;case 3:d.fmt.fmtInteger(a,10,b,\"0123456789abcdefx\");$s=12;continue;case 4:d.fmt.fmtInteger(a,2,b,\"0123456789abcdefx\");$s=12;continue;case 5:d.fmt.fmtInteger(a,8,b,\"0123456789abcdefx\");$s=12;continue;case 6:d.fmt.fmtInteger(a,16,b,\"0123456789abcdefx\");$s=12;continue;case 7:d.fmt.fmtInteger(a,16,b,\"0123456789ABCDEFX\");$s=12;continue;case 8:d.fmt.fmtC(a);$s=12;continue;case 9:if((a.$high<0||(a.$high===0&&a.$low<=1114111))){$s=13;continue;}$s=14;continue;case 13:d.fmt.fmtQc(a);$s=15;continue;case 14:$r=d.badVerb(c);$s=16;case 16:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 15:$s=12;continue;case 10:d.fmt.fmtUnicode(a);$s=12;continue;case 11:$r=d.badVerb(c);$s=17;case 17:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 12:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtInteger};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtInteger=function(a,b,c){return this.$val.fmtInteger(a,b,c);};Q.ptr.prototype.fmtFloat=function(a,b,c){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=c;if(e===(118)){$s=2;continue;}if((e===(98))||(e===(103))||(e===(71))){$s=3;continue;}if((e===(102))||(e===(101))||(e===(69))){$s=4;continue;}if(e===(70)){$s=5;continue;}$s=6;continue;case 2:d.fmt.fmtFloat(a,b,103,-1);$s=7;continue;case 3:d.fmt.fmtFloat(a,b,c,-1);$s=7;continue;case 4:d.fmt.fmtFloat(a,b,c,6);$s=7;continue;case 5:d.fmt.fmtFloat(a,b,102,6);$s=7;continue;case 6:$r=d.badVerb(c);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 7:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtFloat};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtFloat=function(a,b,c){return this.$val.fmtFloat(a,b,c);};Q.ptr.prototype.fmtComplex=function(a,b,c){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=c;if((e===(118))||(e===(98))||(e===(103))||(e===(71))||(e===(102))||(e===(70))||(e===(101))||(e===(69))){$s=2;continue;}$s=3;continue;case 2:f=d.fmt.fmtFlags.plus;(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(40);$r=d.fmtFloat(a.$real,(g=b/2,(g===g&&g!==1/0&&g!==-1/0)?g>>0:$throwRuntimeError(\"integer divide by zero\")),c);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d.fmt.fmtFlags.plus=true;$r=d.fmtFloat(a.$imag,(h=b/2,(h===h&&h!==1/0&&h!==-1/0)?h>>0:$throwRuntimeError(\"integer divide by zero\")),c);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"i)\");d.fmt.fmtFlags.plus=f;$s=4;continue;case 3:$r=d.badVerb(c);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 4:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtComplex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtComplex=function(a,b,c){return this.$val.fmtComplex(a,b,c);};Q.ptr.prototype.fmtString=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=b;if(d===(118)){$s=2;continue;}if(d===(115)){$s=3;continue;}if(d===(120)){$s=4;continue;}if(d===(88)){$s=5;continue;}if(d===(113)){$s=6;continue;}$s=7;continue;case 2:if(c.fmt.fmtFlags.sharpV){c.fmt.fmtQ(a);}else{c.fmt.fmtS(a);}$s=8;continue;case 3:c.fmt.fmtS(a);$s=8;continue;case 4:c.fmt.fmtSx(a,\"0123456789abcdefx\");$s=8;continue;case 5:c.fmt.fmtSx(a,\"0123456789ABCDEFX\");$s=8;continue;case 6:c.fmt.fmtQ(a);$s=8;continue;case 7:$r=c.badVerb(b);$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 8:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtString};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtString=function(a,b){return this.$val.fmtString(a,b);};Q.ptr.prototype.fmtBytes=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=b;if((e===(118))||(e===(100))){$s=2;continue;}if(e===(115)){$s=3;continue;}if(e===(120)){$s=4;continue;}if(e===(88)){$s=5;continue;}if(e===(113)){$s=6;continue;}$s=7;continue;case 2:if(d.fmt.fmtFlags.sharpV){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(c);if(a===BO.nil){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"(nil)\");$s=-1;return;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(123);f=a;g=0;while(true){if(!(g<f.$length)){break;}h=g;i=((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]);if(h>0){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\", \");}d.fmt0x64((new $Uint64(0,i)),true);g++;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(125);}else{(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(91);j=a;k=0;while(true){if(!(k<j.$length)){break;}l=k;m=((k<0||k>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+k]);if(l>0){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(32);}d.fmt.fmtInteger((new $Uint64(0,m)),10,false,\"0123456789abcdefx\");k++;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(93);}$s=8;continue;case 3:d.fmt.fmtBs(a);$s=8;continue;case 4:d.fmt.fmtBx(a,\"0123456789abcdefx\");$s=8;continue;case 5:d.fmt.fmtBx(a,\"0123456789ABCDEFX\");$s=8;continue;case 6:d.fmt.fmtQ(($bytesToString(a)));$s=8;continue;case 7:n=G.ValueOf(a);$s=9;case 9:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}$r=d.printValue($clone(n,G.Value),b,0);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 8:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtBytes};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtBytes=function(a,b,c){return this.$val.fmtBytes(a,b,c);};Q.ptr.prototype.fmtPointer=function(a,b){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=0;e=$clone(a,G.Value).Kind();if((e===(18))||(e===(19))||(e===(21))||(e===(22))||(e===(23))||(e===(26))){$s=2;continue;}$s=3;continue;case 2:d=$clone(a,G.Value).Pointer();$s=4;continue;case 3:$r=c.badVerb(b);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 4:case 1:f=b;if(f===(118)){$s=7;continue;}if(f===(112)){$s=8;continue;}if((f===(98))||(f===(111))||(f===(100))||(f===(120))||(f===(88))){$s=9;continue;}$s=10;continue;case 7:if(c.fmt.fmtFlags.sharpV){$s=12;continue;}$s=13;continue;case 12:(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteByte(40);g=$clone(a,G.Value).Type().String();$s=15;case 15:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}$r=(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(g);$s=16;case 16:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\")(\");if(d===0){(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\"nil\");}else{c.fmt0x64((new $Uint64(0,d.constructor===Number?d:1)),true);}(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteByte(41);$s=14;continue;case 13:if(d===0){c.fmt.padString(\"<nil>\");}else{c.fmt0x64((new $Uint64(0,d.constructor===Number?d:1)),!c.fmt.fmtFlags.sharp);}case 14:$s=11;continue;case 8:c.fmt0x64((new $Uint64(0,d.constructor===Number?d:1)),!c.fmt.fmtFlags.sharp);$s=11;continue;case 9:$r=c.fmtInteger((new $Uint64(0,d.constructor===Number?d:1)),false,b);$s=17;case 17:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=11;continue;case 10:$r=c.badVerb(b);$s=18;case 18:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 11:case 6:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.fmtPointer};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.fmtPointer=function(a,b){return this.$val.fmtPointer(a,b);};Q.ptr.prototype.catchPanic=function(a,b,c){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=$recover();if(!($interfaceIsEqual(e,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:f=G.ValueOf(a);$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if(($clone(g,G.Value).Kind()===22)&&$clone(g,G.Value).IsNil()){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"<nil>\");$s=-1;return;}if(d.panicking){$panic(e);}h=$clone(d.fmt.fmtFlags,J);d.fmt.clearflags();(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"%!\");(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteRune(b);(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"(PANIC=\");(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(c);(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\" method: \");d.panicking=true;$r=d.printArg(e,118);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d.panicking=false;(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(41);J.copy(d.fmt.fmtFlags,h);case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.catchPanic};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.catchPanic=function(a,b,c){return this.$val.catchPanic(a,b,c);};Q.ptr.prototype.handleMethods=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=false;c=this;if(c.erroring){$s=-1;return b;}d=$assertType(c.arg,M,true);e=d[0];f=d[1];if(f){$s=1;continue;}$s=2;continue;case 1:b=true;$deferred.push([$methodVal(c,\"catchPanic\"),[c.arg,a,\"Format\"]]);$r=e.Format(c,a);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return b;case 2:if(c.fmt.fmtFlags.sharpV){$s=4;continue;}$s=5;continue;case 4:g=$assertType(c.arg,O,true);h=g[0];i=g[1];if(i){$s=7;continue;}$s=8;continue;case 7:b=true;$deferred.push([$methodVal(c,\"catchPanic\"),[c.arg,a,\"GoString\"]]);j=h.GoString();$s=9;case 9:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}$r=c.fmt.fmtS(j);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return b;case 8:$s=6;continue;case 5:k=a;if((k===(118))||(k===(115))||(k===(120))||(k===(88))||(k===(113))){$s=12;continue;}$s=13;continue;case 12:l=c.arg;if($assertType(l,$error,true)[1]){$s=14;continue;}if($assertType(l,N,true)[1]){$s=15;continue;}$s=16;continue;case 14:m=l;b=true;$deferred.push([$methodVal(c,\"catchPanic\"),[c.arg,a,\"Error\"]]);o=m.Error();$s=17;case 17:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}$r=c.fmtString(o,a);$s=18;case 18:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return b;case 15:n=l;b=true;$deferred.push([$methodVal(c,\"catchPanic\"),[c.arg,a,\"String\"]]);p=n.String();$s=19;case 19:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}$r=c.fmtString(p,a);$s=20;case 20:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return b;case 16:case 13:case 11:case 6:b=false;$s=-1;return b;}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return b;}if($curGoroutine.asleep){if($f===undefined){$f={$blk:Q.ptr.prototype.handleMethods};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};Q.prototype.handleMethods=function(a){return this.$val.handleMethods(a);};Q.ptr.prototype.printArg=function(a,b){var a,aa,ab,ac,ad,ae,af,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;c.arg=a;c.value=new G.Value.ptr(BJ.nil,0,0);if($interfaceIsEqual(a,$ifaceNil)){$s=1;continue;}$s=2;continue;case 1:d=b;if((d===(84))||(d===(118))){$s=4;continue;}$s=5;continue;case 4:c.fmt.padString(\"<nil>\");$s=6;continue;case 5:$r=c.badVerb(b);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 6:case 3:$s=-1;return;case 2:e=b;if(e===(84)){$s=9;continue;}if(e===(112)){$s=10;continue;}$s=11;continue;case 9:f=G.TypeOf(a).String();$s=12;case 12:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$r=c.fmt.fmtS(f);$s=13;case 13:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 10:g=G.ValueOf(a);$s=14;case 14:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}$r=c.fmtPointer($clone(g,G.Value),112);$s=15;case 15:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 11:case 8:h=a;if($assertType(h,$Bool,true)[1]){$s=16;continue;}if($assertType(h,$Float32,true)[1]){$s=17;continue;}if($assertType(h,$Float64,true)[1]){$s=18;continue;}if($assertType(h,$Complex64,true)[1]){$s=19;continue;}if($assertType(h,$Complex128,true)[1]){$s=20;continue;}if($assertType(h,$Int,true)[1]){$s=21;continue;}if($assertType(h,$Int8,true)[1]){$s=22;continue;}if($assertType(h,$Int16,true)[1]){$s=23;continue;}if($assertType(h,$Int32,true)[1]){$s=24;continue;}if($assertType(h,$Int64,true)[1]){$s=25;continue;}if($assertType(h,$Uint,true)[1]){$s=26;continue;}if($assertType(h,$Uint8,true)[1]){$s=27;continue;}if($assertType(h,$Uint16,true)[1]){$s=28;continue;}if($assertType(h,$Uint32,true)[1]){$s=29;continue;}if($assertType(h,$Uint64,true)[1]){$s=30;continue;}if($assertType(h,$Uintptr,true)[1]){$s=31;continue;}if($assertType(h,$String,true)[1]){$s=32;continue;}if($assertType(h,BO,true)[1]){$s=33;continue;}if($assertType(h,G.Value,true)[1]){$s=34;continue;}$s=35;continue;case 16:i=h.$val;$r=c.fmtBool(i,b);$s=37;case 37:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 17:j=h.$val;$r=c.fmtFloat((j),32,b);$s=38;case 38:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 18:k=h.$val;$r=c.fmtFloat(k,64,b);$s=39;case 39:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 19:l=h.$val;$r=c.fmtComplex((new $Complex128(l.$real,l.$imag)),64,b);$s=40;case 40:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 20:m=h.$val;$r=c.fmtComplex(m,128,b);$s=41;case 41:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 21:n=h.$val;$r=c.fmtInteger((new $Uint64(0,n)),true,b);$s=42;case 42:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 22:o=h.$val;$r=c.fmtInteger((new $Uint64(0,o)),true,b);$s=43;case 43:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 23:p=h.$val;$r=c.fmtInteger((new $Uint64(0,p)),true,b);$s=44;case 44:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 24:q=h.$val;$r=c.fmtInteger((new $Uint64(0,q)),true,b);$s=45;case 45:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 25:r=h.$val;$r=c.fmtInteger((new $Uint64(r.$high,r.$low)),true,b);$s=46;case 46:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 26:s=h.$val;$r=c.fmtInteger((new $Uint64(0,s)),false,b);$s=47;case 47:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 27:t=h.$val;$r=c.fmtInteger((new $Uint64(0,t)),false,b);$s=48;case 48:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 28:u=h.$val;$r=c.fmtInteger((new $Uint64(0,u)),false,b);$s=49;case 49:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 29:v=h.$val;$r=c.fmtInteger((new $Uint64(0,v)),false,b);$s=50;case 50:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 30:w=h.$val;$r=c.fmtInteger(w,false,b);$s=51;case 51:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 31:x=h.$val;$r=c.fmtInteger((new $Uint64(0,x.constructor===Number?x:1)),false,b);$s=52;case 52:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 32:y=h.$val;$r=c.fmtString(y,b);$s=53;case 53:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 33:z=h.$val;$r=c.fmtBytes(z,b,\"[]byte\");$s=54;case 54:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 34:aa=h.$val;if($clone(aa,G.Value).IsValid()&&$clone(aa,G.Value).CanInterface()){$s=55;continue;}$s=56;continue;case 55:ac=$clone(aa,G.Value).Interface();$s=57;case 57:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}c.arg=ac;ad=c.handleMethods(b);$s=60;case 60:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}if(ad){$s=58;continue;}$s=59;continue;case 58:$s=-1;return;case 59:case 56:$r=c.printValue($clone(aa,G.Value),b,0);$s=61;case 61:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=36;continue;case 35:ab=h;ae=c.handleMethods(b);$s=64;case 64:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}if(!ae){$s=62;continue;}$s=63;continue;case 62:af=G.ValueOf(ab);$s=65;case 65:if($c){$c=false;af=af.$blk();}if(af&&af.$blk!==undefined){break s;}$r=c.printValue($clone(af,G.Value),b,0);$s=66;case 66:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 63:case 36:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.printArg};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.printArg=function(a,b){return this.$val.printArg(a,b);};Q.ptr.prototype.printValue=function(a,b,c){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;if(c>0&&$clone(a,G.Value).IsValid()&&$clone(a,G.Value).CanInterface()){$s=1;continue;}$s=2;continue;case 1:e=$clone(a,G.Value).Interface();$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d.arg=e;f=d.handleMethods(b);$s=6;case 6:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}if(f){$s=4;continue;}$s=5;continue;case 4:$s=-1;return;case 5:case 2:d.arg=$ifaceNil;d.value=a;g=a;h=$clone(a,G.Value).Kind();if(h===(0)){$s=8;continue;}if(h===(1)){$s=9;continue;}if((h===(2))||(h===(3))||(h===(4))||(h===(5))||(h===(6))){$s=10;continue;}if((h===(7))||(h===(8))||(h===(9))||(h===(10))||(h===(11))||(h===(12))){$s=11;continue;}if(h===(13)){$s=12;continue;}if(h===(14)){$s=13;continue;}if(h===(15)){$s=14;continue;}if(h===(16)){$s=15;continue;}if(h===(24)){$s=16;continue;}if(h===(21)){$s=17;continue;}if(h===(25)){$s=18;continue;}if(h===(20)){$s=19;continue;}if((h===(17))||(h===(23))){$s=20;continue;}if(h===(22)){$s=21;continue;}if((h===(18))||(h===(19))||(h===(26))){$s=22;continue;}$s=23;continue;case 8:if(c===0){$s=25;continue;}$s=26;continue;case 25:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"<invalid reflect.Value>\");$s=27;continue;case 26:i=b;if(i===(118)){$s=29;continue;}$s=30;continue;case 29:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"<nil>\");$s=31;continue;case 30:$r=d.badVerb(b);$s=32;case 32:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 31:case 28:case 27:$s=24;continue;case 9:$r=d.fmtBool($clone(g,G.Value).Bool(),b);$s=33;case 33:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 10:$r=d.fmtInteger(((j=$clone(g,G.Value).Int(),new $Uint64(j.$high,j.$low))),true,b);$s=34;case 34:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 11:$r=d.fmtInteger($clone(g,G.Value).Uint(),false,b);$s=35;case 35:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 12:$r=d.fmtFloat($clone(g,G.Value).Float(),32,b);$s=36;case 36:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 13:$r=d.fmtFloat($clone(g,G.Value).Float(),64,b);$s=37;case 37:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 14:$r=d.fmtComplex($clone(g,G.Value).Complex(),64,b);$s=38;case 38:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 15:$r=d.fmtComplex($clone(g,G.Value).Complex(),128,b);$s=39;case 39:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 16:k=$clone(g,G.Value).String();$s=40;case 40:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$r=d.fmtString(k,b);$s=41;case 41:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 17:if(d.fmt.fmtFlags.sharpV){$s=42;continue;}$s=43;continue;case 42:l=$clone(g,G.Value).Type().String();$s=45;case 45:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}$r=(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(l);$s=46;case 46:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if($clone(g,G.Value).IsNil()){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"(nil)\");$s=-1;return;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(123);$s=44;continue;case 43:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"map[\");case 44:m=D.Sort($clone(g,G.Value));$s=47;case 47:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=m;o=n.Key;p=0;case 48:if(!(p<o.$length)){$s=49;continue;}q=p;r=((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]);if(q>0){if(d.fmt.fmtFlags.sharpV){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\", \");}else{(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(32);}}$r=d.printValue($clone(r,G.Value),b,c+1>>0);$s=50;case 50:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(58);$r=d.printValue($clone((s=n.Value,((q<0||q>=s.$length)?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+q])),G.Value),b,c+1>>0);$s=51;case 51:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}p++;$s=48;continue;case 49:if(d.fmt.fmtFlags.sharpV){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(125);}else{(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(93);}$s=24;continue;case 18:if(d.fmt.fmtFlags.sharpV){$s=52;continue;}$s=53;continue;case 52:t=$clone(g,G.Value).Type().String();$s=54;case 54:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}$r=(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(t);$s=55;case 55:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 53:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(123);u=0;case 56:if(!(u<$clone(g,G.Value).NumField())){$s=57;continue;}if(u>0){if(d.fmt.fmtFlags.sharpV){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\", \");}else{(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(32);}}if(d.fmt.fmtFlags.plusV||d.fmt.fmtFlags.sharpV){$s=58;continue;}$s=59;continue;case 58:v=$clone(g,G.Value).Type().Field(u);$s=60;case 60:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}w=v.Name;if(!(w===\"\")){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(w);(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(58);}case 59:x=AD($clone(g,G.Value),u);$s=61;case 61:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}$r=d.printValue($clone(x,G.Value),b,c+1>>0);$s=62;case 62:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}u=u+(1)>>0;$s=56;continue;case 57:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(125);$s=24;continue;case 19:y=$clone(g,G.Value).Elem();$s=63;case 63:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}z=y;if(!$clone(z,G.Value).IsValid()){$s=64;continue;}$s=65;continue;case 64:if(d.fmt.fmtFlags.sharpV){$s=67;continue;}$s=68;continue;case 67:aa=$clone(g,G.Value).Type().String();$s=70;case 70:if($c){$c=false;aa=aa.$blk();}if(aa&&aa.$blk!==undefined){break s;}$r=(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(aa);$s=71;case 71:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"(nil)\");$s=69;continue;case 68:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"<nil>\");case 69:$s=66;continue;case 65:$r=d.printValue($clone(z,G.Value),b,c+1>>0);$s=72;case 72:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 66:$s=24;continue;case 20:ab=b;if((ab===(115))||(ab===(113))||(ab===(120))||(ab===(88))){$s=74;continue;}$s=75;continue;case 74:ac=$clone(g,G.Value).Type();ad=ac.Elem();$s=78;case 78:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ae=ad.Kind();$s=79;case 79:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}if(ae===8){$s=76;continue;}$s=77;continue;case 76:af=BO.nil;if($clone(g,G.Value).Kind()===23){$s=80;continue;}if($clone(g,G.Value).CanAddr()){$s=81;continue;}$s=82;continue;case 80:ag=$clone(g,G.Value).Bytes();$s=84;case 84:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}af=ag;$s=83;continue;case 81:ah=$clone(g,G.Value).Slice(0,$clone(g,G.Value).Len());$s=85;case 85:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ai=$clone(ah,G.Value).Bytes();$s=86;case 86:if($c){$c=false;ai=ai.$blk();}if(ai&&ai.$blk!==undefined){break s;}af=ai;$s=83;continue;case 82:af=$makeSlice(BO,$clone(g,G.Value).Len());aj=af;ak=0;case 87:if(!(ak<aj.$length)){$s=88;continue;}al=ak;am=$clone(g,G.Value).Index(al);$s=89;case 89:if($c){$c=false;am=am.$blk();}if(am&&am.$blk!==undefined){break s;}an=$clone(am,G.Value).Uint();$s=90;case 90:if($c){$c=false;an=an.$blk();}if(an&&an.$blk!==undefined){break s;}((al<0||al>=af.$length)?($throwRuntimeError(\"index out of range\"),undefined):af.$array[af.$offset+al]=((an.$low<<24>>>24)));ak++;$s=87;continue;case 88:case 83:ao=af;ap=b;aq=ac.String();$s=91;case 91:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;$r=d.fmtBytes(ao,ap,ar);$s=92;case 92:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 77:case 75:case 73:if(d.fmt.fmtFlags.sharpV){$s=93;continue;}$s=94;continue;case 93:as=$clone(g,G.Value).Type().String();$s=96;case 96:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}$r=(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(as);$s=97;case 97:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(($clone(g,G.Value).Kind()===23)&&$clone(g,G.Value).IsNil()){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\"(nil)\");$s=-1;return;}(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(123);at=0;case 98:if(!(at<$clone(g,G.Value).Len())){$s=99;continue;}if(at>0){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteString(\", \");}au=$clone(g,G.Value).Index(at);$s=100;case 100:if($c){$c=false;au=au.$blk();}if(au&&au.$blk!==undefined){break s;}$r=d.printValue($clone(au,G.Value),b,c+1>>0);$s=101;case 101:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}at=at+(1)>>0;$s=98;continue;case 99:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(125);$s=95;continue;case 94:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(91);av=0;case 102:if(!(av<$clone(g,G.Value).Len())){$s=103;continue;}if(av>0){(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(32);}aw=$clone(g,G.Value).Index(av);$s=104;case 104:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}$r=d.printValue($clone(aw,G.Value),b,c+1>>0);$s=105;case 105:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}av=av+(1)>>0;$s=102;continue;case 103:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(93);case 95:$s=24;continue;case 21:if((c===0)&&!(($clone(g,G.Value).Pointer()===0))){$s=106;continue;}$s=107;continue;case 106:ax=$clone(g,G.Value).Elem();$s=109;case 109:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ay=ax;az=$clone(ay,G.Value).Kind();if((az===(17))||(az===(23))||(az===(25))||(az===(21))){$s=110;continue;}$s=111;continue;case 110:(d.$ptr_buf||(d.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},d))).WriteByte(38);$r=d.printValue($clone(ay,G.Value),b,c+1>>0);$s=112;case 112:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 111:case 108:case 107:$r=d.fmtPointer($clone(g,G.Value),b);$s=113;case 113:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 22:$r=d.fmtPointer($clone(g,G.Value),b);$s=114;case 114:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=24;continue;case 23:$r=d.unknownType($clone(g,G.Value));$s=115;case 115:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 24:case 7:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.printValue};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.printValue=function(a,b,c){return this.$val.printValue(a,b,c);};AG=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=0;d=false;e=0;e=b;if(b<a.$length){$s=1;continue;}$s=2;continue;case 1:f=$assertType(((b<0||b>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+b]),$Int,true);c=f[0];d=f[1];if(!d){$s=3;continue;}$s=4;continue;case 3:g=G.ValueOf(((b<0||b>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+b]));$s=6;case 6:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;i=$clone(h,G.Value).Kind();if((i===(2))||(i===(3))||(i===(4))||(i===(5))||(i===(6))){j=$clone(h,G.Value).Int();if((k=(new $Int64(0,(((j.$low+((j.$high>>31)*4294967296))>>0)))),(k.$high===j.$high&&k.$low===j.$low))){c=(((j.$low+((j.$high>>31)*4294967296))>>0));d=true;}}else if((i===(7))||(i===(8))||(i===(9))||(i===(10))||(i===(11))||(i===(12))){l=$clone(h,G.Value).Uint();if((m=(new $Int64(l.$high,l.$low)),(m.$high>0||(m.$high===0&&m.$low>=0)))&&(n=(new $Uint64(0,((l.$low>>0)))),(n.$high===l.$high&&n.$low===l.$low))){c=((l.$low>>0));d=true;}}case 5:case 4:e=b+1>>0;if(AE(c)){c=0;d=false;}case 2:$s=-1;return[c,d,e];}return;}if($f===undefined){$f={$blk:AG};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};AH=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;b=0;c=0;d=false;if(a.length<3){e=0;f=1;g=false;b=e;c=f;d=g;return[b,c,d];}h=1;while(true){if(!(h<a.length)){break;}if(a.charCodeAt(h)===93){i=AF(a,1,h);j=i[0];k=i[1];l=i[2];if(!k||!((l===h))){m=0;n=h+1>>0;o=false;b=m;c=n;d=o;return[b,c,d];}p=j-1>>0;q=h+1>>0;r=true;b=p;c=q;d=r;return[b,c,d];}h=h+(1)>>0;}s=0;t=1;u=false;b=s;c=t;d=u;return[b,c,d];};Q.ptr.prototype.argNumber=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;e=0;f=0;g=false;h=this;if(b.length<=c||!((b.charCodeAt(c)===91))){i=a;j=c;k=false;e=i;f=j;g=k;return[e,f,g];}h.reordered=true;l=AH($substring(b,c));m=l[0];n=l[1];o=l[2];if(o&&0<=m&&m<d){p=m;q=c+n>>0;r=true;e=p;f=q;g=r;return[e,f,g];}h.goodArgNum=false;s=a;t=c+n>>0;u=o;e=s;f=t;g=u;return[e,f,g];};Q.prototype.argNumber=function(a,b,c,d){return this.$val.argNumber(a,b,c,d);};Q.ptr.prototype.badArgNum=function(a){var a,b;b=this;(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"%!\");(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteRune(a);(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"(BADINDEX)\");};Q.prototype.badArgNum=function(a){return this.$val.badArgNum(a);};Q.ptr.prototype.missingArg=function(a){var a,b;b=this;(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"%!\");(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteRune(a);(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteString(\"(MISSING)\");};Q.prototype.missingArg=function(a){return this.$val.missingArg(a);};Q.ptr.prototype.doPrintf=function(a,b){var a,aa,ab,ac,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=a.length;e=0;f=false;c.reordered=false;g=0;case 1:if(!(g<d)){$s=2;continue;}c.goodArgNum=true;h=g;while(true){if(!(g<d&&!((a.charCodeAt(g)===37)))){break;}g=g+(1)>>0;}if(g>h){(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString($substring(a,h,g));}if(g>=d){$s=2;continue;}g=g+(1)>>0;c.fmt.clearflags();case 3:if(!(g<d)){$s=4;continue;}i=a.charCodeAt(g);j=i;if(j===(35)){$s=6;continue;}if(j===(48)){$s=7;continue;}if(j===(43)){$s=8;continue;}if(j===(45)){$s=9;continue;}if(j===(32)){$s=10;continue;}$s=11;continue;case 6:c.fmt.fmtFlags.sharp=true;$s=12;continue;case 7:c.fmt.fmtFlags.zero=!c.fmt.fmtFlags.minus;$s=12;continue;case 8:c.fmt.fmtFlags.plus=true;$s=12;continue;case 9:c.fmt.fmtFlags.minus=true;c.fmt.fmtFlags.zero=false;$s=12;continue;case 10:c.fmt.fmtFlags.space=true;$s=12;continue;case 11:if(97<=i&&i<=122&&e<b.$length){$s=13;continue;}$s=14;continue;case 13:if(i===118){c.fmt.fmtFlags.sharpV=c.fmt.fmtFlags.sharp;c.fmt.fmtFlags.sharp=false;c.fmt.fmtFlags.plusV=c.fmt.fmtFlags.plus;c.fmt.fmtFlags.plus=false;}$r=c.printArg(((e<0||e>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+e]),((i>>0)));$s=15;case 15:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e+(1)>>0;g=g+(1)>>0;$s=1;continue s;case 14:$s=4;continue s;case 12:case 5:g=g+(1)>>0;$s=3;continue;case 4:k=c.argNumber(e,a,g,b.$length);e=k[0];g=k[1];f=k[2];if(g<d&&(a.charCodeAt(g)===42)){$s=16;continue;}$s=17;continue;case 16:g=g+(1)>>0;m=AG(b,e);$s=19;case 19:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;c.fmt.wid=l[0];c.fmt.fmtFlags.widPresent=l[1];e=l[2];if(!c.fmt.fmtFlags.widPresent){(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\"%!(BADWIDTH)\");}if(c.fmt.wid<0){c.fmt.wid=-c.fmt.wid;c.fmt.fmtFlags.minus=true;c.fmt.fmtFlags.zero=false;}f=false;$s=18;continue;case 17:n=AF(a,g,d);c.fmt.wid=n[0];c.fmt.fmtFlags.widPresent=n[1];g=n[2];if(f&&c.fmt.fmtFlags.widPresent){c.goodArgNum=false;}case 18:if((g+1>>0)<d&&(a.charCodeAt(g)===46)){$s=20;continue;}$s=21;continue;case 20:g=g+(1)>>0;if(f){c.goodArgNum=false;}o=c.argNumber(e,a,g,b.$length);e=o[0];g=o[1];f=o[2];if(g<d&&(a.charCodeAt(g)===42)){$s=22;continue;}$s=23;continue;case 22:g=g+(1)>>0;q=AG(b,e);$s=25;case 25:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;c.fmt.prec=p[0];c.fmt.fmtFlags.precPresent=p[1];e=p[2];if(c.fmt.prec<0){c.fmt.prec=0;c.fmt.fmtFlags.precPresent=false;}if(!c.fmt.fmtFlags.precPresent){(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\"%!(BADPREC)\");}f=false;$s=24;continue;case 23:r=AF(a,g,d);c.fmt.prec=r[0];c.fmt.fmtFlags.precPresent=r[1];g=r[2];if(!c.fmt.fmtFlags.precPresent){c.fmt.prec=0;c.fmt.fmtFlags.precPresent=true;}case 24:case 21:if(!f){s=c.argNumber(e,a,g,b.$length);e=s[0];g=s[1];f=s[2];}if(g>=d){(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\"%!(NOVERB)\");$s=2;continue;}t=((a.charCodeAt(g)>>0));u=1;v=t;w=u;if(v>=128){x=B.DecodeRuneInString($substring(a,g));v=x[0];w=x[1];}g=g+(w)>>0;if((v===37)){$s=27;continue;}if(!c.goodArgNum){$s=28;continue;}if(e>=b.$length){$s=29;continue;}if((v===118)){$s=30;continue;}$s=31;continue;case 27:(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteByte(37);$s=32;continue;case 28:c.badArgNum(v);$s=32;continue;case 29:c.missingArg(v);$s=32;continue;case 30:c.fmt.fmtFlags.sharpV=c.fmt.fmtFlags.sharp;c.fmt.fmtFlags.sharp=false;c.fmt.fmtFlags.plusV=c.fmt.fmtFlags.plus;c.fmt.fmtFlags.plus=false;$r=c.printArg(((e<0||e>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+e]),v);$s=33;case 33:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e+(1)>>0;$s=32;continue;case 31:$r=c.printArg(((e<0||e>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+e]),v);$s=34;case 34:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e+(1)>>0;case 32:case 26:$s=1;continue;case 2:if(!c.reordered&&e<b.$length){$s=35;continue;}$s=36;continue;case 35:c.fmt.clearflags();(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\"%!(EXTRA \");y=$subslice(b,e);z=0;case 37:if(!(z<y.$length)){$s=38;continue;}aa=z;ab=((z<0||z>=y.$length)?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+z]);if(aa>0){(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\", \");}if($interfaceIsEqual(ab,$ifaceNil)){$s=39;continue;}$s=40;continue;case 39:(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(\"<nil>\");$s=41;continue;case 40:ac=G.TypeOf(ab).String();$s=42;case 42:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}$r=(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteString(ac);$s=43;case 43:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteByte(61);$r=c.printArg(ab,118);$s=44;case 44:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 41:z++;$s=37;continue;case 38:(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteByte(41);case 36:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.doPrintf};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.doPrintf=function(a,b){return this.$val.doPrintf(a,b);};Q.ptr.prototype.doPrint=function(a){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=false;d=a;e=0;case 1:if(!(e<d.$length)){$s=2;continue;}f=e;g=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);if(!(!($interfaceIsEqual(g,$ifaceNil)))){h=false;$s=3;continue s;}i=G.TypeOf(g).Kind();$s=4;case 4:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i===24;case 3:j=h;if(f>0&&!j&&!c){(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(32);}$r=b.printArg(g,118);$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=j;e++;$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.doPrint};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.doPrint=function(a){return this.$val.doPrint(a);};Q.ptr.prototype.doPrintln=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=a;d=0;case 1:if(!(d<c.$length)){$s=2;continue;}e=d;f=((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]);if(e>0){(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(32);}$r=b.printArg(f,118);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d++;$s=1;continue;case 2:(b.$ptr_buf||(b.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},b))).WriteByte(10);$s=-1;return;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.doPrintln};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.doPrintln=function(a){return this.$val.doPrintln(a);};AV.ptr.prototype.Read=function(a){var a,b,c,d,e,f;b=0;c=$ifaceNil;d=this;e=0;f=C.New(\"ScanState's Read should not be called. Use ReadRune\");b=e;c=f;return[b,c];};AV.prototype.Read=function(a){return this.$val.Read(a);};AV.ptr.prototype.ReadRune=function(){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=0;b=0;c=$ifaceNil;d=this;if(d.atEOF||d.count>=d.ssave.argLimit){c=E.EOF;$s=-1;return[a,b,c];}f=d.rs.ReadRune();$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;a=e[0];b=e[1];c=e[2];if($interfaceIsEqual(c,$ifaceNil)){d.count=d.count+(1)>>0;if(d.ssave.nlIsEnd&&(a===10)){d.atEOF=true;}}else if($interfaceIsEqual(c,E.EOF)){d.atEOF=true;}$s=-1;return[a,b,c];}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.ReadRune};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.ReadRune=function(){return this.$val.ReadRune();};AV.ptr.prototype.Width=function(){var a,b,c,d,e,f,g;a=0;b=false;c=this;if(c.ssave.maxWid===1073741824){d=0;e=false;a=d;b=e;return[a,b];}f=c.ssave.maxWid;g=true;a=f;b=g;return[a,b];};AV.prototype.Width=function(){return this.$val.Width();};AV.ptr.prototype.getRune=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=0;b=this;d=b.ReadRune();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}c=d;a=c[0];e=c[2];if(!($interfaceIsEqual(e,$ifaceNil))){if($interfaceIsEqual(e,E.EOF)){a=-1;$s=-1;return a;}b.error(e);}$s=-1;return a;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.getRune};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.getRune=function(){return this.$val.getRune();};AV.ptr.prototype.UnreadRune=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.rs.UnreadRune();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}b;a.atEOF=false;a.count=a.count-(1)>>0;$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.UnreadRune};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.UnreadRune=function(){return this.$val.UnreadRune();};AV.ptr.prototype.error=function(a){var a,b,c;b=this;$panic((c=new AU.ptr(a),new c.constructor.elem(c)));};AV.prototype.error=function(a){return this.$val.error(a);};AV.ptr.prototype.errorString=function(a){var a,b,c;b=this;$panic((c=new AU.ptr(C.New(a)),new c.constructor.elem(c)));};AV.prototype.errorString=function(a){return this.$val.errorString(a);};AV.ptr.prototype.Token=function(a,b){var a,b,c,d,e,f,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=[c];d=BO.nil;c[0]=$ifaceNil;e=this;$deferred.push([(function(c){return function(){var f,g,h,i;f=$recover();if(!($interfaceIsEqual(f,$ifaceNil))){g=$assertType(f,AU,true);h=$clone(g[0],AU);i=g[1];if(i){c[0]=h.err;}else{$panic(f);}}};})(c),[]]);if(b===$throwNilPointerError){b=AZ;}e.buf=$subslice(e.buf,0,0);f=e.token(a,b);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}d=f;$s=-1;return[d,c[0]];}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return[d,c[0]];}if($curGoroutine.asleep){if($f===undefined){$f={$blk:AV.ptr.prototype.Token};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AV.prototype.Token=function(a,b){return this.$val.Token(a,b);};AY=function(a){var a,b,c,d,e;if(a>=65536){return false;}b=((a<<16>>>16));c=AX;d=0;while(true){if(!(d<c.$length)){break;}e=$clone(((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]),BM);if(b<e[0]){return false;}if(b<=e[1]){return true;}d++;}return false;};AZ=function(a){var a;return!AY(a);};AV.ptr.prototype.free=function(a){var a,b;b=this;if(a.validSave){AW.copy(b.ssave,a);return;}if(b.buf.$capacity>1024){return;}b.buf=$subslice(b.buf,0,0);b.rs=$ifaceNil;BB.Put(b);};AV.prototype.free=function(a){return this.$val.free(a);};AV.ptr.prototype.SkipSpace=function(){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;case 1:b=a.getRune();$s=3;case 3:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;if(c===-1){$s=-1;return;}if(!(c===13)){d=false;$s=6;continue s;}e=a.peek(\"\\n\");$s=7;case 7:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;case 6:if(d){$s=4;continue;}$s=5;continue;case 4:$s=1;continue;case 5:if(c===10){$s=8;continue;}$s=9;continue;case 8:if(a.ssave.nlIsSpace){$s=1;continue;}a.errorString(\"unexpected newline\");$s=-1;return;case 9:if(!AY(c)){$s=10;continue;}$s=11;continue;case 10:f=a.UnreadRune();$s=12;case 12:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}f;$s=2;continue;case 11:$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.SkipSpace};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.SkipSpace=function(){return this.$val.SkipSpace();};AV.ptr.prototype.token=function(a,b){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(a){$s=1;continue;}$s=2;continue;case 1:$r=c.SkipSpace();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:case 4:d=c.getRune();$s=6;case 6:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===-1){$s=5;continue;}f=b(e);$s=9;case 9:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}if(!f){$s=7;continue;}$s=8;continue;case 7:g=c.UnreadRune();$s=10;case 10:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}g;$s=5;continue;case 8:(c.$ptr_buf||(c.$ptr_buf=new BK(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))).WriteRune(e);$s=4;continue;case 5:$s=-1;return(h=c.buf,$subslice(new BO(h.$array),h.$offset,h.$offset+h.$length));}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.token};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.token=function(a,b){return this.$val.token(a,b);};BF=function(a,b){var a,b,c,d,e,f,g;c=a;d=0;while(true){if(!(d<c.length)){break;}e=$decodeRune(c,d);f=d;g=e[0];if(g===b){return f;}d+=e[1];}return-1;};AV.ptr.prototype.peek=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.getRune();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;if(!((d===-1))){$s=2;continue;}$s=3;continue;case 2:e=b.UnreadRune();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;case 3:$s=-1;return BF(a,d)>=0;}return;}if($f===undefined){$f={$blk:AV.ptr.prototype.peek};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AV.prototype.peek=function(a){return this.$val.peek(a);};CO.methods=[{prop:\"clearflags\",name:\"clearflags\",pkg:\"fmt\",typ:$funcType([],[],false)},{prop:\"init\",name:\"init\",pkg:\"fmt\",typ:$funcType([BK],[],false)},{prop:\"writePadding\",name:\"writePadding\",pkg:\"fmt\",typ:$funcType([$Int],[],false)},{prop:\"pad\",name:\"pad\",pkg:\"fmt\",typ:$funcType([BO],[],false)},{prop:\"padString\",name:\"padString\",pkg:\"fmt\",typ:$funcType([$String],[],false)},{prop:\"fmtBoolean\",name:\"fmtBoolean\",pkg:\"fmt\",typ:$funcType([$Bool],[],false)},{prop:\"fmtUnicode\",name:\"fmtUnicode\",pkg:\"fmt\",typ:$funcType([$Uint64],[],false)},{prop:\"fmtInteger\",name:\"fmtInteger\",pkg:\"fmt\",typ:$funcType([$Uint64,$Int,$Bool,$String],[],false)},{prop:\"truncateString\",name:\"truncateString\",pkg:\"fmt\",typ:$funcType([$String],[$String],false)},{prop:\"truncate\",name:\"truncate\",pkg:\"fmt\",typ:$funcType([BO],[BO],false)},{prop:\"fmtS\",name:\"fmtS\",pkg:\"fmt\",typ:$funcType([$String],[],false)},{prop:\"fmtBs\",name:\"fmtBs\",pkg:\"fmt\",typ:$funcType([BO],[],false)},{prop:\"fmtSbx\",name:\"fmtSbx\",pkg:\"fmt\",typ:$funcType([$String,BO,$String],[],false)},{prop:\"fmtSx\",name:\"fmtSx\",pkg:\"fmt\",typ:$funcType([$String,$String],[],false)},{prop:\"fmtBx\",name:\"fmtBx\",pkg:\"fmt\",typ:$funcType([BO,$String],[],false)},{prop:\"fmtQ\",name:\"fmtQ\",pkg:\"fmt\",typ:$funcType([$String],[],false)},{prop:\"fmtC\",name:\"fmtC\",pkg:\"fmt\",typ:$funcType([$Uint64],[],false)},{prop:\"fmtQc\",name:\"fmtQc\",pkg:\"fmt\",typ:$funcType([$Uint64],[],false)},{prop:\"fmtFloat\",name:\"fmtFloat\",pkg:\"fmt\",typ:$funcType([$Float64,$Int,$Int32,$Int],[],false)}];BK.methods=[{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([BO],[],false)},{prop:\"WriteString\",name:\"WriteString\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"WriteByte\",name:\"WriteByte\",pkg:\"\",typ:$funcType([$Uint8],[],false)},{prop:\"WriteRune\",name:\"WriteRune\",pkg:\"\",typ:$funcType([$Int32],[],false)}];BQ.methods=[{prop:\"free\",name:\"free\",pkg:\"fmt\",typ:$funcType([],[],false)},{prop:\"Width\",name:\"Width\",pkg:\"\",typ:$funcType([],[$Int,$Bool],false)},{prop:\"Precision\",name:\"Precision\",pkg:\"\",typ:$funcType([],[$Int,$Bool],false)},{prop:\"Flag\",name:\"Flag\",pkg:\"\",typ:$funcType([$Int],[$Bool],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([BO],[$Int,$error],false)},{prop:\"WriteString\",name:\"WriteString\",pkg:\"\",typ:$funcType([$String],[$Int,$error],false)},{prop:\"unknownType\",name:\"unknownType\",pkg:\"fmt\",typ:$funcType([G.Value],[],false)},{prop:\"badVerb\",name:\"badVerb\",pkg:\"fmt\",typ:$funcType([$Int32],[],false)},{prop:\"fmtBool\",name:\"fmtBool\",pkg:\"fmt\",typ:$funcType([$Bool,$Int32],[],false)},{prop:\"fmt0x64\",name:\"fmt0x64\",pkg:\"fmt\",typ:$funcType([$Uint64,$Bool],[],false)},{prop:\"fmtInteger\",name:\"fmtInteger\",pkg:\"fmt\",typ:$funcType([$Uint64,$Bool,$Int32],[],false)},{prop:\"fmtFloat\",name:\"fmtFloat\",pkg:\"fmt\",typ:$funcType([$Float64,$Int,$Int32],[],false)},{prop:\"fmtComplex\",name:\"fmtComplex\",pkg:\"fmt\",typ:$funcType([$Complex128,$Int,$Int32],[],false)},{prop:\"fmtString\",name:\"fmtString\",pkg:\"fmt\",typ:$funcType([$String,$Int32],[],false)},{prop:\"fmtBytes\",name:\"fmtBytes\",pkg:\"fmt\",typ:$funcType([BO,$Int32,$String],[],false)},{prop:\"fmtPointer\",name:\"fmtPointer\",pkg:\"fmt\",typ:$funcType([G.Value,$Int32],[],false)},{prop:\"catchPanic\",name:\"catchPanic\",pkg:\"fmt\",typ:$funcType([$emptyInterface,$Int32,$String],[],false)},{prop:\"handleMethods\",name:\"handleMethods\",pkg:\"fmt\",typ:$funcType([$Int32],[$Bool],false)},{prop:\"printArg\",name:\"printArg\",pkg:\"fmt\",typ:$funcType([$emptyInterface,$Int32],[],false)},{prop:\"printValue\",name:\"printValue\",pkg:\"fmt\",typ:$funcType([G.Value,$Int32,$Int],[],false)},{prop:\"argNumber\",name:\"argNumber\",pkg:\"fmt\",typ:$funcType([$Int,$String,$Int,$Int],[$Int,$Int,$Bool],false)},{prop:\"badArgNum\",name:\"badArgNum\",pkg:\"fmt\",typ:$funcType([$Int32],[],false)},{prop:\"missingArg\",name:\"missingArg\",pkg:\"fmt\",typ:$funcType([$Int32],[],false)},{prop:\"doPrintf\",name:\"doPrintf\",pkg:\"fmt\",typ:$funcType([$String,BI],[],false)},{prop:\"doPrint\",name:\"doPrint\",pkg:\"fmt\",typ:$funcType([BI],[],false)},{prop:\"doPrintln\",name:\"doPrintln\",pkg:\"fmt\",typ:$funcType([BI],[],false)}];BT.methods=[{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([BO],[$Int,$error],false)},{prop:\"ReadRune\",name:\"ReadRune\",pkg:\"\",typ:$funcType([],[$Int32,$Int,$error],false)},{prop:\"Width\",name:\"Width\",pkg:\"\",typ:$funcType([],[$Int,$Bool],false)},{prop:\"getRune\",name:\"getRune\",pkg:\"fmt\",typ:$funcType([],[$Int32],false)},{prop:\"mustReadRune\",name:\"mustReadRune\",pkg:\"fmt\",typ:$funcType([],[$Int32],false)},{prop:\"UnreadRune\",name:\"UnreadRune\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"error\",name:\"error\",pkg:\"fmt\",typ:$funcType([$error],[],false)},{prop:\"errorString\",name:\"errorString\",pkg:\"fmt\",typ:$funcType([$String],[],false)},{prop:\"Token\",name:\"Token\",pkg:\"\",typ:$funcType([$Bool,CP],[BO,$error],false)},{prop:\"free\",name:\"free\",pkg:\"fmt\",typ:$funcType([AW],[],false)},{prop:\"SkipSpace\",name:\"SkipSpace\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"token\",name:\"token\",pkg:\"fmt\",typ:$funcType([$Bool,CP],[BO],false)},{prop:\"consume\",name:\"consume\",pkg:\"fmt\",typ:$funcType([$String,$Bool],[$Bool],false)},{prop:\"peek\",name:\"peek\",pkg:\"fmt\",typ:$funcType([$String],[$Bool],false)},{prop:\"notEOF\",name:\"notEOF\",pkg:\"fmt\",typ:$funcType([],[],false)},{prop:\"accept\",name:\"accept\",pkg:\"fmt\",typ:$funcType([$String],[$Bool],false)},{prop:\"okVerb\",name:\"okVerb\",pkg:\"fmt\",typ:$funcType([$Int32,$String,$String],[$Bool],false)},{prop:\"scanBool\",name:\"scanBool\",pkg:\"fmt\",typ:$funcType([$Int32],[$Bool],false)},{prop:\"getBase\",name:\"getBase\",pkg:\"fmt\",typ:$funcType([$Int32],[$Int,$String],false)},{prop:\"scanNumber\",name:\"scanNumber\",pkg:\"fmt\",typ:$funcType([$String,$Bool],[$String],false)},{prop:\"scanRune\",name:\"scanRune\",pkg:\"fmt\",typ:$funcType([$Int],[$Int64],false)},{prop:\"scanBasePrefix\",name:\"scanBasePrefix\",pkg:\"fmt\",typ:$funcType([],[$Int,$String,$Bool],false)},{prop:\"scanInt\",name:\"scanInt\",pkg:\"fmt\",typ:$funcType([$Int32,$Int],[$Int64],false)},{prop:\"scanUint\",name:\"scanUint\",pkg:\"fmt\",typ:$funcType([$Int32,$Int],[$Uint64],false)},{prop:\"floatToken\",name:\"floatToken\",pkg:\"fmt\",typ:$funcType([],[$String],false)},{prop:\"complexTokens\",name:\"complexTokens\",pkg:\"fmt\",typ:$funcType([],[$String,$String],false)},{prop:\"convertFloat\",name:\"convertFloat\",pkg:\"fmt\",typ:$funcType([$String,$Int],[$Float64],false)},{prop:\"scanComplex\",name:\"scanComplex\",pkg:\"fmt\",typ:$funcType([$Int32,$Int],[$Complex128],false)},{prop:\"convertString\",name:\"convertString\",pkg:\"fmt\",typ:$funcType([$Int32],[$String],false)},{prop:\"quotedString\",name:\"quotedString\",pkg:\"fmt\",typ:$funcType([],[$String],false)},{prop:\"hexByte\",name:\"hexByte\",pkg:\"fmt\",typ:$funcType([],[$Uint8,$Bool],false)},{prop:\"hexString\",name:\"hexString\",pkg:\"fmt\",typ:$funcType([],[$String],false)},{prop:\"scanOne\",name:\"scanOne\",pkg:\"fmt\",typ:$funcType([$Int32,$emptyInterface],[],false)},{prop:\"doScan\",name:\"doScan\",pkg:\"fmt\",typ:$funcType([BI],[$Int,$error],false)},{prop:\"advance\",name:\"advance\",pkg:\"fmt\",typ:$funcType([$String],[$Int],false)},{prop:\"doScanf\",name:\"doScanf\",pkg:\"fmt\",typ:$funcType([$String,BI],[$Int,$error],false)}];J.init(\"fmt\",[{prop:\"widPresent\",name:\"widPresent\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"precPresent\",name:\"precPresent\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"minus\",name:\"minus\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"plus\",name:\"plus\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"sharp\",name:\"sharp\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"space\",name:\"space\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"zero\",name:\"zero\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"plusV\",name:\"plusV\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"sharpV\",name:\"sharpV\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);K.init(\"fmt\",[{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:BK,tag:\"\"},{prop:\"fmtFlags\",name:\"fmtFlags\",embedded:true,exported:false,typ:J,tag:\"\"},{prop:\"wid\",name:\"wid\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"prec\",name:\"prec\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"intbuf\",name:\"intbuf\",embedded:false,exported:false,typ:BL,tag:\"\"}]);L.init([{prop:\"Flag\",name:\"Flag\",pkg:\"\",typ:$funcType([$Int],[$Bool],false)},{prop:\"Precision\",name:\"Precision\",pkg:\"\",typ:$funcType([],[$Int,$Bool],false)},{prop:\"Width\",name:\"Width\",pkg:\"\",typ:$funcType([],[$Int,$Bool],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([BO],[$Int,$error],false)}]);M.init([{prop:\"Format\",name:\"Format\",pkg:\"\",typ:$funcType([L,$Int32],[],false)}]);N.init([{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}]);O.init([{prop:\"GoString\",name:\"GoString\",pkg:\"\",typ:$funcType([],[$String],false)}]);P.init($Uint8);Q.init(\"fmt\",[{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:P,tag:\"\"},{prop:\"arg\",name:\"arg\",embedded:false,exported:false,typ:$emptyInterface,tag:\"\"},{prop:\"value\",name:\"value\",embedded:false,exported:false,typ:G.Value,tag:\"\"},{prop:\"fmt\",name:\"fmt\",embedded:false,exported:false,typ:K,tag:\"\"},{prop:\"reordered\",name:\"reordered\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"goodArgNum\",name:\"goodArgNum\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"panicking\",name:\"panicking\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"erroring\",name:\"erroring\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);AU.init(\"fmt\",[{prop:\"err\",name:\"err\",embedded:false,exported:false,typ:$error,tag:\"\"}]);AV.init(\"fmt\",[{prop:\"rs\",name:\"rs\",embedded:false,exported:false,typ:E.RuneScanner,tag:\"\"},{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:P,tag:\"\"},{prop:\"count\",name:\"count\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"atEOF\",name:\"atEOF\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"ssave\",name:\"ssave\",embedded:true,exported:false,typ:AW,tag:\"\"}]);AW.init(\"fmt\",[{prop:\"validSave\",name:\"validSave\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"nlIsEnd\",name:\"nlIsEnd\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"nlIsSpace\",name:\"nlIsSpace\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"argLimit\",name:\"argLimit\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"limit\",name:\"limit\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"maxWid\",name:\"maxWid\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=C.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=I.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}R=new H.Pool.ptr(0,0,BI.nil,(function(){return new Q.ptr(P.nil,$ifaceNil,new G.Value.ptr(BJ.nil,0,0),new K.ptr(BK.nil,new J.ptr(false,false,false,false,false,false,false,false,false),0,0,BL.zero()),false,false,false,false);}));AX=new BN([$toNativeArray($kindUint16,[9,13]),$toNativeArray($kindUint16,[32,32]),$toNativeArray($kindUint16,[133,133]),$toNativeArray($kindUint16,[160,160]),$toNativeArray($kindUint16,[5760,5760]),$toNativeArray($kindUint16,[8192,8202]),$toNativeArray($kindUint16,[8232,8233]),$toNativeArray($kindUint16,[8239,8239]),$toNativeArray($kindUint16,[8287,8287]),$toNativeArray($kindUint16,[12288,12288])]);BB=new H.Pool.ptr(0,0,BI.nil,(function(){return new AV.ptr($ifaceNil,P.nil,0,false,new AW.ptr(false,false,false,0,0,0));}));BD=C.New(\"syntax error scanning complex number\");BE=C.New(\"syntax error scanning boolean\");}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"bytes\"]=(function(){var $pkg={},$init,A,D,B,E,C,BS,BV,CD,K,F,G,AJ,AM,BP,BQ,BR,BT;A=$packages[\"errors\"];D=$packages[\"internal/bytealg\"];B=$packages[\"io\"];E=$packages[\"unicode\"];C=$packages[\"unicode/utf8\"];BS=$pkg.Reader=$newType(0,$kindStruct,\"bytes.Reader\",true,\"bytes\",true,function(s_,i_,prevRune_){this.$val=this;if(arguments.length===0){this.s=BV.nil;this.i=new $Int64(0,0);this.prevRune=0;return;}this.s=s_;this.i=i_;this.prevRune=prevRune_;});BV=$sliceType($Uint8);CD=$ptrType(BS);F=function(d,e){var d,e,f,g,h,i;f=d;g=0;while(true){if(!(g<f.$length)){break;}h=g;i=((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]);if(i===e){return h;}g++;}return-1;};$pkg.IndexByte=F;G=function(d,e){var d,e,f,g,h,i;if(!((d.$length===e.$length))){return false;}f=d;g=0;while(true){if(!(g<f.$length)){break;}h=g;i=((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]);if(!((i===((h<0||h>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+h])))){return false;}g++;}return true;};$pkg.Equal=G;AJ=function(d,e){var d,e;return d.$length>=e.$length&&G($subslice(d,0,e.$length),e);};$pkg.HasPrefix=AJ;AM=function(d,e){var d,e,f,g,h;if(e<0){$panic(new $String(\"bytes: negative Repeat count\"));}else if(e>0&&!(((f=($imul(d.$length,e))/e,(f===f&&f!==1/0&&f!==-1/0)?f>>0:$throwRuntimeError(\"integer divide by zero\"))===d.$length))){$panic(new $String(\"bytes: Repeat count causes overflow\"));}g=$makeSlice(BV,($imul(d.$length,e)));h=$copySlice(g,d);while(true){if(!(h<g.$length)){break;}$copySlice($subslice(g,h),$subslice(g,0,h));h=$imul(h,(2));}return g;};$pkg.Repeat=AM;BP=function(d,e){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;f=e.$length;if((f===0)){return 0;}else if((f===1)){return F(d,(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]));}else if((f===d.$length)){if(G(e,d)){return 0;}return-1;}else if(f>d.$length){return-1;}else if(f<=D.MaxLen){if(d.$length<=0){return D.Index(d,e);}g=(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]);h=(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1]);i=0;j=(d.$length-f>>0)+1>>0;k=0;while(true){if(!(i<j)){break;}if(!((((i<0||i>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+i])===g))){l=F($subslice(d,i,j),g);if(l<0){return-1;}i=i+(l)>>0;}if(((m=i+1>>0,((m<0||m>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+m]))===h)&&G($subslice(d,i,(i+f>>0)),e)){return i;}k=k+(1)>>0;i=i+(1)>>0;if(k>D.Cutover(i)){n=D.Index($subslice(d,i),e);if(n>=0){return n+i>>0;}return-1;}}return-1;}o=(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]);p=(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1]);q=0;r=0;s=(d.$length-f>>0)+1>>0;while(true){if(!(q<s)){break;}if(!((((q<0||q>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+q])===o))){t=F($subslice(d,q,s),o);if(t<0){break;}q=q+(t)>>0;}if(((u=q+1>>0,((u<0||u>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+u]))===p)&&G($subslice(d,q,(q+f>>0)),e)){return q;}q=q+(1)>>0;r=r+(1)>>0;if(r>=(4+(q>>4>>0)>>0)&&q<s){v=BQ($subslice(d,q),e);if(v<0){return-1;}return q+v>>0;}}return-1;};$pkg.Index=BP;BQ=function(d,e){var d,e,f,g,h,i,j,k,l,m;f=BR(e);g=f[0];h=f[1];i=e.$length;j=0;k=0;while(true){if(!(k<i)){break;}j=($imul(j,16777619)>>>0)+((((k<0||k>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+k])>>>0))>>>0;k=k+(1)>>0;}if((j===g)&&G($subslice(d,0,i),e)){return 0;}l=i;while(true){if(!(l<d.$length)){break;}j=$imul(j,(16777619))>>>0;j=j+(((((l<0||l>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+l])>>>0)))>>>0;j=j-(($imul(h,(((m=l-i>>0,((m<0||m>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+m]))>>>0)))>>>0))>>>0;l=l+(1)>>0;if((j===g)&&G($subslice(d,(l-i>>0),l),e)){return l-i>>0;}}return-1;};BR=function(d){var d,e,f,g,h,i,j,k;e=0;f=0;while(true){if(!(f<d.$length)){break;}e=($imul(e,16777619)>>>0)+((((f<0||f>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+f])>>>0))>>>0;f=f+(1)>>0;}g=1;h=16777619;i=g;j=h;k=d.$length;while(true){if(!(k>0)){break;}if(!(((k&1)===0))){i=$imul(i,(j))>>>0;}j=$imul(j,(j))>>>0;k=(k>>$min((1),31))>>0;}return[e,i];};BS.ptr.prototype.Len=function(){var d,e,f,g,h,i;d=this;if((e=d.i,f=(new $Int64(0,d.s.$length)),(e.$high>f.$high||(e.$high===f.$high&&e.$low>=f.$low)))){return 0;}return(((g=(h=(new $Int64(0,d.s.$length)),i=d.i,new $Int64(h.$high-i.$high,h.$low-i.$low)),g.$low+((g.$high>>31)*4294967296))>>0));};BS.prototype.Len=function(){return this.$val.Len();};BS.ptr.prototype.Size=function(){var d;d=this;return(new $Int64(0,d.s.$length));};BS.prototype.Size=function(){return this.$val.Size();};BS.ptr.prototype.Read=function(d){var d,e,f,g,h,i,j,k,l,m;e=0;f=$ifaceNil;g=this;if((h=g.i,i=(new $Int64(0,g.s.$length)),(h.$high>i.$high||(h.$high===i.$high&&h.$low>=i.$low)))){j=0;k=B.EOF;e=j;f=k;return[e,f];}g.prevRune=-1;e=$copySlice(d,$subslice(g.s,$flatten64(g.i)));g.i=(l=g.i,m=(new $Int64(0,e)),new $Int64(l.$high+m.$high,l.$low+m.$low));return[e,f];};BS.prototype.Read=function(d){return this.$val.Read(d);};BS.ptr.prototype.ReadAt=function(d,e){var d,e,f,g,h,i,j,k,l,m;f=0;g=$ifaceNil;h=this;if((e.$high<0||(e.$high===0&&e.$low<0))){i=0;j=A.New(\"bytes.Reader.ReadAt: negative offset\");f=i;g=j;return[f,g];}if((k=(new $Int64(0,h.s.$length)),(e.$high>k.$high||(e.$high===k.$high&&e.$low>=k.$low)))){l=0;m=B.EOF;f=l;g=m;return[f,g];}f=$copySlice(d,$subslice(h.s,$flatten64(e)));if(f<d.$length){g=B.EOF;}return[f,g];};BS.prototype.ReadAt=function(d,e){return this.$val.ReadAt(d,e);};BS.ptr.prototype.ReadByte=function(){var d,e,f,g,h,i,j,k;d=this;d.prevRune=-1;if((e=d.i,f=(new $Int64(0,d.s.$length)),(e.$high>f.$high||(e.$high===f.$high&&e.$low>=f.$low)))){return[0,B.EOF];}i=(g=d.s,h=d.i,(($flatten64(h)<0||$flatten64(h)>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+$flatten64(h)]));d.i=(j=d.i,k=new $Int64(0,1),new $Int64(j.$high+k.$high,j.$low+k.$low));return[i,$ifaceNil];};BS.prototype.ReadByte=function(){return this.$val.ReadByte();};BS.ptr.prototype.UnreadByte=function(){var d,e,f,g;d=this;if((e=d.i,(e.$high<0||(e.$high===0&&e.$low<=0)))){return A.New(\"bytes.Reader.UnreadByte: at beginning of slice\");}d.prevRune=-1;d.i=(f=d.i,g=new $Int64(0,1),new $Int64(f.$high-g.$high,f.$low-g.$low));return $ifaceNil;};BS.prototype.UnreadByte=function(){return this.$val.UnreadByte();};BS.ptr.prototype.ReadRune=function(){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;d=0;e=0;f=$ifaceNil;g=this;if((h=g.i,i=(new $Int64(0,g.s.$length)),(h.$high>i.$high||(h.$high===i.$high&&h.$low>=i.$low)))){g.prevRune=-1;j=0;k=0;l=B.EOF;d=j;e=k;f=l;return[d,e,f];}g.prevRune=(((m=g.i,m.$low+((m.$high>>31)*4294967296))>>0));p=(n=g.s,o=g.i,(($flatten64(o)<0||$flatten64(o)>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+$flatten64(o)]));if(p<128){g.i=(q=g.i,r=new $Int64(0,1),new $Int64(q.$high+r.$high,q.$low+r.$low));s=((p>>0));t=1;u=$ifaceNil;d=s;e=t;f=u;return[d,e,f];}v=C.DecodeRune($subslice(g.s,$flatten64(g.i)));d=v[0];e=v[1];g.i=(w=g.i,x=(new $Int64(0,e)),new $Int64(w.$high+x.$high,w.$low+x.$low));return[d,e,f];};BS.prototype.ReadRune=function(){return this.$val.ReadRune();};BS.ptr.prototype.UnreadRune=function(){var d,e;d=this;if((e=d.i,(e.$high<0||(e.$high===0&&e.$low<=0)))){return A.New(\"bytes.Reader.UnreadRune: at beginning of slice\");}if(d.prevRune<0){return A.New(\"bytes.Reader.UnreadRune: previous operation was not ReadRune\");}d.i=(new $Int64(0,d.prevRune));d.prevRune=-1;return $ifaceNil;};BS.prototype.UnreadRune=function(){return this.$val.UnreadRune();};BS.ptr.prototype.Seek=function(d,e){var d,e,f,g,h,i,j;f=this;f.prevRune=-1;g=new $Int64(0,0);h=e;if(h===(0)){g=d;}else if(h===(1)){g=(i=f.i,new $Int64(i.$high+d.$high,i.$low+d.$low));}else if(h===(2)){g=(j=(new $Int64(0,f.s.$length)),new $Int64(j.$high+d.$high,j.$low+d.$low));}else{return[new $Int64(0,0),A.New(\"bytes.Reader.Seek: invalid whence\")];}if((g.$high<0||(g.$high===0&&g.$low<0))){return[new $Int64(0,0),A.New(\"bytes.Reader.Seek: negative position\")];}f.i=g;return[g,$ifaceNil];};BS.prototype.Seek=function(d,e){return this.$val.Seek(d,e);};BS.ptr.prototype.WriteTo=function(d){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=new $Int64(0,0);f=$ifaceNil;g=this;g.prevRune=-1;if((h=g.i,i=(new $Int64(0,g.s.$length)),(h.$high>i.$high||(h.$high===i.$high&&h.$low>=i.$low)))){j=new $Int64(0,0);k=$ifaceNil;e=j;f=k;$s=-1;return[e,f];}l=$subslice(g.s,$flatten64(g.i));n=d.Write(l);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];f=m[1];if(o>l.$length){$panic(new $String(\"bytes.Reader.WriteTo: invalid Write count\"));}g.i=(p=g.i,q=(new $Int64(0,o)),new $Int64(p.$high+q.$high,p.$low+q.$low));e=(new $Int64(0,o));if(!((o===l.$length))&&$interfaceIsEqual(f,$ifaceNil)){f=B.ErrShortWrite;}$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:BS.ptr.prototype.WriteTo};}$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};BS.prototype.WriteTo=function(d){return this.$val.WriteTo(d);};BS.ptr.prototype.Reset=function(d){var d,e;e=this;BS.copy(e,new BS.ptr(d,new $Int64(0,0),-1));};BS.prototype.Reset=function(d){return this.$val.Reset(d);};BT=function(d){var d;return new BS.ptr(d,new $Int64(0,0),-1);};$pkg.NewReader=BT;CD.methods=[{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([BV],[$Int,$error],false)},{prop:\"ReadAt\",name:\"ReadAt\",pkg:\"\",typ:$funcType([BV,$Int64],[$Int,$error],false)},{prop:\"ReadByte\",name:\"ReadByte\",pkg:\"\",typ:$funcType([],[$Uint8,$error],false)},{prop:\"UnreadByte\",name:\"UnreadByte\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"ReadRune\",name:\"ReadRune\",pkg:\"\",typ:$funcType([],[$Int32,$Int,$error],false)},{prop:\"UnreadRune\",name:\"UnreadRune\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Seek\",name:\"Seek\",pkg:\"\",typ:$funcType([$Int64,$Int],[$Int64,$error],false)},{prop:\"WriteTo\",name:\"WriteTo\",pkg:\"\",typ:$funcType([B.Writer],[$Int64,$error],false)},{prop:\"Reset\",name:\"Reset\",pkg:\"\",typ:$funcType([BV],[],false)}];BS.init(\"bytes\",[{prop:\"s\",name:\"s\",embedded:false,exported:false,typ:BV,tag:\"\"},{prop:\"i\",name:\"i\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"prevRune\",name:\"prevRune\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.ErrTooLarge=A.New(\"bytes.Buffer: too large\");K=A.New(\"bytes.Buffer: reader returned negative count from Read\");}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"encoding/binary\"]=(function(){var $pkg={},$init,A,B,C,D,E,F,G,N,O,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,U,H,I,J,K,L,P;A=$packages[\"errors\"];B=$packages[\"io\"];C=$packages[\"math\"];D=$packages[\"reflect\"];E=$pkg.ByteOrder=$newType(8,$kindInterface,\"binary.ByteOrder\",true,\"encoding/binary\",true,null);F=$pkg.littleEndian=$newType(0,$kindStruct,\"binary.littleEndian\",true,\"encoding/binary\",false,function(){this.$val=this;if(arguments.length===0){return;}});G=$pkg.bigEndian=$newType(0,$kindStruct,\"binary.bigEndian\",true,\"encoding/binary\",false,function(){this.$val=this;if(arguments.length===0){return;}});N=$pkg.decoder=$newType(0,$kindStruct,\"binary.decoder\",true,\"encoding/binary\",false,function(order_,buf_,offset_){this.$val=this;if(arguments.length===0){this.order=$ifaceNil;this.buf=X.nil;this.offset=0;return;}this.order=order_;this.buf=buf_;this.offset=offset_;});O=$pkg.encoder=$newType(0,$kindStruct,\"binary.encoder\",true,\"encoding/binary\",false,function(order_,buf_,offset_){this.$val=this;if(arguments.length===0){this.order=$ifaceNil;this.buf=X.nil;this.offset=0;return;}this.order=order_;this.buf=buf_;this.offset=offset_;});X=$sliceType($Uint8);Y=$ptrType($Bool);Z=$ptrType($Int8);AA=$ptrType($Uint8);AB=$ptrType($Int16);AC=$ptrType($Uint16);AD=$ptrType($Int32);AE=$ptrType($Uint32);AF=$ptrType($Int64);AG=$ptrType($Uint64);AH=$sliceType($Bool);AI=$sliceType($Int8);AJ=$sliceType($Int16);AK=$sliceType($Uint16);AL=$sliceType($Int32);AM=$sliceType($Uint32);AN=$sliceType($Int64);AO=$sliceType($Uint64);AP=$ptrType(N);AQ=$ptrType(O);F.ptr.prototype.Uint16=function(a){var a;$unused((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]));return((((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])<<16>>>16))|((((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])<<16>>>16))<<8<<16>>>16))>>>0;};F.prototype.Uint16=function(a){return this.$val.Uint16(a);};F.ptr.prototype.PutUint16=function(a,b){var a,b;$unused((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((b<<24>>>24)));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=(((b>>>8<<16>>>16)<<24>>>24)));};F.prototype.PutUint16=function(a,b){return this.$val.PutUint16(a,b);};F.ptr.prototype.Uint32=function(a){var a;$unused((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]));return((((((((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])>>>0))|((((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])>>>0))<<8>>>0))>>>0)|((((2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2])>>>0))<<16>>>0))>>>0)|((((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3])>>>0))<<24>>>0))>>>0;};F.prototype.Uint32=function(a){return this.$val.Uint32(a);};F.ptr.prototype.PutUint32=function(a,b){var a,b;$unused((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((b<<24>>>24)));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=(((b>>>8>>>0)<<24>>>24)));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=(((b>>>16>>>0)<<24>>>24)));(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]=(((b>>>24>>>0)<<24>>>24)));};F.prototype.PutUint32=function(a,b){return this.$val.PutUint32(a,b);};F.ptr.prototype.Uint64=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;$unused((7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]));return(b=(c=(d=(e=(f=(g=(h=(new $Uint64(0,(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]))),i=$shiftLeft64((new $Uint64(0,(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]))),8),new $Uint64(h.$high|i.$high,(h.$low|i.$low)>>>0)),j=$shiftLeft64((new $Uint64(0,(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]))),16),new $Uint64(g.$high|j.$high,(g.$low|j.$low)>>>0)),k=$shiftLeft64((new $Uint64(0,(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]))),24),new $Uint64(f.$high|k.$high,(f.$low|k.$low)>>>0)),l=$shiftLeft64((new $Uint64(0,(4>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+4]))),32),new $Uint64(e.$high|l.$high,(e.$low|l.$low)>>>0)),m=$shiftLeft64((new $Uint64(0,(5>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+5]))),40),new $Uint64(d.$high|m.$high,(d.$low|m.$low)>>>0)),n=$shiftLeft64((new $Uint64(0,(6>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+6]))),48),new $Uint64(c.$high|n.$high,(c.$low|n.$low)>>>0)),o=$shiftLeft64((new $Uint64(0,(7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]))),56),new $Uint64(b.$high|o.$high,(b.$low|o.$low)>>>0));};F.prototype.Uint64=function(a){return this.$val.Uint64(a);};F.ptr.prototype.PutUint64=function(a,b){var a,b;$unused((7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=((b.$low<<24>>>24)));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=(($shiftRightUint64(b,8).$low<<24>>>24)));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=(($shiftRightUint64(b,16).$low<<24>>>24)));(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]=(($shiftRightUint64(b,24).$low<<24>>>24)));(4>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+4]=(($shiftRightUint64(b,32).$low<<24>>>24)));(5>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+5]=(($shiftRightUint64(b,40).$low<<24>>>24)));(6>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+6]=(($shiftRightUint64(b,48).$low<<24>>>24)));(7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]=(($shiftRightUint64(b,56).$low<<24>>>24)));};F.prototype.PutUint64=function(a,b){return this.$val.PutUint64(a,b);};F.ptr.prototype.String=function(){return\"LittleEndian\";};F.prototype.String=function(){return this.$val.String();};F.ptr.prototype.GoString=function(){return\"binary.LittleEndian\";};F.prototype.GoString=function(){return this.$val.GoString();};G.ptr.prototype.Uint16=function(a){var a;$unused((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]));return((((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])<<16>>>16))|((((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])<<16>>>16))<<8<<16>>>16))>>>0;};G.prototype.Uint16=function(a){return this.$val.Uint16(a);};G.ptr.prototype.PutUint16=function(a,b){var a,b;$unused((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=(((b>>>8<<16>>>16)<<24>>>24)));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=((b<<24>>>24)));};G.prototype.PutUint16=function(a,b){return this.$val.PutUint16(a,b);};G.ptr.prototype.Uint32=function(a){var a;$unused((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]));return((((((((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3])>>>0))|((((2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2])>>>0))<<8>>>0))>>>0)|((((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])>>>0))<<16>>>0))>>>0)|((((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])>>>0))<<24>>>0))>>>0;};G.prototype.Uint32=function(a){return this.$val.Uint32(a);};G.ptr.prototype.PutUint32=function(a,b){var a,b;$unused((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=(((b>>>24>>>0)<<24>>>24)));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=(((b>>>16>>>0)<<24>>>24)));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=(((b>>>8>>>0)<<24>>>24)));(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]=((b<<24>>>24)));};G.prototype.PutUint32=function(a,b){return this.$val.PutUint32(a,b);};G.ptr.prototype.Uint64=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;$unused((7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]));return(b=(c=(d=(e=(f=(g=(h=(new $Uint64(0,(7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]))),i=$shiftLeft64((new $Uint64(0,(6>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+6]))),8),new $Uint64(h.$high|i.$high,(h.$low|i.$low)>>>0)),j=$shiftLeft64((new $Uint64(0,(5>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+5]))),16),new $Uint64(g.$high|j.$high,(g.$low|j.$low)>>>0)),k=$shiftLeft64((new $Uint64(0,(4>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+4]))),24),new $Uint64(f.$high|k.$high,(f.$low|k.$low)>>>0)),l=$shiftLeft64((new $Uint64(0,(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]))),32),new $Uint64(e.$high|l.$high,(e.$low|l.$low)>>>0)),m=$shiftLeft64((new $Uint64(0,(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]))),40),new $Uint64(d.$high|m.$high,(d.$low|m.$low)>>>0)),n=$shiftLeft64((new $Uint64(0,(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]))),48),new $Uint64(c.$high|n.$high,(c.$low|n.$low)>>>0)),o=$shiftLeft64((new $Uint64(0,(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]))),56),new $Uint64(b.$high|o.$high,(b.$low|o.$low)>>>0));};G.prototype.Uint64=function(a){return this.$val.Uint64(a);};G.ptr.prototype.PutUint64=function(a,b){var a,b;$unused((7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]));(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]=(($shiftRightUint64(b,56).$low<<24>>>24)));(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1]=(($shiftRightUint64(b,48).$low<<24>>>24)));(2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2]=(($shiftRightUint64(b,40).$low<<24>>>24)));(3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3]=(($shiftRightUint64(b,32).$low<<24>>>24)));(4>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+4]=(($shiftRightUint64(b,24).$low<<24>>>24)));(5>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+5]=(($shiftRightUint64(b,16).$low<<24>>>24)));(6>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+6]=(($shiftRightUint64(b,8).$low<<24>>>24)));(7>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+7]=((b.$low<<24>>>24)));};G.prototype.PutUint64=function(a,b){return this.$val.PutUint64(a,b);};G.ptr.prototype.String=function(){return\"BigEndian\";};G.prototype.String=function(){return this.$val.String();};G.ptr.prototype.GoString=function(){return\"binary.BigEndian\";};G.prototype.GoString=function(){return this.$val.GoString();};H=function(a,b,c){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,c,ca,cb,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;bu=$f.bu;bv=$f.bv;bw=$f.bw;bx=$f.bx;by=$f.by;bz=$f.bz;c=$f.c;ca=$f.ca;cb=$f.cb;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=P(c);if(!((d===0))){$s=1;continue;}$s=2;continue;case 1:e=$makeSlice(X,d);g=B.ReadFull(a,e);$s=3;case 3:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;h=f[1];if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return h;}i=c;if($assertType(i,Y,true)[1]){$s=4;continue;}if($assertType(i,Z,true)[1]){$s=5;continue;}if($assertType(i,AA,true)[1]){$s=6;continue;}if($assertType(i,AB,true)[1]){$s=7;continue;}if($assertType(i,AC,true)[1]){$s=8;continue;}if($assertType(i,AD,true)[1]){$s=9;continue;}if($assertType(i,AE,true)[1]){$s=10;continue;}if($assertType(i,AF,true)[1]){$s=11;continue;}if($assertType(i,AG,true)[1]){$s=12;continue;}if($assertType(i,AH,true)[1]){$s=13;continue;}if($assertType(i,AI,true)[1]){$s=14;continue;}if($assertType(i,X,true)[1]){$s=15;continue;}if($assertType(i,AJ,true)[1]){$s=16;continue;}if($assertType(i,AK,true)[1]){$s=17;continue;}if($assertType(i,AL,true)[1]){$s=18;continue;}if($assertType(i,AM,true)[1]){$s=19;continue;}if($assertType(i,AN,true)[1]){$s=20;continue;}if($assertType(i,AO,true)[1]){$s=21;continue;}$s=22;continue;case 4:j=i.$val;j.$set(!(((0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0])===0)));$s=22;continue;case 5:k=i.$val;k.$set((((0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0])<<24>>24)));$s=22;continue;case 6:l=i.$val;l.$set((0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]));$s=22;continue;case 7:m=i.$val;ab=b.Uint16(e);$s=23;case 23:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}m.$set(((ab<<16>>16)));$s=22;continue;case 8:n=i.$val;ac=b.Uint16(e);$s=24;case 24:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}n.$set(ac);$s=22;continue;case 9:o=i.$val;ad=b.Uint32(e);$s=25;case 25:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}o.$set(((ad>>0)));$s=22;continue;case 10:p=i.$val;ae=b.Uint32(e);$s=26;case 26:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}p.$set(ae);$s=22;continue;case 11:q=i.$val;ag=b.Uint64(e);$s=27;case 27:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}q.$set(((af=ag,new $Int64(af.$high,af.$low))));$s=22;continue;case 12:r=i.$val;ah=b.Uint64(e);$s=28;case 28:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}r.$set(ah);$s=22;continue;case 13:s=i.$val;ai=e;aj=0;while(true){if(!(aj<ai.$length)){break;}ak=aj;al=((aj<0||aj>=ai.$length)?($throwRuntimeError(\"index out of range\"),undefined):ai.$array[ai.$offset+aj]);((ak<0||ak>=s.$length)?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+ak]=!((al===0)));aj++;}$s=22;continue;case 14:t=i.$val;am=e;an=0;while(true){if(!(an<am.$length)){break;}ao=an;ap=((an<0||an>=am.$length)?($throwRuntimeError(\"index out of range\"),undefined):am.$array[am.$offset+an]);((ao<0||ao>=t.$length)?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+ao]=((ap<<24>>24)));an++;}$s=22;continue;case 15:u=i.$val;$copySlice(u,e);$s=22;continue;case 16:v=i.$val;aq=v;ar=0;case 29:if(!(ar<aq.$length)){$s=30;continue;}as=ar;at=b.Uint16($subslice(e,($imul(2,as))));$s=31;case 31:if($c){$c=false;at=at.$blk();}if(at&&at.$blk!==undefined){break s;}((as<0||as>=v.$length)?($throwRuntimeError(\"index out of range\"),undefined):v.$array[v.$offset+as]=((at<<16>>16)));ar++;$s=29;continue;case 30:$s=22;continue;case 17:w=i.$val;au=w;av=0;case 32:if(!(av<au.$length)){$s=33;continue;}aw=av;ax=b.Uint16($subslice(e,($imul(2,aw))));$s=34;case 34:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}((aw<0||aw>=w.$length)?($throwRuntimeError(\"index out of range\"),undefined):w.$array[w.$offset+aw]=ax);av++;$s=32;continue;case 33:$s=22;continue;case 18:x=i.$val;ay=x;az=0;case 35:if(!(az<ay.$length)){$s=36;continue;}ba=az;bb=b.Uint32($subslice(e,($imul(4,ba))));$s=37;case 37:if($c){$c=false;bb=bb.$blk();}if(bb&&bb.$blk!==undefined){break s;}((ba<0||ba>=x.$length)?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+ba]=((bb>>0)));az++;$s=35;continue;case 36:$s=22;continue;case 19:y=i.$val;bc=y;bd=0;case 38:if(!(bd<bc.$length)){$s=39;continue;}be=bd;bf=b.Uint32($subslice(e,($imul(4,be))));$s=40;case 40:if($c){$c=false;bf=bf.$blk();}if(bf&&bf.$blk!==undefined){break s;}((be<0||be>=y.$length)?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+be]=bf);bd++;$s=38;continue;case 39:$s=22;continue;case 20:z=i.$val;bg=z;bh=0;case 41:if(!(bh<bg.$length)){$s=42;continue;}bi=bh;bk=b.Uint64($subslice(e,($imul(8,bi))));$s=43;case 43:if($c){$c=false;bk=bk.$blk();}if(bk&&bk.$blk!==undefined){break s;}((bi<0||bi>=z.$length)?($throwRuntimeError(\"index out of range\"),undefined):z.$array[z.$offset+bi]=((bj=bk,new $Int64(bj.$high,bj.$low))));bh++;$s=41;continue;case 42:$s=22;continue;case 21:aa=i.$val;bl=aa;bm=0;case 44:if(!(bm<bl.$length)){$s=45;continue;}bn=bm;bo=b.Uint64($subslice(e,($imul(8,bn))));$s=46;case 46:if($c){$c=false;bo=bo.$blk();}if(bo&&bo.$blk!==undefined){break s;}((bn<0||bn>=aa.$length)?($throwRuntimeError(\"index out of range\"),undefined):aa.$array[aa.$offset+bn]=bo);bm++;$s=44;continue;case 45:case 22:$s=-1;return $ifaceNil;case 2:bp=D.ValueOf(c);$s=47;case 47:if($c){$c=false;bp=bp.$blk();}if(bp&&bp.$blk!==undefined){break s;}bq=bp;br=-1;bs=$clone(bq,D.Value).Kind();if(bs===(22)){$s=49;continue;}if(bs===(23)){$s=50;continue;}$s=51;continue;case 49:bt=$clone(bq,D.Value).Elem();$s=52;case 52:if($c){$c=false;bt=bt.$blk();}if(bt&&bt.$blk!==undefined){break s;}bq=bt;bu=K($clone(bq,D.Value));$s=53;case 53:if($c){$c=false;bu=bu.$blk();}if(bu&&bu.$blk!==undefined){break s;}br=bu;$s=51;continue;case 50:bv=K($clone(bq,D.Value));$s=54;case 54:if($c){$c=false;bv=bv.$blk();}if(bv&&bv.$blk!==undefined){break s;}br=bv;case 51:case 48:if(br<0){$s=55;continue;}$s=56;continue;case 55:bw=D.TypeOf(c).String();$s=57;case 57:if($c){$c=false;bw=bw.$blk();}if(bw&&bw.$blk!==undefined){break s;}bx=A.New(\"binary.Read: invalid type \"+bw);$s=58;case 58:if($c){$c=false;bx=bx.$blk();}if(bx&&bx.$blk!==undefined){break s;}$s=-1;return bx;case 56:by=new N.ptr(b,$makeSlice(X,br),0);ca=B.ReadFull(a,by.buf);$s=59;case 59:if($c){$c=false;ca=ca.$blk();}if(ca&&ca.$blk!==undefined){break s;}bz=ca;cb=bz[1];if(!($interfaceIsEqual(cb,$ifaceNil))){$s=-1;return cb;}$r=by.value($clone(bq,D.Value));$s=60;case 60:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:H};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.bu=bu;$f.bv=bv;$f.bw=bw;$f.bx=bx;$f.by=by;$f.bz=bz;$f.c=c;$f.ca=ca;$f.cb=cb;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Read=H;I=function(a,b,c){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz,c,ca,cb,cc,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;bo=$f.bo;bp=$f.bp;bq=$f.bq;br=$f.br;bs=$f.bs;bt=$f.bt;bu=$f.bu;bv=$f.bv;bw=$f.bw;bx=$f.bx;by=$f.by;bz=$f.bz;c=$f.c;ca=$f.ca;cb=$f.cb;cc=$f.cc;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=P(c);if(!((d===0))){$s=1;continue;}$s=2;continue;case 1:e=$makeSlice(X,d);f=c;if($assertType(f,Y,true)[1]){$s=3;continue;}if($assertType(f,$Bool,true)[1]){$s=4;continue;}if($assertType(f,AH,true)[1]){$s=5;continue;}if($assertType(f,Z,true)[1]){$s=6;continue;}if($assertType(f,$Int8,true)[1]){$s=7;continue;}if($assertType(f,AI,true)[1]){$s=8;continue;}if($assertType(f,AA,true)[1]){$s=9;continue;}if($assertType(f,$Uint8,true)[1]){$s=10;continue;}if($assertType(f,X,true)[1]){$s=11;continue;}if($assertType(f,AB,true)[1]){$s=12;continue;}if($assertType(f,$Int16,true)[1]){$s=13;continue;}if($assertType(f,AJ,true)[1]){$s=14;continue;}if($assertType(f,AC,true)[1]){$s=15;continue;}if($assertType(f,$Uint16,true)[1]){$s=16;continue;}if($assertType(f,AK,true)[1]){$s=17;continue;}if($assertType(f,AD,true)[1]){$s=18;continue;}if($assertType(f,$Int32,true)[1]){$s=19;continue;}if($assertType(f,AL,true)[1]){$s=20;continue;}if($assertType(f,AE,true)[1]){$s=21;continue;}if($assertType(f,$Uint32,true)[1]){$s=22;continue;}if($assertType(f,AM,true)[1]){$s=23;continue;}if($assertType(f,AF,true)[1]){$s=24;continue;}if($assertType(f,$Int64,true)[1]){$s=25;continue;}if($assertType(f,AN,true)[1]){$s=26;continue;}if($assertType(f,AG,true)[1]){$s=27;continue;}if($assertType(f,$Uint64,true)[1]){$s=28;continue;}if($assertType(f,AO,true)[1]){$s=29;continue;}$s=30;continue;case 3:g=f.$val;if(g.$get()){(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=1);}else{(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=0);}$s=30;continue;case 4:h=f.$val;if(h){(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=1);}else{(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=0);}$s=30;continue;case 5:i=f.$val;ah=i;ai=0;while(true){if(!(ai<ah.$length)){break;}aj=ai;ak=((ai<0||ai>=ah.$length)?($throwRuntimeError(\"index out of range\"),undefined):ah.$array[ah.$offset+ai]);if(ak){((aj<0||aj>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+aj]=1);}else{((aj<0||aj>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+aj]=0);}ai++;}$s=30;continue;case 6:j=f.$val;(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=((j.$get()<<24>>>24)));$s=30;continue;case 7:k=f.$val;(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=((k<<24>>>24)));$s=30;continue;case 8:l=f.$val;al=l;am=0;while(true){if(!(am<al.$length)){break;}an=am;ao=((am<0||am>=al.$length)?($throwRuntimeError(\"index out of range\"),undefined):al.$array[al.$offset+am]);((an<0||an>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+an]=((ao<<24>>>24)));am++;}$s=30;continue;case 9:m=f.$val;(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=m.$get());$s=30;continue;case 10:n=f.$val;(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=n);$s=30;continue;case 11:o=f.$val;e=o;$s=30;continue;case 12:p=f.$val;$r=b.PutUint16(e,((p.$get()<<16>>>16)));$s=31;case 31:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 13:q=f.$val;$r=b.PutUint16(e,((q<<16>>>16)));$s=32;case 32:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 14:r=f.$val;ap=r;aq=0;case 33:if(!(aq<ap.$length)){$s=34;continue;}ar=aq;as=((aq<0||aq>=ap.$length)?($throwRuntimeError(\"index out of range\"),undefined):ap.$array[ap.$offset+aq]);$r=b.PutUint16($subslice(e,($imul(2,ar))),((as<<16>>>16)));$s=35;case 35:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}aq++;$s=33;continue;case 34:$s=30;continue;case 15:s=f.$val;$r=b.PutUint16(e,s.$get());$s=36;case 36:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 16:t=f.$val;$r=b.PutUint16(e,t);$s=37;case 37:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 17:u=f.$val;at=u;au=0;case 38:if(!(au<at.$length)){$s=39;continue;}av=au;aw=((au<0||au>=at.$length)?($throwRuntimeError(\"index out of range\"),undefined):at.$array[at.$offset+au]);$r=b.PutUint16($subslice(e,($imul(2,av))),aw);$s=40;case 40:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}au++;$s=38;continue;case 39:$s=30;continue;case 18:v=f.$val;$r=b.PutUint32(e,((v.$get()>>>0)));$s=41;case 41:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 19:w=f.$val;$r=b.PutUint32(e,((w>>>0)));$s=42;case 42:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 20:x=f.$val;ax=x;ay=0;case 43:if(!(ay<ax.$length)){$s=44;continue;}az=ay;ba=((ay<0||ay>=ax.$length)?($throwRuntimeError(\"index out of range\"),undefined):ax.$array[ax.$offset+ay]);$r=b.PutUint32($subslice(e,($imul(4,az))),((ba>>>0)));$s=45;case 45:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}ay++;$s=43;continue;case 44:$s=30;continue;case 21:y=f.$val;$r=b.PutUint32(e,y.$get());$s=46;case 46:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 22:z=f.$val;$r=b.PutUint32(e,z);$s=47;case 47:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 23:aa=f.$val;bb=aa;bc=0;case 48:if(!(bc<bb.$length)){$s=49;continue;}bd=bc;be=((bc<0||bc>=bb.$length)?($throwRuntimeError(\"index out of range\"),undefined):bb.$array[bb.$offset+bc]);$r=b.PutUint32($subslice(e,($imul(4,bd))),be);$s=50;case 50:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}bc++;$s=48;continue;case 49:$s=30;continue;case 24:ab=f.$val;$r=b.PutUint64(e,((bf=ab.$get(),new $Uint64(bf.$high,bf.$low))));$s=51;case 51:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 25:ac=f.$val;$r=b.PutUint64(e,(new $Uint64(ac.$high,ac.$low)));$s=52;case 52:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 26:ad=f.$val;bg=ad;bh=0;case 53:if(!(bh<bg.$length)){$s=54;continue;}bi=bh;bj=((bh<0||bh>=bg.$length)?($throwRuntimeError(\"index out of range\"),undefined):bg.$array[bg.$offset+bh]);$r=b.PutUint64($subslice(e,($imul(8,bi))),(new $Uint64(bj.$high,bj.$low)));$s=55;case 55:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}bh++;$s=53;continue;case 54:$s=30;continue;case 27:ae=f.$val;$r=b.PutUint64(e,ae.$get());$s=56;case 56:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 28:af=f.$val;$r=b.PutUint64(e,af);$s=57;case 57:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=30;continue;case 29:ag=f.$val;bk=ag;bl=0;case 58:if(!(bl<bk.$length)){$s=59;continue;}bm=bl;bn=((bl<0||bl>=bk.$length)?($throwRuntimeError(\"index out of range\"),undefined):bk.$array[bk.$offset+bl]);$r=b.PutUint64($subslice(e,($imul(8,bm))),bn);$s=60;case 60:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}bl++;$s=58;continue;case 59:case 30:bp=a.Write(e);$s=61;case 61:if($c){$c=false;bp=bp.$blk();}if(bp&&bp.$blk!==undefined){break s;}bo=bp;bq=bo[1];$s=-1;return bq;case 2:br=D.ValueOf(c);$s=62;case 62:if($c){$c=false;br=br.$blk();}if(br&&br.$blk!==undefined){break s;}bs=D.Indirect($clone(br,D.Value));$s=63;case 63:if($c){$c=false;bs=bs.$blk();}if(bs&&bs.$blk!==undefined){break s;}bt=bs;bu=K($clone(bt,D.Value));$s=64;case 64:if($c){$c=false;bu=bu.$blk();}if(bu&&bu.$blk!==undefined){break s;}bv=bu;if(bv<0){$s=65;continue;}$s=66;continue;case 65:bw=D.TypeOf(c).String();$s=67;case 67:if($c){$c=false;bw=bw.$blk();}if(bw&&bw.$blk!==undefined){break s;}bx=A.New(\"binary.Write: invalid type \"+bw);$s=68;case 68:if($c){$c=false;bx=bx.$blk();}if(bx&&bx.$blk!==undefined){break s;}$s=-1;return bx;case 66:by=$makeSlice(X,bv);bz=new O.ptr(b,by,0);$r=bz.value($clone(bt,D.Value));$s=69;case 69:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}cb=a.Write(by);$s=70;case 70:if($c){$c=false;cb=cb.$blk();}if(cb&&cb.$blk!==undefined){break s;}ca=cb;cc=ca[1];$s=-1;return cc;}return;}if($f===undefined){$f={$blk:I};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.bo=bo;$f.bp=bp;$f.bq=bq;$f.br=br;$f.bs=bs;$f.bt=bt;$f.bu=bu;$f.bv=bv;$f.bw=bw;$f.bx=bx;$f.by=by;$f.bz=bz;$f.c=c;$f.ca=ca;$f.cb=cb;$f.cc=cc;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Write=I;J=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=D.ValueOf(a);$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=D.Indirect($clone(b,D.Value));$s=2;case 2:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=K($clone(c,D.Value));$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:J};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Size=J;K=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if($clone(a,D.Value).Kind()===23){$s=1;continue;}$s=2;continue;case 1:b=$clone(a,D.Value).Type().Elem();$s=3;case 3:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=L(b);$s=4;case 4:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;if(d>=0){$s=-1;return $imul(d,$clone(a,D.Value).Len());}$s=-1;return-1;case 2:e=L($clone(a,D.Value).Type());$s=5;case 5:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:K};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};L=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=a.Kind();$s=2;case 2:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;if(c===(17)){$s=3;continue;}if(c===(25)){$s=4;continue;}if((c===(1))||(c===(8))||(c===(9))||(c===(10))||(c===(11))||(c===(3))||(c===(4))||(c===(5))||(c===(6))||(c===(13))||(c===(14))||(c===(15))||(c===(16))){$s=5;continue;}$s=6;continue;case 3:d=a.Elem();$s=7;case 7:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=L(d);$s=8;case 8:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(f>=0){$s=9;continue;}$s=10;continue;case 9:g=a.Len();$s=11;case 11:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}$s=-1;return $imul(f,g);case 10:$s=6;continue;case 4:h=0;i=0;k=a.NumField();$s=12;case 12:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=i;m=j;case 13:if(!(l<m)){$s=14;continue;}n=a.Field(l);$s=15;case 15:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=L(n.Type);$s=16;case 16:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}p=o;if(p<0){$s=-1;return-1;}h=h+(p)>>0;l=l+(1)>>0;$s=13;continue;case 14:$s=-1;return h;case 5:q=a.Size();$s=17;case 17:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}$s=-1;return((q>>0));case 6:case 1:$s=-1;return-1;}return;}if($f===undefined){$f={$blk:L};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};N.ptr.prototype.bool=function(){var a,b,c,d;a=this;d=(b=a.buf,c=a.offset,((c<0||c>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+c]));a.offset=a.offset+(1)>>0;return!((d===0));};N.prototype.bool=function(){return this.$val.bool();};O.ptr.prototype.bool=function(a){var a,b,c,d,e,f;b=this;if(a){(c=b.buf,d=b.offset,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=1));}else{(e=b.buf,f=b.offset,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]=0));}b.offset=b.offset+(1)>>0;};O.prototype.bool=function(a){return this.$val.bool(a);};N.ptr.prototype.uint8=function(){var a,b,c,d;a=this;d=(b=a.buf,c=a.offset,((c<0||c>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+c]));a.offset=a.offset+(1)>>0;return d;};N.prototype.uint8=function(){return this.$val.uint8();};O.ptr.prototype.uint8=function(a){var a,b,c,d;b=this;(c=b.buf,d=b.offset,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=a));b.offset=b.offset+(1)>>0;};O.prototype.uint8=function(a){return this.$val.uint8(a);};N.ptr.prototype.uint16=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.order.Uint16($subslice(a.buf,a.offset,(a.offset+2>>0)));$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;a.offset=a.offset+(2)>>0;$s=-1;return c;}return;}if($f===undefined){$f={$blk:N.ptr.prototype.uint16};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.uint16=function(){return this.$val.uint16();};O.ptr.prototype.uint16=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.order.PutUint16($subslice(b.buf,b.offset,(b.offset+2>>0)),a);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b.offset=b.offset+(2)>>0;$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.uint16};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.uint16=function(a){return this.$val.uint16(a);};N.ptr.prototype.uint32=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.order.Uint32($subslice(a.buf,a.offset,(a.offset+4>>0)));$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;a.offset=a.offset+(4)>>0;$s=-1;return c;}return;}if($f===undefined){$f={$blk:N.ptr.prototype.uint32};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.uint32=function(){return this.$val.uint32();};O.ptr.prototype.uint32=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.order.PutUint32($subslice(b.buf,b.offset,(b.offset+4>>0)),a);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b.offset=b.offset+(4)>>0;$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.uint32};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.uint32=function(a){return this.$val.uint32(a);};N.ptr.prototype.uint64=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.order.Uint64($subslice(a.buf,a.offset,(a.offset+8>>0)));$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;a.offset=a.offset+(8)>>0;$s=-1;return c;}return;}if($f===undefined){$f={$blk:N.ptr.prototype.uint64};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.uint64=function(){return this.$val.uint64();};O.ptr.prototype.uint64=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.order.PutUint64($subslice(b.buf,b.offset,(b.offset+8>>0)),a);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b.offset=b.offset+(8)>>0;$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.uint64};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.uint64=function(a){return this.$val.uint64(a);};N.ptr.prototype.int8=function(){var a;a=this;return((a.uint8()<<24>>24));};N.prototype.int8=function(){return this.$val.int8();};O.ptr.prototype.int8=function(a){var a,b;b=this;b.uint8(((a<<24>>>24)));};O.prototype.int8=function(a){return this.$val.int8(a);};N.ptr.prototype.int16=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.uint16();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return((b<<16>>16));}return;}if($f===undefined){$f={$blk:N.ptr.prototype.int16};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.int16=function(){return this.$val.int16();};O.ptr.prototype.int16=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.uint16(((a<<16>>>16)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.int16};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.int16=function(a){return this.$val.int16(a);};N.ptr.prototype.int32=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.uint32();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return((b>>0));}return;}if($f===undefined){$f={$blk:N.ptr.prototype.int32};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.int32=function(){return this.$val.int32();};O.ptr.prototype.int32=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.uint32(((a>>>0)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.int32};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.int32=function(a){return this.$val.int32(a);};N.ptr.prototype.int64=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;c=a.uint64();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return((b=c,new $Int64(b.$high,b.$low)));}return;}if($f===undefined){$f={$blk:N.ptr.prototype.int64};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.int64=function(){return this.$val.int64();};O.ptr.prototype.int64=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.uint64((new $Uint64(a.$high,a.$low)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.int64};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.int64=function(a){return this.$val.int64(a);};N.ptr.prototype.value=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=$clone(a,D.Value).Kind();if(c===(17)){$s=2;continue;}if(c===(25)){$s=3;continue;}if(c===(23)){$s=4;continue;}if(c===(1)){$s=5;continue;}if(c===(3)){$s=6;continue;}if(c===(4)){$s=7;continue;}if(c===(5)){$s=8;continue;}if(c===(6)){$s=9;continue;}if(c===(8)){$s=10;continue;}if(c===(9)){$s=11;continue;}if(c===(10)){$s=12;continue;}if(c===(11)){$s=13;continue;}if(c===(13)){$s=14;continue;}if(c===(14)){$s=15;continue;}if(c===(15)){$s=16;continue;}if(c===(16)){$s=17;continue;}$s=18;continue;case 2:d=$clone(a,D.Value).Len();e=0;case 19:if(!(e<d)){$s=20;continue;}f=$clone(a,D.Value).Index(e);$s=21;case 21:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$r=b.value($clone(f,D.Value));$s=22;case 22:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e+(1)>>0;$s=19;continue;case 20:$s=18;continue;case 3:g=$clone(a,D.Value).Type();h=$clone(a,D.Value).NumField();i=0;case 23:if(!(i<h)){$s=24;continue;}j=$clone(a,D.Value).Field(i);$s=25;case 25:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;if($clone(k,D.Value).CanSet()){l=true;$s=29;continue s;}m=g.Field(i);$s=30;case 30:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=!(m.Name===\"_\");case 29:if(l){$s=26;continue;}$s=27;continue;case 26:$r=b.value($clone(k,D.Value));$s=31;case 31:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=28;continue;case 27:$r=b.skip($clone(k,D.Value));$s=32;case 32:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 28:i=i+(1)>>0;$s=23;continue;case 24:$s=18;continue;case 4:n=$clone(a,D.Value).Len();o=0;case 33:if(!(o<n)){$s=34;continue;}p=$clone(a,D.Value).Index(o);$s=35;case 35:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}$r=b.value($clone(p,D.Value));$s=36;case 36:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}o=o+(1)>>0;$s=33;continue;case 34:$s=18;continue;case 5:$clone(a,D.Value).SetBool(b.bool());$s=18;continue;case 6:$clone(a,D.Value).SetInt((new $Int64(0,b.int8())));$s=18;continue;case 7:q=b.int16();$s=37;case 37:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetInt((new $Int64(0,q)));$s=38;case 38:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 8:r=b.int32();$s=39;case 39:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetInt((new $Int64(0,r)));$s=40;case 40:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 9:s=b.int64();$s=41;case 41:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetInt(s);$s=42;case 42:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 10:$clone(a,D.Value).SetUint((new $Uint64(0,b.uint8())));$s=18;continue;case 11:t=b.uint16();$s=43;case 43:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetUint((new $Uint64(0,t)));$s=44;case 44:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 12:u=b.uint32();$s=45;case 45:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetUint((new $Uint64(0,u)));$s=46;case 46:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 13:v=b.uint64();$s=47;case 47:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetUint(v);$s=48;case 48:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 14:w=b.uint32();$s=49;case 49:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}x=C.Float32frombits(w);$s=50;case 50:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetFloat((x));$s=51;case 51:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 15:y=b.uint64();$s=52;case 52:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}z=C.Float64frombits(y);$s=53;case 53:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}$r=$clone(a,D.Value).SetFloat(z);$s=54;case 54:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 16:aa=b.uint32();$s=55;case 55:if($c){$c=false;aa=aa.$blk();}if(aa&&aa.$blk!==undefined){break s;}ab=C.Float32frombits(aa);$s=56;case 56:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}ac=(ab);ad=b.uint32();$s=57;case 57:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ae=C.Float32frombits(ad);$s=58;case 58:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}af=(ae);$r=$clone(a,D.Value).SetComplex(new $Complex128(ac,af));$s=59;case 59:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=18;continue;case 17:ag=b.uint64();$s=60;case 60:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}ah=C.Float64frombits(ag);$s=61;case 61:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ai=ah;aj=b.uint64();$s=62;case 62:if($c){$c=false;aj=aj.$blk();}if(aj&&aj.$blk!==undefined){break s;}ak=C.Float64frombits(aj);$s=63;case 63:if($c){$c=false;ak=ak.$blk();}if(ak&&ak.$blk!==undefined){break s;}al=ak;$r=$clone(a,D.Value).SetComplex(new $Complex128(ai,al));$s=64;case 64:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 18:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:N.ptr.prototype.value};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.value=function(a){return this.$val.value(a);};O.ptr.prototype.value=function(a){var a,aa,ab,ac,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=$clone(a,D.Value).Kind();if(c===(17)){$s=2;continue;}if(c===(25)){$s=3;continue;}if(c===(23)){$s=4;continue;}if(c===(1)){$s=5;continue;}if((c===(2))||(c===(3))||(c===(4))||(c===(5))||(c===(6))){$s=6;continue;}if((c===(7))||(c===(8))||(c===(9))||(c===(10))||(c===(11))||(c===(12))){$s=7;continue;}if((c===(13))||(c===(14))){$s=8;continue;}if((c===(15))||(c===(16))){$s=9;continue;}$s=10;continue;case 2:d=$clone(a,D.Value).Len();e=0;case 11:if(!(e<d)){$s=12;continue;}f=$clone(a,D.Value).Index(e);$s=13;case 13:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$r=b.value($clone(f,D.Value));$s=14;case 14:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}e=e+(1)>>0;$s=11;continue;case 12:$s=10;continue;case 3:g=$clone(a,D.Value).Type();h=$clone(a,D.Value).NumField();i=0;case 15:if(!(i<h)){$s=16;continue;}j=$clone(a,D.Value).Field(i);$s=17;case 17:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;if($clone(k,D.Value).CanSet()){l=true;$s=21;continue s;}m=g.Field(i);$s=22;case 22:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=!(m.Name===\"_\");case 21:if(l){$s=18;continue;}$s=19;continue;case 18:$r=b.value($clone(k,D.Value));$s=23;case 23:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=20;continue;case 19:$r=b.skip($clone(k,D.Value));$s=24;case 24:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 20:i=i+(1)>>0;$s=15;continue;case 16:$s=10;continue;case 4:n=$clone(a,D.Value).Len();o=0;case 25:if(!(o<n)){$s=26;continue;}p=$clone(a,D.Value).Index(o);$s=27;case 27:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}$r=b.value($clone(p,D.Value));$s=28;case 28:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}o=o+(1)>>0;$s=25;continue;case 26:$s=10;continue;case 5:b.bool($clone(a,D.Value).Bool());$s=10;continue;case 6:q=$clone(a,D.Value).Type().Kind();$s=30;case 30:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=q;if(r===(3)){$s=31;continue;}if(r===(4)){$s=32;continue;}if(r===(5)){$s=33;continue;}if(r===(6)){$s=34;continue;}$s=35;continue;case 31:b.int8((((s=$clone(a,D.Value).Int(),s.$low+((s.$high>>31)*4294967296))<<24>>24)));$s=35;continue;case 32:$r=b.int16((((t=$clone(a,D.Value).Int(),t.$low+((t.$high>>31)*4294967296))<<16>>16)));$s=36;case 36:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=35;continue;case 33:$r=b.int32((((u=$clone(a,D.Value).Int(),u.$low+((u.$high>>31)*4294967296))>>0)));$s=37;case 37:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=35;continue;case 34:$r=b.int64($clone(a,D.Value).Int());$s=38;case 38:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 35:case 29:$s=10;continue;case 7:v=$clone(a,D.Value).Type().Kind();$s=40;case 40:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}w=v;if(w===(8)){$s=41;continue;}if(w===(9)){$s=42;continue;}if(w===(10)){$s=43;continue;}if(w===(11)){$s=44;continue;}$s=45;continue;case 41:b.uint8((($clone(a,D.Value).Uint().$low<<24>>>24)));$s=45;continue;case 42:$r=b.uint16((($clone(a,D.Value).Uint().$low<<16>>>16)));$s=46;case 46:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=45;continue;case 43:$r=b.uint32((($clone(a,D.Value).Uint().$low>>>0)));$s=47;case 47:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=45;continue;case 44:$r=b.uint64($clone(a,D.Value).Uint());$s=48;case 48:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 45:case 39:$s=10;continue;case 8:x=$clone(a,D.Value).Type().Kind();$s=50;case 50:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}y=x;if(y===(13)){$s=51;continue;}if(y===(14)){$s=52;continue;}$s=53;continue;case 51:$r=b.uint32(C.Float32bits(($fround($clone(a,D.Value).Float()))));$s=54;case 54:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=53;continue;case 52:$r=b.uint64(C.Float64bits($clone(a,D.Value).Float()));$s=55;case 55:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 53:case 49:$s=10;continue;case 9:z=$clone(a,D.Value).Type().Kind();$s=57;case 57:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}aa=z;if(aa===(15)){$s=58;continue;}if(aa===(16)){$s=59;continue;}$s=60;continue;case 58:ab=$clone(a,D.Value).Complex();$r=b.uint32(C.Float32bits(($fround(ab.$real))));$s=61;case 61:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=b.uint32(C.Float32bits(($fround(ab.$imag))));$s=62;case 62:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=60;continue;case 59:ac=$clone(a,D.Value).Complex();$r=b.uint64(C.Float64bits(ac.$real));$s=63;case 63:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=b.uint64(C.Float64bits(ac.$imag));$s=64;case 64:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 60:case 56:case 10:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.value};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.value=function(a){return this.$val.value(a);};N.ptr.prototype.skip=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=K($clone(a,D.Value));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}b.offset=b.offset+(c)>>0;$s=-1;return;}return;}if($f===undefined){$f={$blk:N.ptr.prototype.skip};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.skip=function(a){return this.$val.skip(a);};O.ptr.prototype.skip=function(a){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=K($clone(a,D.Value));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=$subslice(b.buf,b.offset,(b.offset+d>>0));f=e;g=0;while(true){if(!(g<f.$length)){break;}h=g;((h<0||h>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+h]=0);g++;}b.offset=b.offset+(d)>>0;$s=-1;return;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.skip};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.skip=function(a){return this.$val.skip(a);};P=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o;b=a;if($assertType(b,$Bool,true)[1]||$assertType(b,$Int8,true)[1]||$assertType(b,$Uint8,true)[1]||$assertType(b,Y,true)[1]||$assertType(b,Z,true)[1]||$assertType(b,AA,true)[1]){c=b;return 1;}else if($assertType(b,AH,true)[1]){d=b.$val;return d.$length;}else if($assertType(b,AI,true)[1]){e=b.$val;return e.$length;}else if($assertType(b,X,true)[1]){f=b.$val;return f.$length;}else if($assertType(b,$Int16,true)[1]||$assertType(b,$Uint16,true)[1]||$assertType(b,AB,true)[1]||$assertType(b,AC,true)[1]){g=b;return 2;}else if($assertType(b,AJ,true)[1]){h=b.$val;return $imul(2,h.$length);}else if($assertType(b,AK,true)[1]){i=b.$val;return $imul(2,i.$length);}else if($assertType(b,$Int32,true)[1]||$assertType(b,$Uint32,true)[1]||$assertType(b,AD,true)[1]||$assertType(b,AE,true)[1]){j=b;return 4;}else if($assertType(b,AL,true)[1]){k=b.$val;return $imul(4,k.$length);}else if($assertType(b,AM,true)[1]){l=b.$val;return $imul(4,l.$length);}else if($assertType(b,$Int64,true)[1]||$assertType(b,$Uint64,true)[1]||$assertType(b,AF,true)[1]||$assertType(b,AG,true)[1]){m=b;return 8;}else if($assertType(b,AN,true)[1]){n=b.$val;return $imul(8,n.$length);}else if($assertType(b,AO,true)[1]){o=b.$val;return $imul(8,o.$length);}return 0;};F.methods=[{prop:\"Uint16\",name:\"Uint16\",pkg:\"\",typ:$funcType([X],[$Uint16],false)},{prop:\"PutUint16\",name:\"PutUint16\",pkg:\"\",typ:$funcType([X,$Uint16],[],false)},{prop:\"Uint32\",name:\"Uint32\",pkg:\"\",typ:$funcType([X],[$Uint32],false)},{prop:\"PutUint32\",name:\"PutUint32\",pkg:\"\",typ:$funcType([X,$Uint32],[],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([X],[$Uint64],false)},{prop:\"PutUint64\",name:\"PutUint64\",pkg:\"\",typ:$funcType([X,$Uint64],[],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"GoString\",name:\"GoString\",pkg:\"\",typ:$funcType([],[$String],false)}];G.methods=[{prop:\"Uint16\",name:\"Uint16\",pkg:\"\",typ:$funcType([X],[$Uint16],false)},{prop:\"PutUint16\",name:\"PutUint16\",pkg:\"\",typ:$funcType([X,$Uint16],[],false)},{prop:\"Uint32\",name:\"Uint32\",pkg:\"\",typ:$funcType([X],[$Uint32],false)},{prop:\"PutUint32\",name:\"PutUint32\",pkg:\"\",typ:$funcType([X,$Uint32],[],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([X],[$Uint64],false)},{prop:\"PutUint64\",name:\"PutUint64\",pkg:\"\",typ:$funcType([X,$Uint64],[],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"GoString\",name:\"GoString\",pkg:\"\",typ:$funcType([],[$String],false)}];AP.methods=[{prop:\"bool\",name:\"bool\",pkg:\"encoding/binary\",typ:$funcType([],[$Bool],false)},{prop:\"uint8\",name:\"uint8\",pkg:\"encoding/binary\",typ:$funcType([],[$Uint8],false)},{prop:\"uint16\",name:\"uint16\",pkg:\"encoding/binary\",typ:$funcType([],[$Uint16],false)},{prop:\"uint32\",name:\"uint32\",pkg:\"encoding/binary\",typ:$funcType([],[$Uint32],false)},{prop:\"uint64\",name:\"uint64\",pkg:\"encoding/binary\",typ:$funcType([],[$Uint64],false)},{prop:\"int8\",name:\"int8\",pkg:\"encoding/binary\",typ:$funcType([],[$Int8],false)},{prop:\"int16\",name:\"int16\",pkg:\"encoding/binary\",typ:$funcType([],[$Int16],false)},{prop:\"int32\",name:\"int32\",pkg:\"encoding/binary\",typ:$funcType([],[$Int32],false)},{prop:\"int64\",name:\"int64\",pkg:\"encoding/binary\",typ:$funcType([],[$Int64],false)},{prop:\"value\",name:\"value\",pkg:\"encoding/binary\",typ:$funcType([D.Value],[],false)},{prop:\"skip\",name:\"skip\",pkg:\"encoding/binary\",typ:$funcType([D.Value],[],false)}];AQ.methods=[{prop:\"bool\",name:\"bool\",pkg:\"encoding/binary\",typ:$funcType([$Bool],[],false)},{prop:\"uint8\",name:\"uint8\",pkg:\"encoding/binary\",typ:$funcType([$Uint8],[],false)},{prop:\"uint16\",name:\"uint16\",pkg:\"encoding/binary\",typ:$funcType([$Uint16],[],false)},{prop:\"uint32\",name:\"uint32\",pkg:\"encoding/binary\",typ:$funcType([$Uint32],[],false)},{prop:\"uint64\",name:\"uint64\",pkg:\"encoding/binary\",typ:$funcType([$Uint64],[],false)},{prop:\"int8\",name:\"int8\",pkg:\"encoding/binary\",typ:$funcType([$Int8],[],false)},{prop:\"int16\",name:\"int16\",pkg:\"encoding/binary\",typ:$funcType([$Int16],[],false)},{prop:\"int32\",name:\"int32\",pkg:\"encoding/binary\",typ:$funcType([$Int32],[],false)},{prop:\"int64\",name:\"int64\",pkg:\"encoding/binary\",typ:$funcType([$Int64],[],false)},{prop:\"value\",name:\"value\",pkg:\"encoding/binary\",typ:$funcType([D.Value],[],false)},{prop:\"skip\",name:\"skip\",pkg:\"encoding/binary\",typ:$funcType([D.Value],[],false)}];E.init([{prop:\"PutUint16\",name:\"PutUint16\",pkg:\"\",typ:$funcType([X,$Uint16],[],false)},{prop:\"PutUint32\",name:\"PutUint32\",pkg:\"\",typ:$funcType([X,$Uint32],[],false)},{prop:\"PutUint64\",name:\"PutUint64\",pkg:\"\",typ:$funcType([X,$Uint64],[],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Uint16\",name:\"Uint16\",pkg:\"\",typ:$funcType([X],[$Uint16],false)},{prop:\"Uint32\",name:\"Uint32\",pkg:\"\",typ:$funcType([X],[$Uint32],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([X],[$Uint64],false)}]);F.init(\"\",[]);G.init(\"\",[]);N.init(\"encoding/binary\",[{prop:\"order\",name:\"order\",embedded:false,exported:false,typ:E,tag:\"\"},{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:X,tag:\"\"},{prop:\"offset\",name:\"offset\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);O.init(\"encoding/binary\",[{prop:\"order\",name:\"order\",embedded:false,exported:false,typ:E,tag:\"\"},{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:X,tag:\"\"},{prop:\"offset\",name:\"offset\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.LittleEndian=new F.ptr();$pkg.BigEndian=new G.ptr();U=A.New(\"binary: varint overflows a 64-bit integer\");}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"strings\"]=(function(){var $pkg={},$init,C,B,F,D,E,G,A,L,BT,CG,CH,CI,CS,CV,H,I,J,K,AH,AK,AM,AN,AO,AQ,AR,AS,AU,AZ,BA,BB,BC,BF,BU,CA;C=$packages[\"errors\"];B=$packages[\"github.com/gopherjs/gopherjs/js\"];F=$packages[\"internal/bytealg\"];D=$packages[\"io\"];E=$packages[\"sync\"];G=$packages[\"unicode\"];A=$packages[\"unicode/utf8\"];L=$pkg.Builder=$newType(0,$kindStruct,\"strings.Builder\",true,\"strings\",true,function(addr_,buf_){this.$val=this;if(arguments.length===0){this.addr=CG.nil;this.buf=CH.nil;return;}this.addr=addr_;this.buf=buf_;});BT=$pkg.asciiSet=$newType(32,$kindArray,\"strings.asciiSet\",true,\"strings\",false,null);CG=$ptrType(L);CH=$sliceType($Uint8);CI=$sliceType($String);CS=$ptrType(BT);CV=$arrayType($Uint32,8);H=function(e,f){var e,f;return $parseInt(e.indexOf($global.String.fromCharCode(f)))>>0;};$pkg.IndexByte=H;I=function(e,f){var e,f;return $parseInt(e.indexOf(f))>>0;};$pkg.Index=I;J=function(e,f){var e,f;return $parseInt(e.lastIndexOf(f))>>0;};$pkg.LastIndex=J;K=function(e,f){var e,f,g,h;g=0;if((f.length===0)){return A.RuneCountInString(e)+1>>0;}else if(f.length>e.length){return 0;}else if((f.length===e.length)){if(f===e){return 1;}return 0;}while(true){h=I(e,f);if(h===-1){break;}g=g+(1)>>0;e=$substring(e,(h+f.length>>0));}return g;};$pkg.Count=K;L.ptr.prototype.String=function(){var e;e=this;return($bytesToString(e.buf));};L.prototype.String=function(){return this.$val.String();};L.ptr.prototype.copyCheck=function(){var e;e=this;if(e.addr===CG.nil){e.addr=e;}else if(!(e.addr===e)){$panic(new $String(\"strings: illegal use of non-zero Builder copied by value\"));}};L.prototype.copyCheck=function(){return this.$val.copyCheck();};L.ptr.prototype.Len=function(){var e;e=this;return e.buf.$length;};L.prototype.Len=function(){return this.$val.Len();};L.ptr.prototype.Cap=function(){var e;e=this;return e.buf.$capacity;};L.prototype.Cap=function(){return this.$val.Cap();};L.ptr.prototype.Reset=function(){var e;e=this;e.addr=CG.nil;e.buf=CH.nil;};L.prototype.Reset=function(){return this.$val.Reset();};L.ptr.prototype.grow=function(e){var e,f,g;f=this;g=$makeSlice(CH,f.buf.$length,(($imul(2,f.buf.$capacity))+e>>0));$copySlice(g,f.buf);f.buf=g;};L.prototype.grow=function(e){return this.$val.grow(e);};L.ptr.prototype.Grow=function(e){var e,f;f=this;f.copyCheck();if(e<0){$panic(new $String(\"strings.Builder.Grow: negative count\"));}if((f.buf.$capacity-f.buf.$length>>0)<e){f.grow(e);}};L.prototype.Grow=function(e){return this.$val.Grow(e);};L.ptr.prototype.Write=function(e){var e,f;f=this;f.copyCheck();f.buf=$appendSlice(f.buf,e);return[e.$length,$ifaceNil];};L.prototype.Write=function(e){return this.$val.Write(e);};L.ptr.prototype.WriteByte=function(e){var e,f;f=this;f.copyCheck();f.buf=$append(f.buf,e);return $ifaceNil;};L.prototype.WriteByte=function(e){return this.$val.WriteByte(e);};L.ptr.prototype.WriteRune=function(e){var e,f,g,h;f=this;f.copyCheck();if(e<128){f.buf=$append(f.buf,((e<<24>>>24)));return[1,$ifaceNil];}g=f.buf.$length;if((f.buf.$capacity-g>>0)<4){f.grow(4);}h=A.EncodeRune($subslice(f.buf,g,(g+4>>0)),e);f.buf=$subslice(f.buf,0,(g+h>>0));return[h,$ifaceNil];};L.prototype.WriteRune=function(e){return this.$val.WriteRune(e);};L.ptr.prototype.WriteString=function(e){var e,f;f=this;f.copyCheck();f.buf=$appendSlice(f.buf,e);return[e.length,$ifaceNil];};L.prototype.WriteString=function(e){return this.$val.WriteString(e);};AH=function(e,f){var e,f,g,h,i,j,k,l,m;g=A.RuneCountInString(e);if(f<0||f>g){f=g;}h=$makeSlice(CI,f);i=0;while(true){if(!(i<(f-1>>0))){break;}j=A.DecodeRuneInString(e);k=j[0];l=j[1];((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=$substring(e,0,l));e=$substring(e,l);if(k===65533){((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=\"\\xEF\\xBF\\xBD\");}i=i+(1)>>0;}if(f>0){(m=f-1>>0,((m<0||m>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+m]=e));}return h;};AK=function(e,f){var e,f;return I(e,f)>=0;};$pkg.Contains=AK;AM=function(e,f){var e,f;return AN(e,f)>=0;};$pkg.ContainsRune=AM;AN=function(e,f){var e,f,g,h,i,j,k;if(0<=f&&f<128){return H(e,((f<<24>>>24)));}else if((f===65533)){g=e;h=0;while(true){if(!(h<g.length)){break;}i=$decodeRune(g,h);j=h;k=i[0];if(k===65533){return j;}h+=i[1];}return-1;}else if(!A.ValidRune(f)){return-1;}else{return I(e,($encodeRune(f)));}};$pkg.IndexRune=AN;AO=function(e,f){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;if(f===\"\"){return-1;}if(e.length>8){g=BU(f);h=$clone(g[0],BT);i=g[1];if(i){j=0;while(true){if(!(j<e.length)){break;}if(new CS(h).contains(e.charCodeAt(j))){return j;}j=j+(1)>>0;}return-1;}}k=e;l=0;while(true){if(!(l<k.length)){break;}m=$decodeRune(k,l);n=l;o=m[0];p=f;q=0;while(true){if(!(q<p.length)){break;}r=$decodeRune(p,q);s=r[0];if(o===s){return n;}q+=r[1];}l+=m[1];}return-1;};$pkg.IndexAny=AO;AQ=function(e,f){var e,f,g;g=e.length-1>>0;while(true){if(!(g>=0)){break;}if(e.charCodeAt(g)===f){return g;}g=g-(1)>>0;}return-1;};$pkg.LastIndexByte=AQ;AR=function(e,f,g,h){var e,f,g,h,i,j,k;if(h===0){return CI.nil;}if(f===\"\"){return AH(e,h);}if(h<0){h=K(e,f)+1>>0;}i=$makeSlice(CI,h);h=h-(1)>>0;j=0;while(true){if(!(j<h)){break;}k=I(e,f);if(k<0){break;}((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]=$substring(e,0,(k+g>>0)));e=$substring(e,(k+f.length>>0));j=j+(1)>>0;}((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]=e);return $subslice(i,0,(j+1>>0));};AS=function(e,f,g){var e,f,g;return AR(e,f,0,g);};$pkg.SplitN=AS;AU=function(e,f){var e,f;return AR(e,f,0,-1);};$pkg.Split=AU;AZ=function(e,f){var e,f,g,h,i,j,k,l,m;g=e.$length;if(g===(0)){return\"\";}else if(g===(1)){return(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]);}h=$imul(f.length,((e.$length-1>>0)));i=0;while(true){if(!(i<e.$length)){break;}h=h+(((i<0||i>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+i]).length)>>0;i=i+(1)>>0;}j=new L.ptr(CG.nil,CH.nil);j.Grow(h);j.WriteString((0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]));k=$subslice(e,1);l=0;while(true){if(!(l<k.$length)){break;}m=((l<0||l>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+l]);j.WriteString(f);j.WriteString(m);l++;}return j.String();};$pkg.Join=AZ;BA=function(e,f){var e,f;return e.length>=f.length&&$substring(e,0,f.length)===f;};$pkg.HasPrefix=BA;BB=function(e,f){var e,f;return e.length>=f.length&&$substring(e,(e.length-f.length>>0))===f;};$pkg.HasSuffix=BB;BC=function(e,f){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:g=new L.ptr(CG.nil,CH.nil);h=f;i=0;case 1:if(!(i<h.length)){$s=2;continue;}j=$decodeRune(h,i);k=i;l=j[0];m=e(l);$s=3;case 3:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=m;if((n===l)&&!((l===65533))){i+=j[1];$s=1;continue;}o=0;if(l===65533){p=A.DecodeRuneInString($substring(f,k));l=p[0];o=p[1];if(!((o===1))&&(n===l)){i+=j[1];$s=1;continue;}}else{o=A.RuneLen(l);}g.Grow(f.length+4>>0);g.WriteString($substring(f,0,k));if(n>=0){g.WriteRune(n);}f=$substring(f,(k+o>>0));$s=2;continue;$s=1;continue;case 2:if(g.Cap()===0){$s=-1;return f;}q=f;r=0;case 4:if(!(r<q.length)){$s=5;continue;}s=$decodeRune(q,r);t=s[0];u=e(t);$s=6;case 6:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}v=u;if(v>=0){if(v<128){g.WriteByte(((v<<24>>>24)));}else{g.WriteRune(v);}}r+=s[1];$s=4;continue;case 5:$s=-1;return g.String();}return;}if($f===undefined){$f={$blk:BC};}$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Map=BC;BF=function(e){var e,f,g,h,i,j,k,l,m,n,o,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=true;g=false;h=f;i=g;j=0;while(true){if(!(j<e.length)){break;}k=e.charCodeAt(j);if(k>=128){h=false;break;}i=i||(k>=65&&k<=90);j=j+(1)>>0;}if(h){if(!i){$s=-1;return e;}l=new L.ptr(CG.nil,CH.nil);l.Grow(e.length);m=0;while(true){if(!(m<e.length)){break;}n=e.charCodeAt(m);if(n>=65&&n<=90){n=n+(32)<<24>>>24;}l.WriteByte(n);m=m+(1)>>0;}$s=-1;return l.String();}o=BC(G.ToLower,e);$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}$s=-1;return o;}return;}if($f===undefined){$f={$blk:BF};}$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.$s=$s;$f.$r=$r;return $f;};$pkg.ToLower=BF;BU=function(e){var e,f,g,h,i,j,k,l,m,n,o;f=CV.zero();g=false;h=0;while(true){if(!(h<e.length)){break;}i=e.charCodeAt(h);if(i>=128){j=$clone(f,BT);k=false;BT.copy(f,j);g=k;return[f,g];}l=i>>>5<<24>>>24;((l<0||l>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[l]=((((l<0||l>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[l])|(((m=((((i&31)>>>0)>>>0)),m<32?(1<<m):0)>>>0)))>>>0));h=h+(1)>>0;}n=$clone(f,BT);o=true;BT.copy(f,n);g=o;return[f,g];};BT.prototype.contains=function(e){var e,f,g,h;f=this.$val;return!((((((g=e>>>5<<24>>>24,(f.nilCheck,((g<0||g>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[g])))&(((h=((((e&31)>>>0)>>>0)),h<32?(1<<h):0)>>>0)))>>>0))===0));};$ptrType(BT).prototype.contains=function(e){return(new BT(this.$get())).contains(e);};CA=function(e,f){var e,f;if(BA(e,f)){return $substring(e,f.length);}return e;};$pkg.TrimPrefix=CA;CG.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"copyCheck\",name:\"copyCheck\",pkg:\"strings\",typ:$funcType([],[],false)},{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Cap\",name:\"Cap\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Reset\",name:\"Reset\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"grow\",name:\"grow\",pkg:\"strings\",typ:$funcType([$Int],[],false)},{prop:\"Grow\",name:\"Grow\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([CH],[$Int,$error],false)},{prop:\"WriteByte\",name:\"WriteByte\",pkg:\"\",typ:$funcType([$Uint8],[$error],false)},{prop:\"WriteRune\",name:\"WriteRune\",pkg:\"\",typ:$funcType([$Int32],[$Int,$error],false)},{prop:\"WriteString\",name:\"WriteString\",pkg:\"\",typ:$funcType([$String],[$Int,$error],false)}];CS.methods=[{prop:\"contains\",name:\"contains\",pkg:\"strings\",typ:$funcType([$Uint8],[$Bool],false)}];L.init(\"strings\",[{prop:\"addr\",name:\"addr\",embedded:false,exported:false,typ:CG,tag:\"\"},{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:CH,tag:\"\"}]);BT.init($Uint32,8);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=C.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"regexp/syntax\"]=(function(){var $pkg={},$init,C,B,D,A,E,F,G,H,M,N,O,P,Z,AM,BK,BL,BN,BQ,BV,BW,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CR,J,K,L,AA,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,BM,I,Q,R,S,T,U,V,W,X,Y,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AN,AO,AP,AQ,BP,BR,BS,BT,BU,BX,BY,BZ;C=$packages[\"sort\"];B=$packages[\"strconv\"];D=$packages[\"strings\"];A=$packages[\"unicode\"];E=$packages[\"unicode/utf8\"];F=$pkg.patchList=$newType(4,$kindUint32,\"syntax.patchList\",true,\"regexp/syntax\",false,null);G=$pkg.frag=$newType(0,$kindStruct,\"syntax.frag\",true,\"regexp/syntax\",false,function(i_,out_){this.$val=this;if(arguments.length===0){this.i=0;this.out=0;return;}this.i=i_;this.out=out_;});H=$pkg.compiler=$newType(0,$kindStruct,\"syntax.compiler\",true,\"regexp/syntax\",false,function(p_){this.$val=this;if(arguments.length===0){this.p=CE.nil;return;}this.p=p_;});M=$pkg.Error=$newType(0,$kindStruct,\"syntax.Error\",true,\"regexp/syntax\",true,function(Code_,Expr_){this.$val=this;if(arguments.length===0){this.Code=\"\";this.Expr=\"\";return;}this.Code=Code_;this.Expr=Expr_;});N=$pkg.ErrorCode=$newType(8,$kindString,\"syntax.ErrorCode\",true,\"regexp/syntax\",true,null);O=$pkg.Flags=$newType(2,$kindUint16,\"syntax.Flags\",true,\"regexp/syntax\",true,null);P=$pkg.parser=$newType(0,$kindStruct,\"syntax.parser\",true,\"regexp/syntax\",false,function(flags_,stack_,free_,numCap_,wholeRegexp_,tmpClass_){this.$val=this;if(arguments.length===0){this.flags=0;this.stack=CH.nil;this.free=CG.nil;this.numCap=0;this.wholeRegexp=\"\";this.tmpClass=CA.nil;return;}this.flags=flags_;this.stack=stack_;this.free=free_;this.numCap=numCap_;this.wholeRegexp=wholeRegexp_;this.tmpClass=tmpClass_;});Z=$pkg.charGroup=$newType(0,$kindStruct,\"syntax.charGroup\",true,\"regexp/syntax\",false,function(sign_,class$1_){this.$val=this;if(arguments.length===0){this.sign=0;this.class$1=CA.nil;return;}this.sign=sign_;this.class$1=class$1_;});AM=$pkg.ranges=$newType(0,$kindStruct,\"syntax.ranges\",true,\"regexp/syntax\",false,function(p_){this.$val=this;if(arguments.length===0){this.p=CK.nil;return;}this.p=p_;});BK=$pkg.Prog=$newType(0,$kindStruct,\"syntax.Prog\",true,\"regexp/syntax\",true,function(Inst_,Start_,NumCap_){this.$val=this;if(arguments.length===0){this.Inst=CF.nil;this.Start=0;this.NumCap=0;return;}this.Inst=Inst_;this.Start=Start_;this.NumCap=NumCap_;});BL=$pkg.InstOp=$newType(1,$kindUint8,\"syntax.InstOp\",true,\"regexp/syntax\",true,null);BN=$pkg.EmptyOp=$newType(1,$kindUint8,\"syntax.EmptyOp\",true,\"regexp/syntax\",true,null);BQ=$pkg.Inst=$newType(0,$kindStruct,\"syntax.Inst\",true,\"regexp/syntax\",true,function(Op_,Out_,Arg_,Rune_){this.$val=this;if(arguments.length===0){this.Op=0;this.Out=0;this.Arg=0;this.Rune=CA.nil;return;}this.Op=Op_;this.Out=Out_;this.Arg=Arg_;this.Rune=Rune_;});BV=$pkg.Regexp=$newType(0,$kindStruct,\"syntax.Regexp\",true,\"regexp/syntax\",true,function(Op_,Flags_,Sub_,Sub0_,Rune_,Rune0_,Min_,Max_,Cap_,Name_){this.$val=this;if(arguments.length===0){this.Op=0;this.Flags=0;this.Sub=CH.nil;this.Sub0=CI.zero();this.Rune=CA.nil;this.Rune0=CJ.zero();this.Min=0;this.Max=0;this.Cap=0;this.Name=\"\";return;}this.Op=Op_;this.Flags=Flags_;this.Sub=Sub_;this.Sub0=Sub0_;this.Rune=Rune_;this.Rune0=Rune0_;this.Min=Min_;this.Max=Max_;this.Cap=Cap_;this.Name=Name_;});BW=$pkg.Op=$newType(1,$kindUint8,\"syntax.Op\",true,\"regexp/syntax\",true,null);CA=$sliceType($Int32);CB=$sliceType(A.Range16);CC=$sliceType(A.Range32);CD=$sliceType($String);CE=$ptrType(BK);CF=$sliceType(BQ);CG=$ptrType(BV);CH=$sliceType(CG);CI=$arrayType(CG,1);CJ=$arrayType($Int32,2);CK=$ptrType(CA);CL=$ptrType(A.RangeTable);CM=$ptrType(D.Builder);CN=$sliceType($Uint8);CO=$ptrType(H);CP=$ptrType(M);CQ=$ptrType(P);CR=$ptrType(BQ);F.prototype.next=function(a){var a,b,c,d,e;b=this.$val;e=(c=a.Inst,d=b>>>1>>>0,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]));if(((b&1)>>>0)===0){return((e.Out>>>0));}return((e.Arg>>>0));};$ptrType(F).prototype.next=function(a){return new F(this.$get()).next(a);};F.prototype.patch=function(a,b){var a,b,c,d,e,f;c=this.$val;while(true){if(!(!((c===0)))){break;}f=(d=a.Inst,e=c>>>1>>>0,((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]));if(((c&1)>>>0)===0){c=((f.Out>>>0));f.Out=b;}else{c=((f.Arg>>>0));f.Arg=b;}}};$ptrType(F).prototype.patch=function(a,b){return new F(this.$get()).patch(a,b);};F.prototype.append=function(a,b){var a,b,c,d,e,f,g,h;c=this.$val;if(c===0){return b;}if(b===0){return c;}d=c;while(true){e=new F(d).next(a);if(e===0){break;}d=e;}h=(f=a.Inst,g=d>>>1>>>0,((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]));if(((d&1)>>>0)===0){h.Out=((b>>>0));}else{h.Arg=((b>>>0));}return c;};$ptrType(F).prototype.append=function(a,b){return new F(this.$get()).append(a,b);};I=function(a){var a,b,c;b=new H.ptr(CE.nil);b.init();c=$clone(b.compile(a),G);new F(c.out).patch(b.p,b.inst(4).i);b.p.Start=((c.i>>0));return[b.p,$ifaceNil];};$pkg.Compile=I;H.ptr.prototype.init=function(){var a;a=this;a.p=new BK.ptr(CF.nil,0,0);a.p.NumCap=2;a.inst(5);};H.prototype.init=function(){return this.$val.init();};H.ptr.prototype.compile=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;b=this;c=a.Op;if(c===(1)){return b.fail();}else if(c===(2)){return b.nop();}else if(c===(3)){if(a.Rune.$length===0){return b.nop();}d=new G.ptr(0,0);e=a.Rune;f=0;while(true){if(!(f<e.$length)){break;}g=f;h=$clone(b.rune($subslice(a.Rune,g,(g+1>>0)),a.Flags),G);if(g===0){G.copy(d,h);}else{G.copy(d,b.cat($clone(d,G),$clone(h,G)));}f++;}return d;}else if(c===(4)){return b.rune(a.Rune,a.Flags);}else if(c===(5)){return b.rune(J,0);}else if(c===(6)){return b.rune(K,0);}else if(c===(7)){return b.empty(1);}else if(c===(8)){return b.empty(2);}else if(c===(9)){return b.empty(4);}else if(c===(10)){return b.empty(8);}else if(c===(11)){return b.empty(16);}else if(c===(12)){return b.empty(32);}else if(c===(13)){i=$clone(b.cap((((a.Cap<<1>>0)>>>0))),G);k=$clone(b.compile((j=a.Sub,(0>=j.$length?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+0]))),G);l=$clone(b.cap(((((a.Cap<<1>>0)|1)>>>0))),G);return b.cat($clone(b.cat($clone(i,G),$clone(k,G)),G),$clone(l,G));}else if(c===(14)){return b.star($clone(b.compile((m=a.Sub,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0]))),G),!((((a.Flags&32)>>>0)===0)));}else if(c===(15)){return b.plus($clone(b.compile((n=a.Sub,(0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0]))),G),!((((a.Flags&32)>>>0)===0)));}else if(c===(16)){return b.quest($clone(b.compile((o=a.Sub,(0>=o.$length?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+0]))),G),!((((a.Flags&32)>>>0)===0)));}else if(c===(18)){if(a.Sub.$length===0){return b.nop();}p=new G.ptr(0,0);q=a.Sub;r=0;while(true){if(!(r<q.$length)){break;}s=r;t=((r<0||r>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+r]);if(s===0){G.copy(p,b.compile(t));}else{G.copy(p,b.cat($clone(p,G),$clone(b.compile(t),G)));}r++;}return p;}else if(c===(19)){u=new G.ptr(0,0);v=a.Sub;w=0;while(true){if(!(w<v.$length)){break;}x=((w<0||w>=v.$length)?($throwRuntimeError(\"index out of range\"),undefined):v.$array[v.$offset+w]);G.copy(u,b.alt($clone(u,G),$clone(b.compile(x),G)));w++;}return u;}$panic(new $String(\"regexp: unhandled case in compile\"));};H.prototype.compile=function(a){return this.$val.compile(a);};H.ptr.prototype.inst=function(a){var a,b,c;b=this;c=new G.ptr(((b.p.Inst.$length>>>0)),0);b.p.Inst=$append(b.p.Inst,new BQ.ptr(a,0,0,CA.nil));return c;};H.prototype.inst=function(a){return this.$val.inst(a);};H.ptr.prototype.nop=function(){var a,b;a=this;b=$clone(a.inst(6),G);b.out=(((b.i<<1>>>0)>>>0));return b;};H.prototype.nop=function(){return this.$val.nop();};H.ptr.prototype.fail=function(){var a;a=this;return new G.ptr(0,0);};H.prototype.fail=function(){return this.$val.fail();};H.ptr.prototype.cap=function(a){var a,b,c,d,e;b=this;c=$clone(b.inst(2),G);c.out=(((c.i<<1>>>0)>>>0));(d=b.p.Inst,e=c.i,((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e])).Arg=a;if(b.p.NumCap<(((a>>0))+1>>0)){b.p.NumCap=((a>>0))+1>>0;}return c;};H.prototype.cap=function(a){return this.$val.cap(a);};H.ptr.prototype.cat=function(a,b){var a,b,c;c=this;if((a.i===0)||(b.i===0)){return new G.ptr(0,0);}new F(a.out).patch(c.p,b.i);return new G.ptr(a.i,b.out);};H.prototype.cat=function(a,b){return this.$val.cat(a,b);};H.ptr.prototype.alt=function(a,b){var a,b,c,d,e,f,g;c=this;if(a.i===0){return b;}if(b.i===0){return a;}d=$clone(c.inst(0),G);g=(e=c.p.Inst,f=d.i,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));g.Out=a.i;g.Arg=b.i;d.out=new F(a.out).append(c.p,b.out);return d;};H.prototype.alt=function(a,b){return this.$val.alt(a,b);};H.ptr.prototype.quest=function(a,b){var a,b,c,d,e,f,g;c=this;d=$clone(c.inst(0),G);g=(e=c.p.Inst,f=d.i,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));if(b){g.Arg=a.i;d.out=(((d.i<<1>>>0)>>>0));}else{g.Out=a.i;d.out=(((((d.i<<1>>>0)|1)>>>0)>>>0));}d.out=new F(d.out).append(c.p,a.out);return d;};H.prototype.quest=function(a,b){return this.$val.quest(a,b);};H.ptr.prototype.star=function(a,b){var a,b,c,d,e,f,g;c=this;d=$clone(c.inst(0),G);g=(e=c.p.Inst,f=d.i,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));if(b){g.Arg=a.i;d.out=(((d.i<<1>>>0)>>>0));}else{g.Out=a.i;d.out=(((((d.i<<1>>>0)|1)>>>0)>>>0));}new F(a.out).patch(c.p,d.i);return d;};H.prototype.star=function(a,b){return this.$val.star(a,b);};H.ptr.prototype.plus=function(a,b){var a,b,c;c=this;return new G.ptr(a.i,c.star($clone(a,G),b).out);};H.prototype.plus=function(a,b){return this.$val.plus(a,b);};H.ptr.prototype.empty=function(a){var a,b,c,d,e;b=this;c=$clone(b.inst(3),G);(d=b.p.Inst,e=c.i,((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e])).Arg=((a>>>0));c.out=(((c.i<<1>>>0)>>>0));return c;};H.prototype.empty=function(a){return this.$val.empty(a);};H.ptr.prototype.rune=function(a,b){var a,b,c,d,e,f,g;c=this;d=$clone(c.inst(7),G);g=(e=c.p.Inst,f=d.i,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));g.Rune=a;b=(b&(1))>>>0;if(!((a.$length===1))||(A.SimpleFold((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]))===(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]))){b=(b&~(1))<<16>>>16;}g.Arg=((b>>>0));d.out=(((d.i<<1>>>0)>>>0));if((((b&1)>>>0)===0)&&((a.$length===1)||(a.$length===2)&&((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])===(1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])))){g.Op=8;}else if((a.$length===2)&&((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])===0)&&((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])===1114111)){g.Op=9;}else if((a.$length===4)&&((0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0])===0)&&((1>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+1])===9)&&((2>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+2])===11)&&((3>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+3])===1114111)){g.Op=10;}return d;};H.prototype.rune=function(a,b){return this.$val.rune(a,b);};BW.prototype.String=function(){var a,b;a=this.$val;if(1<=a&&a<=19){a=a-(1)<<24>>>24;return $substring(\"NoMatchEmptyMatchLiteralCharClassAnyCharNotNLAnyCharBeginLineEndLineBeginTextEndTextWordBoundaryNoWordBoundaryCaptureStarPlusQuestRepeatConcatAlternate\",((a<0||a>=L.length)?($throwRuntimeError(\"index out of range\"),undefined):L[a]),(b=a+1<<24>>>24,((b<0||b>=L.length)?($throwRuntimeError(\"index out of range\"),undefined):L[b])));}else if((a===128)){return\"opPseudo\";}else{return\"Op(\"+B.FormatInt((new $Int64(0,a)),10)+\")\";}};$ptrType(BW).prototype.String=function(){return new BW(this.$get()).String();};M.ptr.prototype.Error=function(){var a;a=this;return\"error parsing regexp: \"+new N(a.Code).String()+\": `\"+a.Expr+\"`\";};M.prototype.Error=function(){return this.$val.Error();};N.prototype.String=function(){var a;a=this.$val;return(a);};$ptrType(N).prototype.String=function(){return new N(this.$get()).String();};P.ptr.prototype.newRegexp=function(a){var a,b,c;b=this;c=b.free;if(!(c===CG.nil)){b.free=c.Sub0[0];BV.copy(c,new BV.ptr(0,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\"));}else{c=new BV.ptr(0,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");}c.Op=a;return c;};P.prototype.newRegexp=function(a){return this.$val.newRegexp(a);};P.ptr.prototype.reuse=function(a){var a,b;b=this;a.Sub0[0]=b.free;b.free=a;};P.prototype.reuse=function(a){return this.$val.reuse(a);};P.ptr.prototype.push=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;b=this;if((a.Op===4)&&(a.Rune.$length===2)&&((c=a.Rune,(0>=c.$length?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+0]))===(d=a.Rune,(1>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+1])))){if(b.maybeConcat((s=a.Rune,(0>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+0])),(b.flags&~1)<<16>>>16)){return CG.nil;}a.Op=3;a.Rune=$subslice(a.Rune,0,1);a.Flags=(b.flags&~1)<<16>>>16;}else if((a.Op===4)&&(a.Rune.$length===4)&&((e=a.Rune,(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]))===(f=a.Rune,(1>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+1])))&&((g=a.Rune,(2>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+2]))===(h=a.Rune,(3>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+3])))&&(A.SimpleFold((i=a.Rune,(0>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+0])))===(j=a.Rune,(2>=j.$length?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+2])))&&(A.SimpleFold((k=a.Rune,(2>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+2])))===(l=a.Rune,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])))||(a.Op===4)&&(a.Rune.$length===2)&&(((m=a.Rune,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0]))+1>>0)===(n=a.Rune,(1>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+1])))&&(A.SimpleFold((o=a.Rune,(0>=o.$length?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+0])))===(p=a.Rune,(1>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+1])))&&(A.SimpleFold((q=a.Rune,(1>=q.$length?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+1])))===(r=a.Rune,(0>=r.$length?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+0])))){if(b.maybeConcat((t=a.Rune,(0>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+0])),(b.flags|1)>>>0)){return CG.nil;}a.Op=3;a.Rune=$subslice(a.Rune,0,1);a.Flags=(b.flags|1)>>>0;}else{b.maybeConcat(-1,0);}b.stack=$append(b.stack,a);return a;};P.prototype.push=function(a){return this.$val.push(a);};P.ptr.prototype.maybeConcat=function(a,b){var a,b,c,d,e,f,g,h,i,j,k;c=this;d=c.stack.$length;if(d<2){return false;}g=(e=c.stack,f=d-1>>0,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));j=(h=c.stack,i=d-2>>0,((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]));if(!((g.Op===3))||!((j.Op===3))||!((((g.Flags&1)>>>0)===((j.Flags&1)>>>0)))){return false;}j.Rune=$appendSlice(j.Rune,g.Rune);if(a>=0){g.Rune=$subslice(new CA(g.Rune0),0,1);(k=g.Rune,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]=a));g.Flags=b;return true;}c.stack=$subslice(c.stack,0,(d-1>>0));c.reuse(g);return false;};P.prototype.maybeConcat=function(a,b){return this.$val.maybeConcat(a,b);};P.ptr.prototype.newLiteral=function(a,b){var a,b,c,d;c=this;d=c.newRegexp(3);d.Flags=b;if(!((((b&1)>>>0)===0))){a=Q(a);}d.Rune0[0]=a;d.Rune=$subslice(new CA(d.Rune0),0,1);return d;};P.prototype.newLiteral=function(a,b){return this.$val.newLiteral(a,b);};Q=function(a){var a,b,c;if(a<65||a>125251){return a;}b=a;c=a;a=A.SimpleFold(a);while(true){if(!(!((a===c)))){break;}if(b>a){b=a;}a=A.SimpleFold(a);}return b;};P.ptr.prototype.literal=function(a){var a,b;b=this;b.push(b.newLiteral(a,b.flags));};P.prototype.literal=function(a){return this.$val.literal(a);};P.ptr.prototype.op=function(a){var a,b,c;b=this;c=b.newRegexp(a);c.Flags=b.flags;return b.push(c);};P.prototype.op=function(a){return this.$val.op(a);};P.ptr.prototype.repeat=function(a,b,c,d,e,f){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;g=this;h=g.flags;if(!((((g.flags&64)>>>0)===0))){if(e.length>0&&(e.charCodeAt(0)===63)){e=$substring(e,1);h=(h^(32))<<16>>>16;}if(!(f===\"\")){return[\"\",new M.ptr(\"invalid nested repetition operator\",$substring(f,0,(f.length-e.length>>0)))];}}i=g.stack.$length;if(i===0){return[\"\",new M.ptr(\"missing argument to repetition operator\",$substring(d,0,(d.length-e.length>>0)))];}l=(j=g.stack,k=i-1>>0,((k<0||k>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+k]));if(l.Op>=128){return[\"\",new M.ptr(\"missing argument to repetition operator\",$substring(d,0,(d.length-e.length>>0)))];}m=g.newRegexp(a);m.Min=b;m.Max=c;m.Flags=h;m.Sub=$subslice(new CH(m.Sub0),0,1);(n=m.Sub,(0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0]=l));(o=g.stack,p=i-1>>0,((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]=m));if((a===17)&&(b>=2||c>=2)&&!R(m,1000)){return[\"\",new M.ptr(\"invalid repeat count\",$substring(d,0,(d.length-e.length>>0)))];}return[e,$ifaceNil];};P.prototype.repeat=function(a,b,c,d,e,f){return this.$val.repeat(a,b,c,d,e,f);};R=function(a,b){var a,b,c,d,e,f,g;if(a.Op===17){c=a.Max;if(c===0){return true;}if(c<0){c=a.Min;}if(c>b){return false;}if(c>0){b=(d=b/(c),(d===d&&d!==1/0&&d!==-1/0)?d>>0:$throwRuntimeError(\"integer divide by zero\"));}}e=a.Sub;f=0;while(true){if(!(f<e.$length)){break;}g=((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]);if(!R(g,b)){return false;}f++;}return true;};P.ptr.prototype.concat=function(){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;a.maybeConcat(-1,0);b=a.stack.$length;while(true){if(!(b>0&&(c=a.stack,d=b-1>>0,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d])).Op<128)){break;}b=b-(1)>>0;}e=$subslice(a.stack,b);a.stack=$subslice(a.stack,0,b);if(e.$length===0){$s=-1;return a.push(a.newRegexp(2));}f=a.collapse(e,18);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=a.push(f);$s=2;case 2:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}$s=-1;return g;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.concat};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.concat=function(){return this.$val.concat();};P.ptr.prototype.alternate=function(){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.stack.$length;while(true){if(!(b>0&&(c=a.stack,d=b-1>>0,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d])).Op<128)){break;}b=b-(1)>>0;}e=$subslice(a.stack,b);a.stack=$subslice(a.stack,0,b);if(e.$length>0){$s=1;continue;}$s=2;continue;case 1:$r=S((f=e.$length-1>>0,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f])));$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 2:if(e.$length===0){$s=-1;return a.push(a.newRegexp(1));}g=a.collapse(e,19);$s=4;case 4:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=a.push(g);$s=5;case 5:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}$s=-1;return h;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.alternate};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.alternate=function(){return this.$val.alternate();};S=function(a){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=a.Op;if(b===(4)){$s=2;continue;}$s=3;continue;case 2:c=AC((a.$ptr_Rune||(a.$ptr_Rune=new CK(function(){return this.$target.Rune;},function($v){this.$target.Rune=$v;},a))));$s=4;case 4:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}a.Rune=c;if((a.Rune.$length===2)&&((d=a.Rune,(0>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+0]))===0)&&((e=a.Rune,(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1]))===1114111)){a.Rune=CA.nil;a.Op=6;$s=-1;return;}if((a.Rune.$length===4)&&((f=a.Rune,(0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0]))===0)&&((g=a.Rune,(1>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+1]))===9)&&((h=a.Rune,(2>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+2]))===11)&&((i=a.Rune,(3>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+3]))===1114111)){a.Rune=CA.nil;a.Op=5;$s=-1;return;}if((a.Rune.$capacity-a.Rune.$length>>0)>100){a.Rune=$appendSlice($subslice(new CA(a.Rune0),0,0),a.Rune);}case 3:case 1:$s=-1;return;}return;}if($f===undefined){$f={$blk:S};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};P.ptr.prototype.collapse=function(a,b){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(a.$length===1){$s=-1;return(0>=a.$length?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+0]);}d=c.newRegexp(b);d.Sub=$subslice(new CH(d.Sub0),0,0);e=a;f=0;while(true){if(!(f<e.$length)){break;}g=((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]);if(g.Op===b){d.Sub=$appendSlice(d.Sub,g.Sub);c.reuse(g);}else{d.Sub=$append(d.Sub,g);}f++;}if(b===19){$s=1;continue;}$s=2;continue;case 1:h=c.factor(d.Sub);$s=3;case 3:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}d.Sub=h;if(d.Sub.$length===1){i=d;d=(j=d.Sub,(0>=j.$length?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+0]));c.reuse(i);}case 2:$s=-1;return d;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.collapse};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.collapse=function(a,b){return this.$val.collapse(a,b);};P.ptr.prototype.factor=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(a.$length<2){$s=-1;return a;}c=CA.nil;d=0;e=0;f=$subslice(a,0,0);g=0;case 1:if(!(g<=a.$length)){$s=2;continue;}h=CA.nil;i=0;if(g<a.$length){$s=3;continue;}$s=4;continue;case 3:j=b.leadingString(((g<0||g>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+g]));h=j[0];i=j[1];if(i===d){k=0;while(true){if(!(k<c.$length&&k<h.$length&&(((k<0||k>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+k])===((k<0||k>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+k])))){break;}k=k+(1)>>0;}if(k>0){c=$subslice(c,0,k);g=g+(1)>>0;$s=1;continue;}}case 4:if(g===e){$s=5;continue;}if(g===(e+1>>0)){$s=6;continue;}$s=7;continue;case 5:$s=8;continue;case 6:f=$append(f,((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]));$s=8;continue;case 7:l=b.newRegexp(3);l.Flags=d;l.Rune=$appendSlice($subslice(l.Rune,0,0),c);m=e;while(true){if(!(m<g)){break;}((m<0||m>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+m]=b.removeLeadingString(((m<0||m>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+m]),c.$length));m=m+(1)>>0;}n=b.collapse($subslice(a,e,g),19);$s=9;case 9:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=n;p=b.newRegexp(18);p.Sub=$append($subslice(p.Sub,0,0),l,o);f=$append(f,p);case 8:e=g;c=h;d=i;g=g+(1)>>0;$s=1;continue;case 2:a=f;e=0;f=$subslice(a,0,0);q=CG.nil;r=0;case 10:if(!(r<=a.$length)){$s=11;continue;}s=CG.nil;if(r<a.$length){$s=12;continue;}$s=13;continue;case 12:s=b.leadingRegexp(((r<0||r>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+r]));if(!(q===CG.nil)&&q.Equal(s)&&(W(q)||((q.Op===17)&&(q.Min===q.Max)&&W((t=q.Sub,(0>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+0])))))){r=r+(1)>>0;$s=10;continue;}case 13:if(r===e){$s=14;continue;}if(r===(e+1>>0)){$s=15;continue;}$s=16;continue;case 14:$s=17;continue;case 15:f=$append(f,((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]));$s=17;continue;case 16:u=q;v=e;while(true){if(!(v<r)){break;}w=!((v===e));((v<0||v>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+v]=b.removeLeadingRegexp(((v<0||v>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+v]),w));v=v+(1)>>0;}x=b.collapse($subslice(a,e,r),19);$s=18;case 18:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}y=x;z=b.newRegexp(18);z.Sub=$append($subslice(z.Sub,0,0),u,y);f=$append(f,z);case 17:e=r;q=s;r=r+(1)>>0;$s=10;continue;case 11:a=f;e=0;f=$subslice(a,0,0);aa=0;case 19:if(!(aa<=a.$length)){$s=20;continue;}if(aa<a.$length&&W(((aa<0||aa>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+aa]))){$s=21;continue;}$s=22;continue;case 21:aa=aa+(1)>>0;$s=19;continue;case 22:if(aa===e){$s=23;continue;}if(aa===(e+1>>0)){$s=24;continue;}$s=25;continue;case 23:$s=26;continue;case 24:f=$append(f,((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]));$s=26;continue;case 25:ab=e;ac=e+1>>0;while(true){if(!(ac<aa)){break;}if(((ab<0||ab>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ab]).Op<((ac<0||ac>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ac]).Op||(((ab<0||ab>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ab]).Op===((ac<0||ac>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ac]).Op)&&((ab<0||ab>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ab]).Rune.$length<((ac<0||ac>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ac]).Rune.$length){ab=ac;}ac=ac+(1)>>0;}ad=((ab<0||ab>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ab]);ae=((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]);((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]=ad);((ab<0||ab>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ab]=ae);af=e+1>>0;while(true){if(!(af<aa)){break;}Y(((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]),((af<0||af>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+af]));b.reuse(((af<0||af>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+af]));af=af+(1)>>0;}$r=S(((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]));$s=27;case 27:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}f=$append(f,((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]));case 26:if(aa<a.$length){f=$append(f,((aa<0||aa>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+aa]));}e=aa+1>>0;aa=aa+(1)>>0;$s=19;continue;case 20:a=f;e=0;f=$subslice(a,0,0);ag=a;ah=0;while(true){if(!(ah<ag.$length)){break;}ai=ah;if((ai+1>>0)<a.$length&&(((ai<0||ai>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ai]).Op===2)&&((aj=ai+1>>0,((aj<0||aj>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+aj])).Op===2)){ah++;continue;}f=$append(f,((ai<0||ai>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+ai]));ah++;}a=f;$s=-1;return a;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.factor};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.factor=function(a){return this.$val.factor(a);};P.ptr.prototype.leadingString=function(a){var a,b,c;b=this;if((a.Op===18)&&a.Sub.$length>0){a=(c=a.Sub,(0>=c.$length?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+0]));}if(!((a.Op===3))){return[CA.nil,0];}return[a.Rune,(a.Flags&1)>>>0];};P.prototype.leadingString=function(a){return this.$val.leadingString(a);};P.ptr.prototype.removeLeadingString=function(a,b){var a,b,c,d,e,f,g,h,i;c=this;if((a.Op===18)&&a.Sub.$length>0){e=(d=a.Sub,(0>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+0]));e=c.removeLeadingString(e,b);(f=a.Sub,(0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0]=e));if(e.Op===2){c.reuse(e);g=a.Sub.$length;if((g===(0))||(g===(1))){a.Op=2;a.Sub=CH.nil;}else if(g===(2)){h=a;a=(i=a.Sub,(1>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+1]));c.reuse(h);}else{$copySlice(a.Sub,$subslice(a.Sub,1));a.Sub=$subslice(a.Sub,0,(a.Sub.$length-1>>0));}}return a;}if(a.Op===3){a.Rune=$subslice(a.Rune,0,$copySlice(a.Rune,$subslice(a.Rune,b)));if(a.Rune.$length===0){a.Op=2;}}return a;};P.prototype.removeLeadingString=function(a,b){return this.$val.removeLeadingString(a,b);};P.ptr.prototype.leadingRegexp=function(a){var a,b,c,d;b=this;if(a.Op===2){return CG.nil;}if((a.Op===18)&&a.Sub.$length>0){d=(c=a.Sub,(0>=c.$length?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+0]));if(d.Op===2){return CG.nil;}return d;}return a;};P.prototype.leadingRegexp=function(a){return this.$val.leadingRegexp(a);};P.ptr.prototype.removeLeadingRegexp=function(a,b){var a,b,c,d,e,f,g;c=this;if((a.Op===18)&&a.Sub.$length>0){if(b){c.reuse((d=a.Sub,(0>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+0])));}a.Sub=$subslice(a.Sub,0,$copySlice(a.Sub,$subslice(a.Sub,1)));e=a.Sub.$length;if(e===(0)){a.Op=2;a.Sub=CH.nil;}else if(e===(1)){f=a;a=(g=a.Sub,(0>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+0]));c.reuse(f);}return a;}if(b){c.reuse(a);}return c.newRegexp(2);};P.prototype.removeLeadingRegexp=function(a,b){return this.$val.removeLeadingRegexp(a,b);};T=function(a,b){var a,b,c,d,e,f,g;c=new BV.ptr(3,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");c.Flags=b;c.Rune=$subslice(new CA(c.Rune0),0,0);d=a;e=0;while(true){if(!(e<d.length)){break;}f=$decodeRune(d,e);g=f[0];if(c.Rune.$length>=c.Rune.$capacity){c.Rune=(new CA($stringToRunes(a)));break;}c.Rune=$append(c.Rune,g);e+=f[1];}return c;};U=function(a,b){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(!((((b&2)>>>0)===0))){c=AN(a);if(!($interfaceIsEqual(c,$ifaceNil))){$s=-1;return[CG.nil,c];}$s=-1;return[T(a,b),$ifaceNil];}d=new P.ptr(0,CH.nil,CG.nil,0,\"\",CA.nil);e=$ifaceNil;f=0;g=0;h=\"\";d.flags=b;d.wholeRegexp=a;i=a;case 1:if(!(!(i===\"\"))){$s=2;continue;}j=\"\";k=i.charCodeAt(0);if(k===(40)){$s=4;continue;}if(k===(124)){$s=5;continue;}if(k===(41)){$s=6;continue;}if(k===(94)){$s=7;continue;}if(k===(36)){$s=8;continue;}if(k===(46)){$s=9;continue;}if(k===(91)){$s=10;continue;}if((k===(42))||(k===(43))||(k===(63))){$s=11;continue;}if(k===(123)){$s=12;continue;}if(k===(92)){$s=13;continue;}$s=14;continue;case 4:if(!((((d.flags&64)>>>0)===0))&&i.length>=2&&(i.charCodeAt(1)===63)){l=d.parsePerlFlags(i);i=l[0];e=l[1];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}$s=3;continue;}d.numCap=d.numCap+(1)>>0;d.op(128).Cap=d.numCap;i=$substring(i,1);$s=15;continue;case 5:m=d.parseVerticalBar();$s=16;case 16:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}e=m;if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}i=$substring(i,1);$s=15;continue;case 6:n=d.parseRightParen();$s=17;case 17:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}e=n;if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}i=$substring(i,1);$s=15;continue;case 7:if(!((((d.flags&16)>>>0)===0))){d.op(9);}else{d.op(7);}i=$substring(i,1);$s=15;continue;case 8:if(!((((d.flags&16)>>>0)===0))){o=d.op(10);o.Flags=(o.Flags|(256))>>>0;}else{d.op(8);}i=$substring(i,1);$s=15;continue;case 9:if(!((((d.flags&8)>>>0)===0))){d.op(6);}else{d.op(5);}i=$substring(i,1);$s=15;continue;case 10:q=d.parseClass(i);$s=18;case 18:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;i=p[0];e=p[1];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}$s=15;continue;case 11:r=i;s=i.charCodeAt(0);if(s===(42)){g=14;}else if(s===(43)){g=15;}else if(s===(63)){g=16;}t=$substring(i,1);u=d.repeat(g,0,0,r,t,h);t=u[0];e=u[1];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}j=r;i=t;$s=15;continue;case 12:g=17;v=i;w=d.parseRepeat(i);x=w[0];y=w[1];z=w[2];aa=w[3];if(!aa){d.literal(123);i=$substring(i,1);$s=3;continue;}if(x<0||x>1000||y>1000||y>=0&&x>y){$s=-1;return[CG.nil,new M.ptr(\"invalid repeat count\",$substring(v,0,(v.length-z.length>>0)))];}ab=d.repeat(g,x,y,v,z,h);z=ab[0];e=ab[1];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}j=v;i=z;$s=15;continue;case 13:if(!((((d.flags&64)>>>0)===0))&&i.length>=2){ac=i.charCodeAt(1);if(ac===(65)){d.op(9);i=$substring(i,2);$s=3;continue s;}else if(ac===(98)){d.op(11);i=$substring(i,2);$s=3;continue s;}else if(ac===(66)){d.op(12);i=$substring(i,2);$s=3;continue s;}else if(ac===(67)){$s=-1;return[CG.nil,new M.ptr(\"invalid escape sequence\",$substring(i,0,2))];}else if(ac===(81)){ad=\"\";ae=D.Index(i,\"\\\\E\");if(ae<0){ad=$substring(i,2);i=\"\";}else{ad=$substring(i,2,ae);i=$substring(i,(ae+2>>0));}while(true){if(!(!(ad===\"\"))){break;}af=AO(ad);ag=af[0];ah=af[1];ai=af[2];if(!($interfaceIsEqual(ai,$ifaceNil))){$s=-1;return[CG.nil,ai];}d.literal(ag);ad=ah;}$s=3;continue s;}else if(ac===(122)){d.op(10);i=$substring(i,2);$s=3;continue s;}}aj=d.newRegexp(4);aj.Flags=d.flags;if(i.length>=2&&((i.charCodeAt(1)===112)||(i.charCodeAt(1)===80))){$s=19;continue;}$s=20;continue;case 19:al=d.parseUnicodeClass(i,$subslice(new CA(aj.Rune0),0,0));$s=21;case 21:if($c){$c=false;al=al.$blk();}if(al&&al.$blk!==undefined){break s;}ak=al;am=ak[0];an=ak[1];ao=ak[2];if(!($interfaceIsEqual(ao,$ifaceNil))){$s=-1;return[CG.nil,ao];}if(!(am===CA.nil)){aj.Rune=am;i=an;d.push(aj);$s=3;continue s;}case 20:aq=d.parsePerlClassEscape(i,$subslice(new CA(aj.Rune0),0,0));$s=22;case 22:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ap=aq;ar=ap[0];as=ap[1];if(!(ar===CA.nil)){aj.Rune=ar;i=as;d.push(aj);$s=3;continue s;}d.reuse(aj);at=d.parseEscape(i);f=at[0];i=at[1];e=at[2];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}d.literal(f);$s=15;continue;case 14:au=AO(i);f=au[0];i=au[1];e=au[2];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[CG.nil,e];}d.literal(f);case 15:case 3:h=j;$s=1;continue;case 2:av=d.concat();$s=23;case 23:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}av;aw=d.swapVerticalBar();$s=26;case 26:if($c){$c=false;aw=aw.$blk();}if(aw&&aw.$blk!==undefined){break s;}if(aw){$s=24;continue;}$s=25;continue;case 24:d.stack=$subslice(d.stack,0,(d.stack.$length-1>>0));case 25:ax=d.alternate();$s=27;case 27:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ax;ay=d.stack.$length;if(!((ay===1))){$s=-1;return[CG.nil,new M.ptr(\"missing closing )\",a)];}$s=-1;return[(az=d.stack,(0>=az.$length?($throwRuntimeError(\"index out of range\"),undefined):az.$array[az.$offset+0])),$ifaceNil];}return;}if($f===undefined){$f={$blk:U};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Parse=U;P.ptr.prototype.parseRepeat=function(a){var a,b,c,d,e,f,g,h,i;b=0;c=0;d=\"\";e=false;f=this;if(a===\"\"||!((a.charCodeAt(0)===123))){return[b,c,d,e];}a=$substring(a,1);g=false;h=f.parseInt(a);b=h[0];a=h[1];g=h[2];if(!g){return[b,c,d,e];}if(a===\"\"){return[b,c,d,e];}if(!((a.charCodeAt(0)===44))){c=b;}else{a=$substring(a,1);if(a===\"\"){return[b,c,d,e];}if(a.charCodeAt(0)===125){c=-1;}else{i=f.parseInt(a);c=i[0];a=i[1];g=i[2];if(!g){return[b,c,d,e];}else if(c<0){b=-1;}}}if(a===\"\"||!((a.charCodeAt(0)===125))){return[b,c,d,e];}d=$substring(a,1);e=true;return[b,c,d,e];};P.prototype.parseRepeat=function(a){return this.$val.parseRepeat(a);};P.ptr.prototype.parsePerlFlags=function(a){var a,aa,ab,ac,ad,ae,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=\"\";c=$ifaceNil;d=this;e=a;if(e.length>4&&(e.charCodeAt(2)===80)&&(e.charCodeAt(3)===60)){f=D.IndexRune(e,62);if(f<0){c=AN(e);if(!($interfaceIsEqual(c,$ifaceNil))){g=\"\";h=c;b=g;c=h;return[b,c];}i=\"\";j=new M.ptr(\"invalid named capture\",a);b=i;c=j;return[b,c];}k=$substring(e,0,(f+1>>0));l=$substring(e,4,f);c=AN(l);if(!($interfaceIsEqual(c,$ifaceNil))){m=\"\";n=c;b=m;c=n;return[b,c];}if(!V(l)){o=\"\";p=new M.ptr(\"invalid named capture\",k);b=o;c=p;return[b,c];}d.numCap=d.numCap+(1)>>0;q=d.op(128);q.Cap=d.numCap;q.Name=l;r=$substring(e,(f+1>>0));s=$ifaceNil;b=r;c=s;return[b,c];}t=0;e=$substring(e,2);u=d.flags;v=1;w=false;Loop:while(true){if(!(!(e===\"\"))){break;}x=AO(e);t=x[0];e=x[1];c=x[2];if(!($interfaceIsEqual(c,$ifaceNil))){y=\"\";z=c;b=y;c=z;return[b,c];}aa=t;if(aa===(105)){u=(u|(1))>>>0;w=true;}else if(aa===(109)){u=(u&~(16))<<16>>>16;w=true;}else if(aa===(115)){u=(u|(8))>>>0;w=true;}else if(aa===(85)){u=(u|(32))>>>0;w=true;}else if(aa===(45)){if(v<0){break Loop;}v=-1;u=~u<<16>>>16;w=false;}else if((aa===(58))||(aa===(41))){if(v<0){if(!w){break Loop;}u=~u<<16>>>16;}if(t===58){d.op(128);}d.flags=u;ab=e;ac=$ifaceNil;b=ab;c=ac;return[b,c];}else{break Loop;}}ad=\"\";ae=new M.ptr(\"invalid or unsupported Perl syntax\",$substring(a,0,(a.length-e.length>>0)));b=ad;c=ae;return[b,c];};P.prototype.parsePerlFlags=function(a){return this.$val.parsePerlFlags(a);};V=function(a){var a,b,c,d,e;if(a===\"\"){return false;}b=a;c=0;while(true){if(!(c<b.length)){break;}d=$decodeRune(b,c);e=d[0];if(!((e===95))&&!AP(e)){return false;}c+=d[1];}return true;};P.ptr.prototype.parseInt=function(a){var a,b,c,d,e,f,g;b=0;c=\"\";d=false;e=this;if(a===\"\"||a.charCodeAt(0)<48||57<a.charCodeAt(0)){return[b,c,d];}if(a.length>=2&&(a.charCodeAt(0)===48)&&48<=a.charCodeAt(1)&&a.charCodeAt(1)<=57){return[b,c,d];}f=a;while(true){if(!(!(a===\"\")&&48<=a.charCodeAt(0)&&a.charCodeAt(0)<=57)){break;}a=$substring(a,1);}c=a;d=true;f=$substring(f,0,(f.length-a.length>>0));g=0;while(true){if(!(g<f.length)){break;}if(b>=100000000){b=-1;break;}b=(($imul(b,10))+((f.charCodeAt(g)>>0))>>0)-48>>0;g=g+(1)>>0;}return[b,c,d];};P.prototype.parseInt=function(a){return this.$val.parseInt(a);};W=function(a){var a;return(a.Op===3)&&(a.Rune.$length===1)||(a.Op===4)||(a.Op===5)||(a.Op===6);};X=function(a,b){var a,b,c,d,e,f,g,h;c=a.Op;if(c===(3)){return(a.Rune.$length===1)&&((d=a.Rune,(0>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+0]))===b);}else if(c===(4)){e=0;while(true){if(!(e<a.Rune.$length)){break;}if((f=a.Rune,((e<0||e>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+e]))<=b&&b<=(g=a.Rune,h=e+1>>0,((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h]))){return true;}e=e+(2)>>0;}return false;}else if(c===(5)){return!((b===10));}else if(c===(6)){return true;}return false;};P.ptr.prototype.parseVerticalBar=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.concat();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}b;c=a.swapVerticalBar();$s=4;case 4:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}if(!c){$s=2;continue;}$s=3;continue;case 2:a.op(129);case 3:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.parseVerticalBar};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.parseVerticalBar=function(){return this.$val.parseVerticalBar();};Y=function(a,b){var a,b,c,d,e,f,g,h;switch(0){default:c=a.Op;if(c===(6)){}else if(c===(5)){if(X(b,10)){a.Op=6;}}else if(c===(4)){if(b.Op===3){a.Rune=AD(a.Rune,(d=b.Rune,(0>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+0])),b.Flags);}else{a.Rune=AG(a.Rune,b.Rune);}}else if(c===(3)){if(((e=b.Rune,(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]))===(f=a.Rune,(0>=f.$length?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+0])))&&(b.Flags===a.Flags)){break;}a.Op=4;a.Rune=AD($subslice(a.Rune,0,0),(g=a.Rune,(0>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+0])),a.Flags);a.Rune=AD(a.Rune,(h=b.Rune,(0>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+0])),b.Flags);}}};P.ptr.prototype.swapVerticalBar=function(){var a,aa,ab,ac,ad,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.stack.$length;if(b>=3&&((c=a.stack,d=b-2>>0,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d])).Op===129)&&W((e=a.stack,f=b-1>>0,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f])))&&W((g=a.stack,h=b-3>>0,((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h])))){k=(i=a.stack,j=b-1>>0,((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]));n=(l=a.stack,m=b-3>>0,((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m]));if(k.Op>n.Op){o=n;p=k;k=o;n=p;(q=a.stack,r=b-3>>0,((r<0||r>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+r]=n));}Y(n,k);a.reuse(k);a.stack=$subslice(a.stack,0,(b-1>>0));$s=-1;return true;}if(b>=2){$s=1;continue;}$s=2;continue;case 1:u=(s=a.stack,t=b-1>>0,((t<0||t>=s.$length)?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+t]));x=(v=a.stack,w=b-2>>0,((w<0||w>=v.$length)?($throwRuntimeError(\"index out of range\"),undefined):v.$array[v.$offset+w]));if(x.Op===129){$s=3;continue;}$s=4;continue;case 3:if(b>=3){$s=5;continue;}$s=6;continue;case 5:$r=S((y=a.stack,z=b-3>>0,((z<0||z>=y.$length)?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+z])));$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 6:(aa=a.stack,ab=b-2>>0,((ab<0||ab>=aa.$length)?($throwRuntimeError(\"index out of range\"),undefined):aa.$array[aa.$offset+ab]=u));(ac=a.stack,ad=b-1>>0,((ad<0||ad>=ac.$length)?($throwRuntimeError(\"index out of range\"),undefined):ac.$array[ac.$offset+ad]=x));$s=-1;return true;case 4:case 2:$s=-1;return false;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.swapVerticalBar};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.swapVerticalBar=function(){return this.$val.swapVerticalBar();};P.ptr.prototype.parseRightParen=function(){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.concat();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}b;c=a.swapVerticalBar();$s=4;case 4:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}if(c){$s=2;continue;}$s=3;continue;case 2:a.stack=$subslice(a.stack,0,(a.stack.$length-1>>0));case 3:d=a.alternate();$s=5;case 5:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}d;e=a.stack.$length;if(e<2){$s=-1;return new M.ptr(\"unexpected )\",a.wholeRegexp);}h=(f=a.stack,g=e-1>>0,((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]));k=(i=a.stack,j=e-2>>0,((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]));a.stack=$subslice(a.stack,0,(e-2>>0));if(!((k.Op===128))){$s=-1;return new M.ptr(\"unexpected )\",a.wholeRegexp);}a.flags=k.Flags;if(k.Cap===0){a.push(h);}else{k.Op=13;k.Sub=$subslice(new CH(k.Sub0),0,1);(l=k.Sub,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0]=h));a.push(k);}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.parseRightParen};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.parseRightParen=function(){return this.$val.parseRightParen();};P.ptr.prototype.parseEscape=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=0;c=\"\";d=$ifaceNil;e=this;f=$substring(a,1);if(f===\"\"){g=0;h=\"\";i=new M.ptr(\"trailing backslash at end of expression\",\"\");b=g;c=h;d=i;return[b,c,d];}j=AO(f);k=j[0];f=j[1];d=j[2];if(!($interfaceIsEqual(d,$ifaceNil))){l=0;m=\"\";n=d;b=l;c=m;d=n;return[b,c,d];}Switch:switch(0){default:o=k;if((o===(49))||(o===(50))||(o===(51))||(o===(52))||(o===(53))||(o===(54))||(o===(55))){if(f===\"\"||f.charCodeAt(0)<48||f.charCodeAt(0)>55){break;}b=k-48>>0;p=1;while(true){if(!(p<3)){break;}if(f===\"\"||f.charCodeAt(0)<48||f.charCodeAt(0)>55){break;}b=(($imul(b,8))+((f.charCodeAt(0)>>0))>>0)-48>>0;f=$substring(f,1);p=p+(1)>>0;}q=b;r=f;s=$ifaceNil;b=q;c=r;d=s;return[b,c,d];}else if(o===(48)){b=k-48>>0;p=1;while(true){if(!(p<3)){break;}if(f===\"\"||f.charCodeAt(0)<48||f.charCodeAt(0)>55){break;}b=(($imul(b,8))+((f.charCodeAt(0)>>0))>>0)-48>>0;f=$substring(f,1);p=p+(1)>>0;}t=b;u=f;v=$ifaceNil;b=t;c=u;d=v;return[b,c,d];}else if(o===(120)){if(f===\"\"){break;}w=AO(f);k=w[0];f=w[1];d=w[2];if(!($interfaceIsEqual(d,$ifaceNil))){x=0;y=\"\";z=d;b=x;c=y;d=z;return[b,c,d];}if(k===123){aa=0;b=0;while(true){if(f===\"\"){break Switch;}ab=AO(f);k=ab[0];f=ab[1];d=ab[2];if(!($interfaceIsEqual(d,$ifaceNil))){ac=0;ad=\"\";ae=d;b=ac;c=ad;d=ae;return[b,c,d];}if(k===125){break;}af=AQ(k);if(af<0){break Switch;}b=($imul(b,16))+af>>0;if(b>1114111){break Switch;}aa=aa+(1)>>0;}if(aa===0){break Switch;}ag=b;ah=f;ai=$ifaceNil;b=ag;c=ah;d=ai;return[b,c,d];}aj=AQ(k);ak=AO(f);k=ak[0];f=ak[1];d=ak[2];if(!($interfaceIsEqual(d,$ifaceNil))){al=0;am=\"\";an=d;b=al;c=am;d=an;return[b,c,d];}ao=AQ(k);if(aj<0||ao<0){break;}ap=($imul(aj,16))+ao>>0;aq=f;ar=$ifaceNil;b=ap;c=aq;d=ar;return[b,c,d];}else if(o===(97)){as=7;at=f;au=d;b=as;c=at;d=au;return[b,c,d];}else if(o===(102)){av=12;aw=f;ax=d;b=av;c=aw;d=ax;return[b,c,d];}else if(o===(110)){ay=10;az=f;ba=d;b=ay;c=az;d=ba;return[b,c,d];}else if(o===(114)){bb=13;bc=f;bd=d;b=bb;c=bc;d=bd;return[b,c,d];}else if(o===(116)){be=9;bf=f;bg=d;b=be;c=bf;d=bg;return[b,c,d];}else if(o===(118)){bh=11;bi=f;bj=d;b=bh;c=bi;d=bj;return[b,c,d];}else if(k<128&&!AP(k)){bk=k;bl=f;bm=$ifaceNil;b=bk;c=bl;d=bm;return[b,c,d];}}bn=0;bo=\"\";bp=new M.ptr(\"invalid escape sequence\",$substring(a,0,(a.length-f.length>>0)));b=bn;c=bo;d=bp;return[b,c,d];};P.prototype.parseEscape=function(a){return this.$val.parseEscape(a);};P.ptr.prototype.parseClassChar=function(a,b){var a,b,c,d,e,f,g,h,i,j,k;c=0;d=\"\";e=$ifaceNil;f=this;if(a===\"\"){g=0;h=\"\";i=new M.ptr(\"missing closing ]\",b);c=g;d=h;e=i;return[c,d,e];}if(a.charCodeAt(0)===92){j=f.parseEscape(a);c=j[0];d=j[1];e=j[2];return[c,d,e];}k=AO(a);c=k[0];d=k[1];e=k[2];return[c,d,e];};P.prototype.parseClassChar=function(a,b){return this.$val.parseClassChar(a,b);};P.ptr.prototype.parsePerlClassEscape=function(a,b){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=CA.nil;d=\"\";e=this;if((((e.flags&64)>>>0)===0)||a.length<2||!((a.charCodeAt(0)===92))){$s=-1;return[c,d];}g=$clone((f=AU[$String.keyFor($substring(a,0,2))],f!==undefined?f.v:new Z.ptr(0,CA.nil)),Z);if(g.sign===0){$s=-1;return[c,d];}i=e.appendGroup(b,$clone(g,Z));$s=1;case 1:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;j=$substring(a,2);c=h;d=j;$s=-1;return[c,d];}return;}if($f===undefined){$f={$blk:P.ptr.prototype.parsePerlClassEscape};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.parsePerlClassEscape=function(a,b){return this.$val.parsePerlClassEscape(a,b);};P.ptr.prototype.parseNamedClass=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=CA.nil;d=\"\";e=$ifaceNil;f=this;if(a.length<2||!((a.charCodeAt(0)===91))||!((a.charCodeAt(1)===58))){$s=-1;return[c,d,e];}g=D.Index($substring(a,2),\":]\");if(g<0){$s=-1;return[c,d,e];}g=g+(2)>>0;h=$substring(a,0,(g+2>>0));i=$substring(a,(g+2>>0));j=h;a=i;l=$clone((k=BJ[$String.keyFor(j)],k!==undefined?k.v:new Z.ptr(0,CA.nil)),Z);if(l.sign===0){m=CA.nil;n=\"\";o=new M.ptr(\"invalid character class range\",j);c=m;d=n;e=o;$s=-1;return[c,d,e];}q=f.appendGroup(b,$clone(l,Z));$s=1;case 1:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;r=a;s=$ifaceNil;c=p;d=r;e=s;$s=-1;return[c,d,e];}return;}if($f===undefined){$f={$blk:P.ptr.prototype.parseNamedClass};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.parseNamedClass=function(a,b){return this.$val.parseNamedClass(a,b);};P.ptr.prototype.appendGroup=function(a,b){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(((c.flags&1)>>>0)===0){$s=1;continue;}$s=2;continue;case 1:if(b.sign<0){a=AI(a,b.class$1);}else{a=AG(a,b.class$1);}$s=3;continue;case 2:d=$subslice(c.tmpClass,0,0);d=AH(d,b.class$1);c.tmpClass=d;e=AC((c.$ptr_tmpClass||(c.$ptr_tmpClass=new CK(function(){return this.$target.tmpClass;},function($v){this.$target.tmpClass=$v;},c))));$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;if(b.sign<0){a=AI(a,d);}else{a=AG(a,d);}case 3:$s=-1;return a;}return;}if($f===undefined){$f={$blk:P.ptr.prototype.appendGroup};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.appendGroup=function(a,b){return this.$val.appendGroup(a,b);};AB=function(a){var a,b,c,d,e,f,g;if(a===\"Any\"){return[AA,AA];}c=(b=A.Categories[$String.keyFor(a)],b!==undefined?b.v:CL.nil);if(!(c===CL.nil)){return[c,(d=A.FoldCategory[$String.keyFor(a)],d!==undefined?d.v:CL.nil)];}f=(e=A.Scripts[$String.keyFor(a)],e!==undefined?e.v:CL.nil);if(!(f===CL.nil)){return[f,(g=A.FoldScript[$String.keyFor(a)],g!==undefined?g.v:CL.nil)];}return[CL.nil,CL.nil];};P.ptr.prototype.parseUnicodeClass=function(a,b){var a,aa,ab,ac,ad,ae,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=CA.nil;d=\"\";e=$ifaceNil;f=this;if((((f.flags&128)>>>0)===0)||a.length<2||!((a.charCodeAt(0)===92))||!((a.charCodeAt(1)===112))&&!((a.charCodeAt(1)===80))){$s=-1;return[c,d,e];}g=1;if(a.charCodeAt(1)===80){g=-1;}h=$substring(a,2);i=AO(h);j=i[0];h=i[1];e=i[2];if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[c,d,e];}k=\"\";l=\"\";m=k;n=l;if(!((j===123))){m=$substring(a,0,(a.length-h.length>>0));n=$substring(m,2);}else{o=D.IndexRune(a,125);if(o<0){e=AN(a);if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[c,d,e];}p=CA.nil;q=\"\";r=new M.ptr(\"invalid character class range\",a);c=p;d=q;e=r;$s=-1;return[c,d,e];}s=$substring(a,0,(o+1>>0));t=$substring(a,(o+1>>0));m=s;h=t;n=$substring(a,3,o);e=AN(n);if(!($interfaceIsEqual(e,$ifaceNil))){$s=-1;return[c,d,e];}}if(!(n===\"\")&&(n.charCodeAt(0)===94)){g=-g;n=$substring(n,1);}u=AB(n);v=u[0];w=u[1];if(v===CL.nil){x=CA.nil;y=\"\";z=new M.ptr(\"invalid character class range\",m);c=x;d=y;e=z;$s=-1;return[c,d,e];}if((((f.flags&1)>>>0)===0)||w===CL.nil){$s=1;continue;}$s=2;continue;case 1:if(g>0){b=AJ(b,v);}else{b=AK(b,v);}$s=3;continue;case 2:aa=$subslice(f.tmpClass,0,0);aa=AJ(aa,v);aa=AJ(aa,w);f.tmpClass=aa;ab=AC((f.$ptr_tmpClass||(f.$ptr_tmpClass=new CK(function(){return this.$target.tmpClass;},function($v){this.$target.tmpClass=$v;},f))));$s=4;case 4:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=ab;if(g>0){b=AG(b,aa);}else{b=AI(b,aa);}case 3:ac=b;ad=h;ae=$ifaceNil;c=ac;d=ad;e=ae;$s=-1;return[c,d,e];}return;}if($f===undefined){$f={$blk:P.ptr.prototype.parseUnicodeClass};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.parseUnicodeClass=function(a,b){return this.$val.parseUnicodeClass(a,b);};P.ptr.prototype.parseClass=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;ba=$f.ba;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=\"\";c=$ifaceNil;d=this;e=$substring(a,1);f=d.newRegexp(4);f.Flags=d.flags;f.Rune=$subslice(new CA(f.Rune0),0,0);g=1;if(!(e===\"\")&&(e.charCodeAt(0)===94)){g=-1;e=$substring(e,1);if(((d.flags&4)>>>0)===0){f.Rune=$append(f.Rune,10,10);}}h=f.Rune;i=true;case 1:if(!(e===\"\"||!((e.charCodeAt(0)===93))||i)){$s=2;continue;}if(!(e===\"\")&&(e.charCodeAt(0)===45)&&(((d.flags&64)>>>0)===0)&&!i&&((e.length===1)||!((e.charCodeAt(1)===93)))){j=E.DecodeRuneInString($substring(e,1));k=j[1];l=\"\";m=new M.ptr(\"invalid character class range\",$substring(e,0,(1+k>>0)));b=l;c=m;$s=-1;return[b,c];}i=false;if(e.length>2&&(e.charCodeAt(0)===91)&&(e.charCodeAt(1)===58)){$s=3;continue;}$s=4;continue;case 3:o=d.parseNamedClass(e,h);$s=5;case 5:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;p=n[0];q=n[1];r=n[2];if(!($interfaceIsEqual(r,$ifaceNil))){s=\"\";t=r;b=s;c=t;$s=-1;return[b,c];}if(!(p===CA.nil)){u=p;v=q;h=u;e=v;$s=1;continue;}case 4:x=d.parseUnicodeClass(e,h);$s=6;case 6:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}w=x;y=w[0];z=w[1];aa=w[2];if(!($interfaceIsEqual(aa,$ifaceNil))){ab=\"\";ac=aa;b=ab;c=ac;$s=-1;return[b,c];}if(!(y===CA.nil)){$s=7;continue;}$s=8;continue;case 7:ad=y;ae=z;h=ad;e=ae;$s=1;continue;case 8:ag=d.parsePerlClassEscape(e,h);$s=9;case 9:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}af=ag;ah=af[0];ai=af[1];if(!(ah===CA.nil)){aj=ah;ak=ai;h=aj;e=ak;$s=1;continue;}al=e;am=0;an=0;ao=am;ap=an;aq=d.parseClassChar(e,a);ao=aq[0];e=aq[1];aa=aq[2];if(!($interfaceIsEqual(aa,$ifaceNil))){ar=\"\";as=aa;b=ar;c=as;$s=-1;return[b,c];}ap=ao;if(e.length>=2&&(e.charCodeAt(0)===45)&&!((e.charCodeAt(1)===93))){e=$substring(e,1);at=d.parseClassChar(e,a);ap=at[0];e=at[1];aa=at[2];if(!($interfaceIsEqual(aa,$ifaceNil))){au=\"\";av=aa;b=au;c=av;$s=-1;return[b,c];}if(ap<ao){al=$substring(al,0,(al.length-e.length>>0));aw=\"\";ax=new M.ptr(\"invalid character class range\",al);b=aw;c=ax;$s=-1;return[b,c];}}if(((d.flags&1)>>>0)===0){h=AE(h,ao,ap);}else{h=AF(h,ao,ap);}$s=1;continue;case 2:e=$substring(e,1);f.Rune=h;ay=AC((f.$ptr_Rune||(f.$ptr_Rune=new CK(function(){return this.$target.Rune;},function($v){this.$target.Rune=$v;},f))));$s=10;case 10:if($c){$c=false;ay=ay.$blk();}if(ay&&ay.$blk!==undefined){break s;}h=ay;if(g<0){h=AL(h);}f.Rune=h;d.push(f);az=e;ba=$ifaceNil;b=az;c=ba;$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:P.ptr.prototype.parseClass};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.ba=ba;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};P.prototype.parseClass=function(a){return this.$val.parseClass(a);};AC=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=C.Sort((b=new AM.ptr(a),new b.constructor.elem(b)));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=a.$get();if(c.$length<2){$s=-1;return c;}d=2;e=2;while(true){if(!(e<c.$length)){break;}f=((e<0||e>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+e]);g=(h=e+1>>0,((h<0||h>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+h]));i=f;j=g;if(i<=((k=d-1>>0,((k<0||k>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+k]))+1>>0)){if(j>(l=d-1>>0,((l<0||l>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+l]))){(m=d-1>>0,((m<0||m>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+m]=j));}e=e+(2)>>0;continue;}((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=i);(n=d+1>>0,((n<0||n>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+n]=j));d=d+(2)>>0;e=e+(2)>>0;}$s=-1;return $subslice(c,0,d);}return;}if($f===undefined){$f={$blk:AC};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};AD=function(a,b,c){var a,b,c;if(!((((c&1)>>>0)===0))){return AF(a,b,b);}return AE(a,b,b);};AE=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m;d=a.$length;e=2;while(true){if(!(e<=4)){break;}if(d>=e){f=(g=d-e>>0,((g<0||g>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+g]));h=(i=(d-e>>0)+1>>0,((i<0||i>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+i]));j=f;k=h;if(b<=(k+1>>0)&&j<=(c+1>>0)){if(b<j){(l=d-e>>0,((l<0||l>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+l]=b));}if(c>k){(m=(d-e>>0)+1>>0,((m<0||m>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+m]=c));}return a;}}e=e+(2)>>0;}return $append(a,b,c);};AF=function(a,b,c){var a,b,c,d,e;if(b<=65&&c>=125251){return AE(a,b,c);}if(c<65||b>125251){return AE(a,b,c);}if(b<65){a=AE(a,b,64);b=65;}if(c>125251){a=AE(a,125252,c);c=125251;}d=b;while(true){if(!(d<=c)){break;}a=AE(a,d,d);e=A.SimpleFold(d);while(true){if(!(!((e===d)))){break;}a=AE(a,e,e);e=A.SimpleFold(e);}d=d+(1)>>0;}return a;};AG=function(a,b){var a,b,c,d;c=0;while(true){if(!(c<b.$length)){break;}a=AE(a,((c<0||c>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+c]),(d=c+1>>0,((d<0||d>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+d])));c=c+(2)>>0;}return a;};AH=function(a,b){var a,b,c,d;c=0;while(true){if(!(c<b.$length)){break;}a=AF(a,((c<0||c>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+c]),(d=c+1>>0,((d<0||d>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+d])));c=c+(2)>>0;}return a;};AI=function(a,b){var a,b,c,d,e,f,g,h,i;c=0;d=0;while(true){if(!(d<b.$length)){break;}e=((d<0||d>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+d]);f=(g=d+1>>0,((g<0||g>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+g]));h=e;i=f;if(c<=(h-1>>0)){a=AE(a,c,h-1>>0);}c=i+1>>0;d=d+(2)>>0;}if(c<=1114111){a=AE(a,c,1114111);}return a;};AJ=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;c=b.R16;d=0;while(true){if(!(d<c.$length)){break;}e=$clone(((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]),A.Range16);f=((e.Lo>>0));g=((e.Hi>>0));h=((e.Stride>>0));i=f;j=g;k=h;if(k===1){a=AE(a,i,j);d++;continue;}l=i;while(true){if(!(l<=j)){break;}a=AE(a,l,l);l=l+(k)>>0;}d++;}m=b.R32;n=0;while(true){if(!(n<m.$length)){break;}o=$clone(((n<0||n>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+n]),A.Range32);p=((o.Lo>>0));q=((o.Hi>>0));r=((o.Stride>>0));s=p;t=q;u=r;if(u===1){a=AE(a,s,t);n++;continue;}v=s;while(true){if(!(v<=t)){break;}a=AE(a,v,v);v=v+(u)>>0;}n++;}return a;};AK=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;c=0;d=b.R16;e=0;while(true){if(!(e<d.$length)){break;}f=$clone(((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]),A.Range16);g=((f.Lo>>0));h=((f.Hi>>0));i=((f.Stride>>0));j=g;k=h;l=i;if(l===1){if(c<=(j-1>>0)){a=AE(a,c,j-1>>0);}c=k+1>>0;e++;continue;}m=j;while(true){if(!(m<=k)){break;}if(c<=(m-1>>0)){a=AE(a,c,m-1>>0);}c=m+1>>0;m=m+(l)>>0;}e++;}n=b.R32;o=0;while(true){if(!(o<n.$length)){break;}p=$clone(((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]),A.Range32);q=((p.Lo>>0));r=((p.Hi>>0));s=((p.Stride>>0));t=q;u=r;v=s;if(v===1){if(c<=(t-1>>0)){a=AE(a,c,t-1>>0);}c=u+1>>0;o++;continue;}w=t;while(true){if(!(w<=u)){break;}if(c<=(w-1>>0)){a=AE(a,c,w-1>>0);}c=w+1>>0;w=w+(v)>>0;}o++;}if(c<=1114111){a=AE(a,c,1114111);}return a;};AL=function(a){var a,b,c,d,e,f,g,h,i,j;b=0;c=0;d=0;while(true){if(!(d<a.$length)){break;}e=((d<0||d>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+d]);f=(g=d+1>>0,((g<0||g>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+g]));h=e;i=f;if(b<=(h-1>>0)){((c<0||c>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+c]=b);(j=c+1>>0,((j<0||j>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+j]=(h-1>>0)));c=c+(2)>>0;}b=i+1>>0;d=d+(2)>>0;}a=$subslice(a,0,c);if(b<=1114111){a=$append(a,b,1114111);}return a;};AM.ptr.prototype.Less=function(a,b){var a,b,c,d,e,f;c=this;d=c.p.$get();a=$imul(a,(2));b=$imul(b,(2));return((a<0||a>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+a])<((b<0||b>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+b])||(((a<0||a>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+a])===((b<0||b>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+b]))&&(e=a+1>>0,((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]))>(f=b+1>>0,((f<0||f>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+f]));};AM.prototype.Less=function(a,b){return this.$val.Less(a,b);};AM.ptr.prototype.Len=function(){var a,b;a=this;return(b=a.p.$get().$length/2,(b===b&&b!==1/0&&b!==-1/0)?b>>0:$throwRuntimeError(\"integer divide by zero\"));};AM.prototype.Len=function(){return this.$val.Len();};AM.ptr.prototype.Swap=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l;c=this;d=c.p.$get();a=$imul(a,(2));b=$imul(b,(2));e=((b<0||b>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+b]);f=(g=b+1>>0,((g<0||g>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+g]));h=((a<0||a>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+a]);i=(j=a+1>>0,((j<0||j>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+j]));((a<0||a>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+a]=e);(k=a+1>>0,((k<0||k>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+k]=f));((b<0||b>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+b]=h);(l=b+1>>0,((l<0||l>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+l]=i));};AM.prototype.Swap=function(a,b){return this.$val.Swap(a,b);};AN=function(a){var a,b,c,d;while(true){if(!(!(a===\"\"))){break;}b=E.DecodeRuneInString(a);c=b[0];d=b[1];if((c===65533)&&(d===1)){return new M.ptr(\"invalid UTF-8\",a);}a=$substring(a,d);}return $ifaceNil;};AO=function(a){var a,b,c,d,e,f,g,h,i,j,k,l;b=0;c=\"\";d=$ifaceNil;e=E.DecodeRuneInString(a);b=e[0];f=e[1];if((b===65533)&&(f===1)){g=0;h=\"\";i=new M.ptr(\"invalid UTF-8\",a);b=g;c=h;d=i;return[b,c,d];}j=b;k=$substring(a,f);l=$ifaceNil;b=j;c=k;d=l;return[b,c,d];};AP=function(a){var a;return 48<=a&&a<=57||65<=a&&a<=90||97<=a&&a<=122;};AQ=function(a){var a;if(48<=a&&a<=57){return a-48>>0;}if(97<=a&&a<=102){return(a-97>>0)+10>>0;}if(65<=a&&a<=70){return(a-65>>0)+10>>0;}return-1;};BL.prototype.String=function(){var a;a=this.$val;if(((a>>>0))>=((BM.$length>>>0))){return\"\";}return((a<0||a>=BM.$length)?($throwRuntimeError(\"index out of range\"),undefined):BM.$array[BM.$offset+a]);};$ptrType(BL).prototype.String=function(){return new BL(this.$get()).String();};BP=function(a){var a;return 65<=a&&a<=90||97<=a&&a<=122||48<=a&&a<=57||(a===95);};$pkg.IsWordChar=BP;BK.ptr.prototype.String=function(){var a,b;a=this;b=new D.Builder.ptr(CM.nil,CN.nil);BS(b,a);return b.String();};BK.prototype.String=function(){return this.$val.String();};BK.ptr.prototype.skipNop=function(a){var a,b,c,d,e,f;b=this;d=(c=b.Inst,((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]));while(true){if(!((d.Op===6)||(d.Op===2))){break;}d=(e=b.Inst,f=d.Out,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));}return d;};BK.prototype.skipNop=function(a){return this.$val.skipNop(a);};BQ.ptr.prototype.op=function(){var a,b,c;a=this;b=a.Op;c=b;if((c===(8))||(c===(9))||(c===(10))){b=7;}return b;};BQ.prototype.op=function(){return this.$val.op();};BK.ptr.prototype.Prefix=function(){var a,b,c,d,e,f,g,h,i,j;a=\"\";b=false;c=this;d=c.skipNop(((c.Start>>>0)));if(!((d.op()===7))||!((d.Rune.$length===1))){e=\"\";f=d.Op===4;a=e;b=f;return[a,b];}g=new D.Builder.ptr(CM.nil,CN.nil);while(true){if(!((d.op()===7)&&(d.Rune.$length===1)&&(((((d.Arg<<16>>>16))&1)>>>0)===0))){break;}g.WriteRune((h=d.Rune,(0>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+0])));d=c.skipNop(d.Out);}i=g.String();j=d.Op===4;a=i;b=j;return[a,b];};BK.prototype.Prefix=function(){return this.$val.Prefix();};BK.ptr.prototype.StartCond=function(){var a,b,c,d,e,f,g;a=this;b=0;c=((a.Start>>>0));e=(d=a.Inst,((c<0||c>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+c]));Loop:while(true){f=e.Op;if(f===(3)){b=(b|(((e.Arg<<24>>>24))))>>>0;}else if(f===(5)){return 255;}else if((f===(2))||(f===(6))){}else{break Loop;}c=e.Out;e=(g=a.Inst,((c<0||c>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+c]));}return b;};BK.prototype.StartCond=function(){return this.$val.StartCond();};BQ.ptr.prototype.MatchRune=function(a){var a,b;b=this;return!((b.MatchRunePos(a)===-1));};BQ.prototype.MatchRune=function(a){return this.$val.MatchRune(a);};BQ.ptr.prototype.MatchRunePos=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;b=this;c=b.Rune;d=c.$length;if(d===(0)){return-1;}else if(d===(1)){e=(0>=c.$length?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+0]);if(a===e){return 0;}if(!((((((b.Arg<<16>>>16))&1)>>>0)===0))){f=A.SimpleFold(e);while(true){if(!(!((f===e)))){break;}if(a===f){return 0;}f=A.SimpleFold(f);}}return-1;}else if(d===(2)){if(a>=(0>=c.$length?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+0])&&a<=(1>=c.$length?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+1])){return 0;}return-1;}else if((d===(4))||(d===(6))||(d===(8))){g=0;while(true){if(!(g<c.$length)){break;}if(a<((g<0||g>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+g])){return-1;}if(a<=(h=g+1>>0,((h<0||h>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+h]))){return(i=g/2,(i===i&&i!==1/0&&i!==-1/0)?i>>0:$throwRuntimeError(\"integer divide by zero\"));}g=g+(2)>>0;}return-1;}j=0;l=(k=c.$length/2,(k===k&&k!==1/0&&k!==-1/0)?k>>0:$throwRuntimeError(\"integer divide by zero\"));while(true){if(!(j<l)){break;}n=j+(m=((l-j>>0))/2,(m===m&&m!==1/0&&m!==-1/0)?m>>0:$throwRuntimeError(\"integer divide by zero\"))>>0;p=(o=$imul(2,n),((o<0||o>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+o]));if(p<=a){if(a<=(q=($imul(2,n))+1>>0,((q<0||q>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+q]))){return n;}j=n+1>>0;}else{l=n;}}return-1;};BQ.prototype.MatchRunePos=function(a){return this.$val.MatchRunePos(a);};BQ.ptr.prototype.MatchEmptyWidth=function(a,b){var a,b,c,d;c=this;d=((c.Arg<<24>>>24));if(d===(1)){return(a===10)||(a===-1);}else if(d===(2)){return(b===10)||(b===-1);}else if(d===(4)){return a===-1;}else if(d===(8)){return b===-1;}else if(d===(16)){return!(BP(a)===BP(b));}else if(d===(32)){return BP(a)===BP(b);}$panic(new $String(\"unknown empty width arg\"));};BQ.prototype.MatchEmptyWidth=function(a,b){return this.$val.MatchEmptyWidth(a,b);};BQ.ptr.prototype.String=function(){var a,b;a=this;b=new D.Builder.ptr(CM.nil,CN.nil);BU(b,a);return b.String();};BQ.prototype.String=function(){return this.$val.String();};BR=function(a,b){var a,b,c,d,e;c=b;d=0;while(true){if(!(d<c.$length)){break;}e=((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]);a.WriteString(e);d++;}};BS=function(a,b){var a,b,c,d,e,f,g,h;c=b.Inst;d=0;while(true){if(!(d<c.$length)){break;}e=d;g=(f=b.Inst,((e<0||e>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+e]));h=B.Itoa(e);if(h.length<3){a.WriteString($substring(\"   \",h.length));}if(e===b.Start){h=h+(\"*\");}BR(a,new CD([h,\"\\t\"]));BU(a,g);BR(a,new CD([\"\\n\"]));d++;}};BT=function(a){var a;return B.FormatUint((new $Uint64(0,a)),10);};BU=function(a,b){var a,b,c;c=b.Op;if(c===(0)){BR(a,new CD([\"alt -> \",BT(b.Out),\", \",BT(b.Arg)]));}else if(c===(1)){BR(a,new CD([\"altmatch -> \",BT(b.Out),\", \",BT(b.Arg)]));}else if(c===(2)){BR(a,new CD([\"cap \",BT(b.Arg),\" -> \",BT(b.Out)]));}else if(c===(3)){BR(a,new CD([\"empty \",BT(b.Arg),\" -> \",BT(b.Out)]));}else if(c===(4)){BR(a,new CD([\"match\"]));}else if(c===(5)){BR(a,new CD([\"fail\"]));}else if(c===(6)){BR(a,new CD([\"nop -> \",BT(b.Out)]));}else if(c===(7)){if(b.Rune===CA.nil){BR(a,new CD([\"rune <nil>\"]));}BR(a,new CD([\"rune \",B.QuoteToASCII(($runesToString(b.Rune)))]));if(!((((((b.Arg<<16>>>16))&1)>>>0)===0))){BR(a,new CD([\"/i\"]));}BR(a,new CD([\" -> \",BT(b.Out)]));}else if(c===(8)){BR(a,new CD([\"rune1 \",B.QuoteToASCII(($runesToString(b.Rune))),\" -> \",BT(b.Out)]));}else if(c===(9)){BR(a,new CD([\"any -> \",BT(b.Out)]));}else if(c===(10)){BR(a,new CD([\"anynotnl -> \",BT(b.Out)]));}};BV.ptr.prototype.Equal=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;b=this;if(b===CG.nil||a===CG.nil){return b===a;}if(!((b.Op===a.Op))){return false;}c=b.Op;if(c===(10)){if(!((((b.Flags&256)>>>0)===((a.Flags&256)>>>0)))){return false;}}else if((c===(3))||(c===(4))){if(!((b.Rune.$length===a.Rune.$length))){return false;}d=b.Rune;e=0;while(true){if(!(e<d.$length)){break;}f=e;g=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);if(!((g===(h=a.Rune,((f<0||f>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+f]))))){return false;}e++;}}else if((c===(19))||(c===(18))){if(!((b.Sub.$length===a.Sub.$length))){return false;}i=b.Sub;j=0;while(true){if(!(j<i.$length)){break;}k=j;l=((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]);if(!l.Equal((m=a.Sub,((k<0||k>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+k])))){return false;}j++;}}else if((c===(14))||(c===(15))||(c===(16))){if(!((((b.Flags&32)>>>0)===((a.Flags&32)>>>0)))||!(n=b.Sub,(0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0])).Equal((o=a.Sub,(0>=o.$length?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+0])))){return false;}}else if(c===(17)){if(!((((b.Flags&32)>>>0)===((a.Flags&32)>>>0)))||!((b.Min===a.Min))||!((b.Max===a.Max))||!(p=b.Sub,(0>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+0])).Equal((q=a.Sub,(0>=q.$length?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+0])))){return false;}}else if(c===(13)){if(!((b.Cap===a.Cap))||!(b.Name===a.Name)||!(r=b.Sub,(0>=r.$length?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+0])).Equal((s=a.Sub,(0>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+0])))){return false;}}return true;};BV.prototype.Equal=function(a){return this.$val.Equal(a);};BX=function(a,b){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;switch(0){default:c=b.Op;if(c===(1)){a.WriteString(\"[^\\\\x00-\\\\x{10FFFF}]\");}else if(c===(2)){a.WriteString(\"(?:)\");}else if(c===(3)){if(!((((b.Flags&1)>>>0)===0))){a.WriteString(\"(?i:\");}d=b.Rune;e=0;while(true){if(!(e<d.$length)){break;}f=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);BY(a,f,false);e++;}if(!((((b.Flags&1)>>>0)===0))){a.WriteString(\")\");}}else if(c===(4)){if(!(((g=b.Rune.$length%2,g===g?g:$throwRuntimeError(\"integer divide by zero\"))===0))){a.WriteString(\"[invalid char class]\");break;}a.WriteRune(91);if(b.Rune.$length===0){a.WriteString(\"^\\\\x00-\\\\x{10FFFF}\");}else if(((h=b.Rune,(0>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+0]))===0)&&((i=b.Rune,j=b.Rune.$length-1>>0,((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]))===1114111)){a.WriteRune(94);k=1;while(true){if(!(k<(b.Rune.$length-1>>0))){break;}l=(m=b.Rune,((k<0||k>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+k]))+1>>0;n=(o=b.Rune,p=k+1>>0,((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]))-1>>0;q=l;r=n;BY(a,q,q===45);if(!((q===r))){a.WriteRune(45);BY(a,r,r===45);}k=k+(2)>>0;}}else{s=0;while(true){if(!(s<b.Rune.$length)){break;}t=(u=b.Rune,((s<0||s>=u.$length)?($throwRuntimeError(\"index out of range\"),undefined):u.$array[u.$offset+s]));v=(w=b.Rune,x=s+1>>0,((x<0||x>=w.$length)?($throwRuntimeError(\"index out of range\"),undefined):w.$array[w.$offset+x]));y=t;z=v;BY(a,y,y===45);if(!((y===z))){a.WriteRune(45);BY(a,z,z===45);}s=s+(2)>>0;}}a.WriteRune(93);}else if(c===(5)){a.WriteString(\"(?-s:.)\");}else if(c===(6)){a.WriteString(\"(?s:.)\");}else if(c===(7)){a.WriteString(\"(?m:^)\");}else if(c===(8)){a.WriteString(\"(?m:$)\");}else if(c===(9)){a.WriteString(\"\\\\A\");}else if(c===(10)){if(!((((b.Flags&256)>>>0)===0))){a.WriteString(\"(?-m:$)\");}else{a.WriteString(\"\\\\z\");}}else if(c===(11)){a.WriteString(\"\\\\b\");}else if(c===(12)){a.WriteString(\"\\\\B\");}else if(c===(13)){if(!(b.Name===\"\")){a.WriteString(\"(?P<\");a.WriteString(b.Name);a.WriteRune(62);}else{a.WriteRune(40);}if(!(((aa=b.Sub,(0>=aa.$length?($throwRuntimeError(\"index out of range\"),undefined):aa.$array[aa.$offset+0])).Op===2))){BX(a,(ab=b.Sub,(0>=ab.$length?($throwRuntimeError(\"index out of range\"),undefined):ab.$array[ab.$offset+0])));}a.WriteRune(41);}else if((c===(14))||(c===(15))||(c===(16))||(c===(17))){ad=(ac=b.Sub,(0>=ac.$length?($throwRuntimeError(\"index out of range\"),undefined):ac.$array[ac.$offset+0]));if(ad.Op>13||(ad.Op===3)&&ad.Rune.$length>1){a.WriteString(\"(?:\");BX(a,ad);a.WriteString(\")\");}else{BX(a,ad);}ae=b.Op;if(ae===(14)){a.WriteRune(42);}else if(ae===(15)){a.WriteRune(43);}else if(ae===(16)){a.WriteRune(63);}else if(ae===(17)){a.WriteRune(123);a.WriteString(B.Itoa(b.Min));if(!((b.Max===b.Min))){a.WriteRune(44);if(b.Max>=0){a.WriteString(B.Itoa(b.Max));}}a.WriteRune(125);}if(!((((b.Flags&32)>>>0)===0))){a.WriteRune(63);}}else if(c===(18)){af=b.Sub;ag=0;while(true){if(!(ag<af.$length)){break;}ah=((ag<0||ag>=af.$length)?($throwRuntimeError(\"index out of range\"),undefined):af.$array[af.$offset+ag]);if(ah.Op===19){a.WriteString(\"(?:\");BX(a,ah);a.WriteString(\")\");}else{BX(a,ah);}ag++;}}else if(c===(19)){ai=b.Sub;aj=0;while(true){if(!(aj<ai.$length)){break;}ak=aj;al=((aj<0||aj>=ai.$length)?($throwRuntimeError(\"index out of range\"),undefined):ai.$array[ai.$offset+aj]);if(ak>0){a.WriteRune(124);}BX(a,al);aj++;}}else{a.WriteString(\"<invalid op\"+B.Itoa(((b.Op>>0)))+\">\");}}};BV.ptr.prototype.String=function(){var a,b;a=this;b=new D.Builder.ptr(CM.nil,CN.nil);BX(b,a);return b.String();};BV.prototype.String=function(){return this.$val.String();};BY=function(a,b,c){var a,b,c,d,e;if(A.IsPrint(b)){if(D.ContainsRune(\"\\\\.+*?()|[]{}^$\",b)||c){a.WriteRune(92);}a.WriteRune(b);return;}switch(0){default:d=b;if(d===(7)){a.WriteString(\"\\\\a\");}else if(d===(12)){a.WriteString(\"\\\\f\");}else if(d===(10)){a.WriteString(\"\\\\n\");}else if(d===(13)){a.WriteString(\"\\\\r\");}else if(d===(9)){a.WriteString(\"\\\\t\");}else if(d===(11)){a.WriteString(\"\\\\v\");}else{if(b<256){a.WriteString(\"\\\\x\");e=B.FormatInt((new $Int64(0,b)),16);if(e.length===1){a.WriteRune(48);}a.WriteString(e);break;}a.WriteString(\"\\\\x{\");a.WriteString(B.FormatInt((new $Int64(0,b)),16));a.WriteString(\"}\");}}};BV.ptr.prototype.MaxCap=function(){var a,b,c,d,e,f;a=this;b=0;if(a.Op===13){b=a.Cap;}c=a.Sub;d=0;while(true){if(!(d<c.$length)){break;}e=((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]);f=e.MaxCap();if(b<f){b=f;}d++;}return b;};BV.prototype.MaxCap=function(){return this.$val.MaxCap();};BV.ptr.prototype.CapNames=function(){var a,b;a=this;b=$makeSlice(CD,(a.MaxCap()+1>>0));a.capNames(b);return b;};BV.prototype.CapNames=function(){return this.$val.CapNames();};BV.ptr.prototype.capNames=function(a){var a,b,c,d,e,f;b=this;if(b.Op===13){(c=b.Cap,((c<0||c>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+c]=b.Name));}d=b.Sub;e=0;while(true){if(!(e<d.$length)){break;}f=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);f.capNames(a);e++;}};BV.prototype.capNames=function(a){return this.$val.capNames(a);};BV.ptr.prototype.Simplify=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;a=this;if(a===CG.nil){return CG.nil;}b=a.Op;if((b===(13))||(b===(18))||(b===(19))){c=a;d=a.Sub;e=0;while(true){if(!(e<d.$length)){break;}f=e;g=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);h=g.Simplify();if(c===a&&!(h===g)){c=new BV.ptr(0,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");BV.copy(c,a);c.Rune=CA.nil;c.Sub=$appendSlice($subslice(new CH(c.Sub0),0,0),$subslice(a.Sub,0,f));}if(!(c===a)){c.Sub=$append(c.Sub,h);}e++;}return c;}else if((b===(14))||(b===(15))||(b===(16))){j=(i=a.Sub,(0>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+0])).Simplify();return BZ(a.Op,a.Flags,j,a);}else if(b===(17)){if((a.Min===0)&&(a.Max===0)){return new BV.ptr(2,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");}l=(k=a.Sub,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])).Simplify();if(a.Max===-1){if(a.Min===0){return BZ(14,a.Flags,l,CG.nil);}if(a.Min===1){return BZ(15,a.Flags,l,CG.nil);}m=new BV.ptr(18,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");m.Sub=$subslice(new CH(m.Sub0),0,0);n=0;while(true){if(!(n<(a.Min-1>>0))){break;}m.Sub=$append(m.Sub,l);n=n+(1)>>0;}m.Sub=$append(m.Sub,BZ(15,a.Flags,l,CG.nil));return m;}if((a.Min===1)&&(a.Max===1)){return l;}o=CG.nil;if(a.Min>0){o=new BV.ptr(18,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");o.Sub=$subslice(new CH(o.Sub0),0,0);p=0;while(true){if(!(p<a.Min)){break;}o.Sub=$append(o.Sub,l);p=p+(1)>>0;}}if(a.Max>a.Min){q=BZ(16,a.Flags,l,CG.nil);r=a.Min+1>>0;while(true){if(!(r<a.Max)){break;}s=new BV.ptr(18,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");s.Sub=$append($subslice(new CH(s.Sub0),0,0),l,q);q=BZ(16,a.Flags,s,CG.nil);r=r+(1)>>0;}if(o===CG.nil){return q;}o.Sub=$append(o.Sub,q);}if(!(o===CG.nil)){return o;}return new BV.ptr(1,0,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");}return a;};BV.prototype.Simplify=function(){return this.$val.Simplify();};BZ=function(a,b,c,d){var a,b,c,d,e;if(c.Op===2){return c;}if((a===c.Op)&&(((b&32)>>>0)===((c.Flags&32)>>>0))){return c;}if(!(d===CG.nil)&&(d.Op===a)&&(((d.Flags&32)>>>0)===((b&32)>>>0))&&c===(e=d.Sub,(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]))){return d;}d=new BV.ptr(a,b,CH.nil,CI.zero(),CA.nil,CJ.zero(),0,0,0,\"\");d.Sub=$append($subslice(new CH(d.Sub0),0,0),c);return d;};F.methods=[{prop:\"next\",name:\"next\",pkg:\"regexp/syntax\",typ:$funcType([CE],[F],false)},{prop:\"patch\",name:\"patch\",pkg:\"regexp/syntax\",typ:$funcType([CE,$Uint32],[],false)},{prop:\"append\",name:\"append\",pkg:\"regexp/syntax\",typ:$funcType([CE,F],[F],false)}];CO.methods=[{prop:\"init\",name:\"init\",pkg:\"regexp/syntax\",typ:$funcType([],[],false)},{prop:\"compile\",name:\"compile\",pkg:\"regexp/syntax\",typ:$funcType([CG],[G],false)},{prop:\"inst\",name:\"inst\",pkg:\"regexp/syntax\",typ:$funcType([BL],[G],false)},{prop:\"nop\",name:\"nop\",pkg:\"regexp/syntax\",typ:$funcType([],[G],false)},{prop:\"fail\",name:\"fail\",pkg:\"regexp/syntax\",typ:$funcType([],[G],false)},{prop:\"cap\",name:\"cap\",pkg:\"regexp/syntax\",typ:$funcType([$Uint32],[G],false)},{prop:\"cat\",name:\"cat\",pkg:\"regexp/syntax\",typ:$funcType([G,G],[G],false)},{prop:\"alt\",name:\"alt\",pkg:\"regexp/syntax\",typ:$funcType([G,G],[G],false)},{prop:\"quest\",name:\"quest\",pkg:\"regexp/syntax\",typ:$funcType([G,$Bool],[G],false)},{prop:\"star\",name:\"star\",pkg:\"regexp/syntax\",typ:$funcType([G,$Bool],[G],false)},{prop:\"plus\",name:\"plus\",pkg:\"regexp/syntax\",typ:$funcType([G,$Bool],[G],false)},{prop:\"empty\",name:\"empty\",pkg:\"regexp/syntax\",typ:$funcType([BN],[G],false)},{prop:\"rune\",name:\"rune\",pkg:\"regexp/syntax\",typ:$funcType([CA,O],[G],false)}];CP.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];N.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];CQ.methods=[{prop:\"newRegexp\",name:\"newRegexp\",pkg:\"regexp/syntax\",typ:$funcType([BW],[CG],false)},{prop:\"reuse\",name:\"reuse\",pkg:\"regexp/syntax\",typ:$funcType([CG],[],false)},{prop:\"push\",name:\"push\",pkg:\"regexp/syntax\",typ:$funcType([CG],[CG],false)},{prop:\"maybeConcat\",name:\"maybeConcat\",pkg:\"regexp/syntax\",typ:$funcType([$Int32,O],[$Bool],false)},{prop:\"newLiteral\",name:\"newLiteral\",pkg:\"regexp/syntax\",typ:$funcType([$Int32,O],[CG],false)},{prop:\"literal\",name:\"literal\",pkg:\"regexp/syntax\",typ:$funcType([$Int32],[],false)},{prop:\"op\",name:\"op\",pkg:\"regexp/syntax\",typ:$funcType([BW],[CG],false)},{prop:\"repeat\",name:\"repeat\",pkg:\"regexp/syntax\",typ:$funcType([BW,$Int,$Int,$String,$String,$String],[$String,$error],false)},{prop:\"concat\",name:\"concat\",pkg:\"regexp/syntax\",typ:$funcType([],[CG],false)},{prop:\"alternate\",name:\"alternate\",pkg:\"regexp/syntax\",typ:$funcType([],[CG],false)},{prop:\"collapse\",name:\"collapse\",pkg:\"regexp/syntax\",typ:$funcType([CH,BW],[CG],false)},{prop:\"factor\",name:\"factor\",pkg:\"regexp/syntax\",typ:$funcType([CH],[CH],false)},{prop:\"leadingString\",name:\"leadingString\",pkg:\"regexp/syntax\",typ:$funcType([CG],[CA,O],false)},{prop:\"removeLeadingString\",name:\"removeLeadingString\",pkg:\"regexp/syntax\",typ:$funcType([CG,$Int],[CG],false)},{prop:\"leadingRegexp\",name:\"leadingRegexp\",pkg:\"regexp/syntax\",typ:$funcType([CG],[CG],false)},{prop:\"removeLeadingRegexp\",name:\"removeLeadingRegexp\",pkg:\"regexp/syntax\",typ:$funcType([CG,$Bool],[CG],false)},{prop:\"parseRepeat\",name:\"parseRepeat\",pkg:\"regexp/syntax\",typ:$funcType([$String],[$Int,$Int,$String,$Bool],false)},{prop:\"parsePerlFlags\",name:\"parsePerlFlags\",pkg:\"regexp/syntax\",typ:$funcType([$String],[$String,$error],false)},{prop:\"parseInt\",name:\"parseInt\",pkg:\"regexp/syntax\",typ:$funcType([$String],[$Int,$String,$Bool],false)},{prop:\"parseVerticalBar\",name:\"parseVerticalBar\",pkg:\"regexp/syntax\",typ:$funcType([],[$error],false)},{prop:\"swapVerticalBar\",name:\"swapVerticalBar\",pkg:\"regexp/syntax\",typ:$funcType([],[$Bool],false)},{prop:\"parseRightParen\",name:\"parseRightParen\",pkg:\"regexp/syntax\",typ:$funcType([],[$error],false)},{prop:\"parseEscape\",name:\"parseEscape\",pkg:\"regexp/syntax\",typ:$funcType([$String],[$Int32,$String,$error],false)},{prop:\"parseClassChar\",name:\"parseClassChar\",pkg:\"regexp/syntax\",typ:$funcType([$String,$String],[$Int32,$String,$error],false)},{prop:\"parsePerlClassEscape\",name:\"parsePerlClassEscape\",pkg:\"regexp/syntax\",typ:$funcType([$String,CA],[CA,$String],false)},{prop:\"parseNamedClass\",name:\"parseNamedClass\",pkg:\"regexp/syntax\",typ:$funcType([$String,CA],[CA,$String,$error],false)},{prop:\"appendGroup\",name:\"appendGroup\",pkg:\"regexp/syntax\",typ:$funcType([CA,Z],[CA],false)},{prop:\"parseUnicodeClass\",name:\"parseUnicodeClass\",pkg:\"regexp/syntax\",typ:$funcType([$String,CA],[CA,$String,$error],false)},{prop:\"parseClass\",name:\"parseClass\",pkg:\"regexp/syntax\",typ:$funcType([$String],[$String,$error],false)}];AM.methods=[{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)},{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)}];CE.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"skipNop\",name:\"skipNop\",pkg:\"regexp/syntax\",typ:$funcType([$Uint32],[CR],false)},{prop:\"Prefix\",name:\"Prefix\",pkg:\"\",typ:$funcType([],[$String,$Bool],false)},{prop:\"StartCond\",name:\"StartCond\",pkg:\"\",typ:$funcType([],[BN],false)}];BL.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];CR.methods=[{prop:\"op\",name:\"op\",pkg:\"regexp/syntax\",typ:$funcType([],[BL],false)},{prop:\"MatchRune\",name:\"MatchRune\",pkg:\"\",typ:$funcType([$Int32],[$Bool],false)},{prop:\"MatchRunePos\",name:\"MatchRunePos\",pkg:\"\",typ:$funcType([$Int32],[$Int],false)},{prop:\"MatchEmptyWidth\",name:\"MatchEmptyWidth\",pkg:\"\",typ:$funcType([$Int32,$Int32],[$Bool],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];CG.methods=[{prop:\"Equal\",name:\"Equal\",pkg:\"\",typ:$funcType([CG],[$Bool],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"MaxCap\",name:\"MaxCap\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"CapNames\",name:\"CapNames\",pkg:\"\",typ:$funcType([],[CD],false)},{prop:\"capNames\",name:\"capNames\",pkg:\"regexp/syntax\",typ:$funcType([CD],[],false)},{prop:\"Simplify\",name:\"Simplify\",pkg:\"\",typ:$funcType([],[CG],false)}];BW.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];G.init(\"regexp/syntax\",[{prop:\"i\",name:\"i\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"out\",name:\"out\",embedded:false,exported:false,typ:F,tag:\"\"}]);H.init(\"regexp/syntax\",[{prop:\"p\",name:\"p\",embedded:false,exported:false,typ:CE,tag:\"\"}]);M.init(\"\",[{prop:\"Code\",name:\"Code\",embedded:false,exported:true,typ:N,tag:\"\"},{prop:\"Expr\",name:\"Expr\",embedded:false,exported:true,typ:$String,tag:\"\"}]);P.init(\"regexp/syntax\",[{prop:\"flags\",name:\"flags\",embedded:false,exported:false,typ:O,tag:\"\"},{prop:\"stack\",name:\"stack\",embedded:false,exported:false,typ:CH,tag:\"\"},{prop:\"free\",name:\"free\",embedded:false,exported:false,typ:CG,tag:\"\"},{prop:\"numCap\",name:\"numCap\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"wholeRegexp\",name:\"wholeRegexp\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"tmpClass\",name:\"tmpClass\",embedded:false,exported:false,typ:CA,tag:\"\"}]);Z.init(\"regexp/syntax\",[{prop:\"sign\",name:\"sign\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"class$1\",name:\"class\",embedded:false,exported:false,typ:CA,tag:\"\"}]);AM.init(\"regexp/syntax\",[{prop:\"p\",name:\"p\",embedded:false,exported:false,typ:CK,tag:\"\"}]);BK.init(\"\",[{prop:\"Inst\",name:\"Inst\",embedded:false,exported:true,typ:CF,tag:\"\"},{prop:\"Start\",name:\"Start\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"NumCap\",name:\"NumCap\",embedded:false,exported:true,typ:$Int,tag:\"\"}]);BQ.init(\"\",[{prop:\"Op\",name:\"Op\",embedded:false,exported:true,typ:BL,tag:\"\"},{prop:\"Out\",name:\"Out\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Arg\",name:\"Arg\",embedded:false,exported:true,typ:$Uint32,tag:\"\"},{prop:\"Rune\",name:\"Rune\",embedded:false,exported:true,typ:CA,tag:\"\"}]);BV.init(\"\",[{prop:\"Op\",name:\"Op\",embedded:false,exported:true,typ:BW,tag:\"\"},{prop:\"Flags\",name:\"Flags\",embedded:false,exported:true,typ:O,tag:\"\"},{prop:\"Sub\",name:\"Sub\",embedded:false,exported:true,typ:CH,tag:\"\"},{prop:\"Sub0\",name:\"Sub0\",embedded:false,exported:true,typ:CI,tag:\"\"},{prop:\"Rune\",name:\"Rune\",embedded:false,exported:true,typ:CA,tag:\"\"},{prop:\"Rune0\",name:\"Rune0\",embedded:false,exported:true,typ:CJ,tag:\"\"},{prop:\"Min\",name:\"Min\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Max\",name:\"Max\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Cap\",name:\"Cap\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:$String,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=C.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}J=new CA([0,9,11,1114111]);K=new CA([0,1114111]);L=$toNativeArray($kindUint8,[0,7,17,24,33,45,52,61,68,77,84,96,110,117,121,125,130,136,142,151]);AA=new A.RangeTable.ptr(new CB([new A.Range16.ptr(0,65535,1)]),new CC([new A.Range32.ptr(65536,1114111,1)]),0);AR=new CA([48,57]);AS=new CA([9,10,12,13,32,32]);AT=new CA([48,57,65,90,95,95,97,122]);AU=$makeMap($String.keyFor,[{k:\"\\\\d\",v:new Z.ptr(1,AR)},{k:\"\\\\D\",v:new Z.ptr(-1,AR)},{k:\"\\\\s\",v:new Z.ptr(1,AS)},{k:\"\\\\S\",v:new Z.ptr(-1,AS)},{k:\"\\\\w\",v:new Z.ptr(1,AT)},{k:\"\\\\W\",v:new Z.ptr(-1,AT)}]);AV=new CA([48,57,65,90,97,122]);AW=new CA([65,90,97,122]);AX=new CA([0,127]);AY=new CA([9,9,32,32]);AZ=new CA([0,31,127,127]);BA=new CA([48,57]);BB=new CA([33,126]);BC=new CA([97,122]);BD=new CA([32,126]);BE=new CA([33,47,58,64,91,96,123,126]);BF=new CA([9,13,32,32]);BG=new CA([65,90]);BH=new CA([48,57,65,90,95,95,97,122]);BI=new CA([48,57,65,70,97,102]);BJ=$makeMap($String.keyFor,[{k:\"[:alnum:]\",v:new Z.ptr(1,AV)},{k:\"[:^alnum:]\",v:new Z.ptr(-1,AV)},{k:\"[:alpha:]\",v:new Z.ptr(1,AW)},{k:\"[:^alpha:]\",v:new Z.ptr(-1,AW)},{k:\"[:ascii:]\",v:new Z.ptr(1,AX)},{k:\"[:^ascii:]\",v:new Z.ptr(-1,AX)},{k:\"[:blank:]\",v:new Z.ptr(1,AY)},{k:\"[:^blank:]\",v:new Z.ptr(-1,AY)},{k:\"[:cntrl:]\",v:new Z.ptr(1,AZ)},{k:\"[:^cntrl:]\",v:new Z.ptr(-1,AZ)},{k:\"[:digit:]\",v:new Z.ptr(1,BA)},{k:\"[:^digit:]\",v:new Z.ptr(-1,BA)},{k:\"[:graph:]\",v:new Z.ptr(1,BB)},{k:\"[:^graph:]\",v:new Z.ptr(-1,BB)},{k:\"[:lower:]\",v:new Z.ptr(1,BC)},{k:\"[:^lower:]\",v:new Z.ptr(-1,BC)},{k:\"[:print:]\",v:new Z.ptr(1,BD)},{k:\"[:^print:]\",v:new Z.ptr(-1,BD)},{k:\"[:punct:]\",v:new Z.ptr(1,BE)},{k:\"[:^punct:]\",v:new Z.ptr(-1,BE)},{k:\"[:space:]\",v:new Z.ptr(1,BF)},{k:\"[:^space:]\",v:new Z.ptr(-1,BF)},{k:\"[:upper:]\",v:new Z.ptr(1,BG)},{k:\"[:^upper:]\",v:new Z.ptr(-1,BG)},{k:\"[:word:]\",v:new Z.ptr(1,BH)},{k:\"[:^word:]\",v:new Z.ptr(-1,BH)},{k:\"[:xdigit:]\",v:new Z.ptr(1,BI)},{k:\"[:^xdigit:]\",v:new Z.ptr(-1,BI)}]);BM=new CD([\"InstAlt\",\"InstAltMatch\",\"InstCapture\",\"InstEmptyWidth\",\"InstMatch\",\"InstFail\",\"InstNop\",\"InstRune\",\"InstRune1\",\"InstRuneAny\",\"InstRuneAnyNotNL\"]);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"regexp\"]=(function(){var $pkg={},$init,G,B,C,A,D,H,E,F,I,J,K,Q,R,S,T,U,V,X,AC,AD,AH,AO,AT,BC,BD,BE,BF,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV,CW,CX,CY,CZ,DA,DB,DC,DD,DE,DF,L,Y,AB,AJ,AK,AP,AQ,AX,AY,BJ,M,N,O,P,W,Z,AA,AE,AF,AG,AI,AL,AM,AN,AR,AS,AU,AW,AZ,BB,BL,BN;G=$packages[\"bytes\"];B=$packages[\"github.com/gopherjs/gopherjs/nosync\"];C=$packages[\"io\"];A=$packages[\"regexp/syntax\"];D=$packages[\"sort\"];H=$packages[\"strconv\"];E=$packages[\"strings\"];F=$packages[\"unicode\"];I=$packages[\"unicode/utf8\"];J=$pkg.job=$newType(0,$kindStruct,\"regexp.job\",true,\"regexp\",false,function(pc_,arg_,pos_){this.$val=this;if(arguments.length===0){this.pc=0;this.arg=false;this.pos=0;return;}this.pc=pc_;this.arg=arg_;this.pos=pos_;});K=$pkg.bitState=$newType(0,$kindStruct,\"regexp.bitState\",true,\"regexp\",false,function(end_,cap_,matchcap_,jobs_,visited_,inputs_){this.$val=this;if(arguments.length===0){this.end=0;this.cap=BV.nil;this.matchcap=BV.nil;this.jobs=BW.nil;this.visited=BT.nil;this.inputs=new U.ptr(new BE.ptr(BX.nil),new BD.ptr(\"\"),new BF.ptr($ifaceNil,false,0));return;}this.end=end_;this.cap=cap_;this.matchcap=matchcap_;this.jobs=jobs_;this.visited=visited_;this.inputs=inputs_;});Q=$pkg.queue=$newType(0,$kindStruct,\"regexp.queue\",true,\"regexp\",false,function(sparse_,dense_){this.$val=this;if(arguments.length===0){this.sparse=BT.nil;this.dense=CP.nil;return;}this.sparse=sparse_;this.dense=dense_;});R=$pkg.entry=$newType(0,$kindStruct,\"regexp.entry\",true,\"regexp\",false,function(pc_,t_){this.$val=this;if(arguments.length===0){this.pc=0;this.t=BY.nil;return;}this.pc=pc_;this.t=t_;});S=$pkg.thread=$newType(0,$kindStruct,\"regexp.thread\",true,\"regexp\",false,function(inst_,cap_){this.$val=this;if(arguments.length===0){this.inst=BZ.nil;this.cap=BV.nil;return;}this.inst=inst_;this.cap=cap_;});T=$pkg.machine=$newType(0,$kindStruct,\"regexp.machine\",true,\"regexp\",false,function(re_,p_,q0_,q1_,pool_,matched_,matchcap_,inputs_){this.$val=this;if(arguments.length===0){this.re=CL.nil;this.p=CM.nil;this.q0=new Q.ptr(BT.nil,CP.nil);this.q1=new Q.ptr(BT.nil,CP.nil);this.pool=CQ.nil;this.matched=false;this.matchcap=BV.nil;this.inputs=new U.ptr(new BE.ptr(BX.nil),new BD.ptr(\"\"),new BF.ptr($ifaceNil,false,0));return;}this.re=re_;this.p=p_;this.q0=q0_;this.q1=q1_;this.pool=pool_;this.matched=matched_;this.matchcap=matchcap_;this.inputs=inputs_;});U=$pkg.inputs=$newType(0,$kindStruct,\"regexp.inputs\",true,\"regexp\",false,function(bytes_,string_,reader_){this.$val=this;if(arguments.length===0){this.bytes=new BE.ptr(BX.nil);this.string=new BD.ptr(\"\");this.reader=new BF.ptr($ifaceNil,false,0);return;}this.bytes=bytes_;this.string=string_;this.reader=reader_;});V=$pkg.lazyFlag=$newType(8,$kindUint64,\"regexp.lazyFlag\",true,\"regexp\",false,null);X=$pkg.onePassMachine=$newType(0,$kindStruct,\"regexp.onePassMachine\",true,\"regexp\",false,function(inputs_,matchcap_){this.$val=this;if(arguments.length===0){this.inputs=new U.ptr(new BE.ptr(BX.nil),new BD.ptr(\"\"),new BF.ptr($ifaceNil,false,0));this.matchcap=BV.nil;return;}this.inputs=inputs_;this.matchcap=matchcap_;});AC=$pkg.onePassProg=$newType(0,$kindStruct,\"regexp.onePassProg\",true,\"regexp\",false,function(Inst_,Start_,NumCap_){this.$val=this;if(arguments.length===0){this.Inst=CG.nil;this.Start=0;this.NumCap=0;return;}this.Inst=Inst_;this.Start=Start_;this.NumCap=NumCap_;});AD=$pkg.onePassInst=$newType(0,$kindStruct,\"regexp.onePassInst\",true,\"regexp\",false,function(Inst_,Next_){this.$val=this;if(arguments.length===0){this.Inst=new A.Inst.ptr(0,0,0,BS.nil);this.Next=BT.nil;return;}this.Inst=Inst_;this.Next=Next_;});AH=$pkg.queueOnePass=$newType(0,$kindStruct,\"regexp.queueOnePass\",true,\"regexp\",false,function(sparse_,dense_,size_,nextIndex_){this.$val=this;if(arguments.length===0){this.sparse=BT.nil;this.dense=BT.nil;this.size=0;this.nextIndex=0;return;}this.sparse=sparse_;this.dense=dense_;this.size=size_;this.nextIndex=nextIndex_;});AO=$pkg.runeSlice=$newType(12,$kindSlice,\"regexp.runeSlice\",true,\"regexp\",false,null);AT=$pkg.Regexp=$newType(0,$kindStruct,\"regexp.Regexp\",true,\"regexp\",true,function(expr_,prog_,onepass_,numSubexp_,maxBitStateLen_,subexpNames_,prefix_,prefixBytes_,prefixRune_,prefixEnd_,mpool_,matchcap_,prefixComplete_,cond_,longest_){this.$val=this;if(arguments.length===0){this.expr=\"\";this.prog=CM.nil;this.onepass=CD.nil;this.numSubexp=0;this.maxBitStateLen=0;this.subexpNames=CN.nil;this.prefix=\"\";this.prefixBytes=BX.nil;this.prefixRune=0;this.prefixEnd=0;this.mpool=0;this.matchcap=0;this.prefixComplete=false;this.cond=0;this.longest=false;return;}this.expr=expr_;this.prog=prog_;this.onepass=onepass_;this.numSubexp=numSubexp_;this.maxBitStateLen=maxBitStateLen_;this.subexpNames=subexpNames_;this.prefix=prefix_;this.prefixBytes=prefixBytes_;this.prefixRune=prefixRune_;this.prefixEnd=prefixEnd_;this.mpool=mpool_;this.matchcap=matchcap_;this.prefixComplete=prefixComplete_;this.cond=cond_;this.longest=longest_;});BC=$pkg.input=$newType(8,$kindInterface,\"regexp.input\",true,\"regexp\",false,null);BD=$pkg.inputString=$newType(0,$kindStruct,\"regexp.inputString\",true,\"regexp\",false,function(str_){this.$val=this;if(arguments.length===0){this.str=\"\";return;}this.str=str_;});BE=$pkg.inputBytes=$newType(0,$kindStruct,\"regexp.inputBytes\",true,\"regexp\",false,function(str_){this.$val=this;if(arguments.length===0){this.str=BX.nil;return;}this.str=str_;});BF=$pkg.inputReader=$newType(0,$kindStruct,\"regexp.inputReader\",true,\"regexp\",false,function(r_,atEOT_,pos_){this.$val=this;if(arguments.length===0){this.r=$ifaceNil;this.atEOT=false;this.pos=0;return;}this.r=r_;this.atEOT=atEOT_;this.pos=pos_;});BO=$sliceType($emptyInterface);BP=$arrayType($Int,0);BQ=$arrayType(B.Pool,5);BR=$arrayType($Uint8,16);BS=$sliceType($Int32);BT=$sliceType($Uint32);BU=$ptrType(K);BV=$sliceType($Int);BW=$sliceType(J);BX=$sliceType($Uint8);BY=$ptrType(S);BZ=$ptrType(A.Inst);CA=$ptrType(V);CB=$ptrType($Int);CC=$ptrType(X);CD=$ptrType(AC);CE=$ptrType(E.Builder);CF=$ptrType(AH);CG=$sliceType(AD);CH=$ptrType($Uint32);CI=$sliceType(BS);CJ=$ptrType(BS);CK=$sliceType($Bool);CL=$ptrType(AT);CM=$ptrType(A.Prog);CN=$sliceType($String);CO=$ptrType(T);CP=$sliceType(R);CQ=$sliceType(BY);CR=$arrayType($Int,2);CS=$arrayType($Int,4);CT=$sliceType(BX);CU=$sliceType(BV);CV=$sliceType(CT);CW=$sliceType(CN);CX=$ptrType(Q);CY=$ptrType(U);CZ=$funcType([$String],[$String],false);DA=$funcType([BX,BV],[BX],false);DB=$funcType([BX],[BX],false);DC=$funcType([BV],[],false);DD=$ptrType(BD);DE=$ptrType(BE);DF=$ptrType(BF);M=function(){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=L.Get();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}a=$assertType(b,BU,true);c=a[0];d=a[1];if(!d){c=new K.ptr(0,BV.nil,BV.nil,BW.nil,BT.nil,new U.ptr(new BE.ptr(BX.nil),new BD.ptr(\"\"),new BF.ptr($ifaceNil,false,0)));}$s=-1;return c;}return;}if($f===undefined){$f={$blk:M};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};N=function(a){var a;a.inputs.clear();L.Put(a);};O=function(a){var a,b;if(!P(a)){return 0;}return(b=262144/a.Inst.$length,(b===b&&b!==1/0&&b!==-1/0)?b>>0:$throwRuntimeError(\"integer divide by zero\"));};P=function(a){var a;return a.Inst.$length<=500;};K.ptr.prototype.reset=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;d=this;d.end=b;if(d.jobs.$capacity===0){d.jobs=$makeSlice(BW,0,256);}else{d.jobs=$subslice(d.jobs,0,0);}f=(e=(((($imul(a.Inst.$length,((b+1>>0))))+32>>0)-1>>0))/32,(e===e&&e!==1/0&&e!==-1/0)?e>>0:$throwRuntimeError(\"integer divide by zero\"));if(d.visited.$capacity<f){d.visited=$makeSlice(BT,f,8192);}else{d.visited=$subslice(d.visited,0,f);g=d.visited;h=0;while(true){if(!(h<g.$length)){break;}i=h;(j=d.visited,((i<0||i>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+i]=0));h++;}}if(d.cap.$capacity<c){d.cap=$makeSlice(BV,c);}else{d.cap=$subslice(d.cap,0,c);}k=d.cap;l=0;while(true){if(!(l<k.$length)){break;}m=l;(n=d.cap,((m<0||m>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+m]=-1));l++;}if(d.matchcap.$capacity<c){d.matchcap=$makeSlice(BV,c);}else{d.matchcap=$subslice(d.matchcap,0,c);}o=d.matchcap;p=0;while(true){if(!(p<o.$length)){break;}q=p;(r=d.matchcap,((q<0||q>=r.$length)?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+q]=-1));p++;}};K.prototype.reset=function(a,b,c){return this.$val.reset(a,b,c);};K.ptr.prototype.shouldVisit=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m;c=this;d=(((($imul(((a>>0)),((c.end+1>>0))))+b>>0)>>>0));if(!(((((e=c.visited,f=(g=d/32,(g===g&&g!==1/0&&g!==-1/0)?g>>>0:$throwRuntimeError(\"integer divide by zero\")),((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]))&(((h=(((d&31)>>>0)),h<32?(1<<h):0)>>>0)))>>>0)===0))){return false;}j=(i=d/32,(i===i&&i!==1/0&&i!==-1/0)?i>>>0:$throwRuntimeError(\"integer divide by zero\"));(m=c.visited,((j<0||j>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+j]=(((k=c.visited,((j<0||j>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+j]))|(((l=(((d&31)>>>0)),l<32?(1<<l):0)>>>0)))>>>0)));return true;};K.prototype.shouldVisit=function(a,b){return this.$val.shouldVisit(a,b);};K.ptr.prototype.push=function(a,b,c,d){var a,b,c,d,e,f;e=this;if(!(((f=a.prog.Inst,((b<0||b>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+b])).Op===5))&&(d||e.shouldVisit(b,c))){e.jobs=$append(e.jobs,new J.ptr(b,d,c));}};K.prototype.push=function(a,b,c,d){return this.$val.push(a,b,c,d);};AT.ptr.prototype.tryBacktrack=function(a,b,c,d){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=e.longest;a.push(e,c,d,false);case 1:if(!(a.jobs.$length>0)){$s=2;continue;}g=a.jobs.$length-1>>0;i=(h=a.jobs,((g<0||g>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+g])).pc;k=(j=a.jobs,((g<0||g>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+g])).pos;m=(l=a.jobs,((g<0||g>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+g])).arg;a.jobs=$subslice(a.jobs,0,g);$s=3;continue;case 4:if(!a.shouldVisit(i,k)){$s=1;continue;}case 3:o=$clone((n=e.prog.Inst,((i<0||i>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+i])),A.Inst);p=o.Op;if(p===(5)){$s=6;continue;}if(p===(0)){$s=7;continue;}if(p===(1)){$s=8;continue;}if(p===(7)){$s=9;continue;}if(p===(8)){$s=10;continue;}if(p===(10)){$s=11;continue;}if(p===(9)){$s=12;continue;}if(p===(2)){$s=13;continue;}if(p===(3)){$s=14;continue;}if(p===(6)){$s=15;continue;}if(p===(4)){$s=16;continue;}$s=17;continue;case 6:$panic(new $String(\"unexpected InstFail\"));$s=18;continue;case 7:if(m){$s=19;continue;}$s=20;continue;case 19:m=false;i=o.Arg;$s=4;continue;$s=21;continue;case 20:a.push(e,i,k,true);i=o.Out;$s=4;continue;case 21:$s=18;continue;case 8:s=(q=e.prog.Inst,r=o.Out,((r<0||r>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+r])).Op;if((s===(7))||(s===(8))||(s===(9))||(s===(10))){$s=23;continue;}$s=24;continue;case 23:a.push(e,o.Arg,k,false);i=o.Arg;k=a.end;$s=4;continue;case 24:case 22:a.push(e,o.Out,a.end,false);i=o.Out;$s=4;continue;$s=18;continue;case 9:u=b.step(k);$s=25;case 25:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}t=u;v=t[0];w=t[1];if(!o.MatchRune(v)){$s=26;continue;}$s=27;continue;case 26:$s=1;continue;case 27:k=k+(w)>>0;i=o.Out;$s=4;continue;$s=18;continue;case 10:y=b.step(k);$s=28;case 28:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;z=x[0];aa=x[1];if(!((z===(ab=o.Rune,(0>=ab.$length?($throwRuntimeError(\"index out of range\"),undefined):ab.$array[ab.$offset+0]))))){$s=29;continue;}$s=30;continue;case 29:$s=1;continue;case 30:k=k+(aa)>>0;i=o.Out;$s=4;continue;$s=18;continue;case 11:ad=b.step(k);$s=31;case 31:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ac=ad;ae=ac[0];af=ac[1];if((ae===10)||(ae===-1)){$s=32;continue;}$s=33;continue;case 32:$s=1;continue;case 33:k=k+(af)>>0;i=o.Out;$s=4;continue;$s=18;continue;case 12:ah=b.step(k);$s=34;case 34:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ag=ah;ai=ag[0];aj=ag[1];if(ai===-1){$s=35;continue;}$s=36;continue;case 35:$s=1;continue;case 36:k=k+(aj)>>0;i=o.Out;$s=4;continue;$s=18;continue;case 13:if(m){$s=37;continue;}$s=38;continue;case 37:(ak=a.cap,al=o.Arg,((al<0||al>=ak.$length)?($throwRuntimeError(\"index out of range\"),undefined):ak.$array[ak.$offset+al]=k));$s=1;continue;$s=39;continue;case 38:if(0<=o.Arg&&o.Arg<((a.cap.$length>>>0))){a.push(e,i,(am=a.cap,an=o.Arg,((an<0||an>=am.$length)?($throwRuntimeError(\"index out of range\"),undefined):am.$array[am.$offset+an])),true);(ao=a.cap,ap=o.Arg,((ap<0||ap>=ao.$length)?($throwRuntimeError(\"index out of range\"),undefined):ao.$array[ao.$offset+ap]=k));}i=o.Out;$s=4;continue;case 39:$s=18;continue;case 14:aq=b.context(k);$s=40;case 40:if($c){$c=false;aq=aq.$blk();}if(aq&&aq.$blk!==undefined){break s;}ar=aq;if(!ar.match(((o.Arg<<24>>>24)))){$s=41;continue;}$s=42;continue;case 41:$s=1;continue;case 42:i=o.Out;$s=4;continue;$s=18;continue;case 15:i=o.Out;$s=4;continue;$s=18;continue;case 16:if(a.cap.$length===0){$s=-1;return true;}if(a.cap.$length>1){(as=a.cap,(1>=as.$length?($throwRuntimeError(\"index out of range\"),undefined):as.$array[as.$offset+1]=k));}au=(at=a.matchcap,(1>=at.$length?($throwRuntimeError(\"index out of range\"),undefined):at.$array[at.$offset+1]));if((au===-1)||(f&&k>0&&k>au)){$copySlice(a.matchcap,a.cap);}if(!f){$s=-1;return true;}if(k===a.end){$s=-1;return true;}$s=1;continue;$s=18;continue;case 17:$panic(new $String(\"bad inst\"));case 18:case 5:$s=1;continue;case 2:$s=-1;return f&&a.matchcap.$length>1&&(av=a.matchcap,(1>=av.$length?($throwRuntimeError(\"index out of range\"),undefined):av.$array[av.$offset+1]))>=0;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.tryBacktrack};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.tryBacktrack=function(a,b,c,d){return this.$val.tryBacktrack(a,b,c,d);};AT.ptr.prototype.backtrack=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=this;g=f.cond;if(g===255){$s=-1;return BV.nil;}if(!((((g&4)>>>0)===0))&&!((c===0))){$s=-1;return BV.nil;}h=M();$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}i=h;j=i.inputs.init($ifaceNil,a,b);k=j[0];l=j[1];i.reset(f.prog,l,d);if(!((((g&4)>>>0)===0))){$s=2;continue;}$s=3;continue;case 2:if(i.cap.$length>0){(m=i.cap,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0]=c));}n=f.tryBacktrack(i,k,((f.prog.Start>>>0)),c);$s=7;case 7:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}if(!n){$s=5;continue;}$s=6;continue;case 5:N(i);$s=-1;return BV.nil;case 6:$s=4;continue;case 3:o=-1;case 8:if(!(c<=l&&!((o===0)))){$s=9;continue;}if(f.prefix.length>0){$s=10;continue;}$s=11;continue;case 10:p=k.index(f,c);$s=12;case 12:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p;if(q<0){N(i);$s=-1;return BV.nil;}c=c+(q)>>0;case 11:if(i.cap.$length>0){(r=i.cap,(0>=r.$length?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+0]=c));}s=f.tryBacktrack(i,k,((f.prog.Start>>>0)),c);$s=15;case 15:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}if(s){$s=13;continue;}$s=14;continue;case 13:$s=16;continue;case 14:u=k.step(c);$s=17;case 17:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}t=u;o=t[1];c=c+(o)>>0;$s=8;continue;case 9:N(i);$s=-1;return BV.nil;case 4:case 16:e=$appendSlice(e,i.matchcap);N(i);$s=-1;return e;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.backtrack};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.backtrack=function(a,b,c,d,e){return this.$val.backtrack(a,b,c,d,e);};U.ptr.prototype.newBytes=function(a){var a,b;b=this;b.bytes.str=a;return b.bytes;};U.prototype.newBytes=function(a){return this.$val.newBytes(a);};U.ptr.prototype.newString=function(a){var a,b;b=this;b.string.str=a;return b.string;};U.prototype.newString=function(a){return this.$val.newString(a);};U.ptr.prototype.newReader=function(a){var a,b;b=this;b.reader.r=a;b.reader.atEOT=false;b.reader.pos=0;return b.reader;};U.prototype.newReader=function(a){return this.$val.newReader(a);};U.ptr.prototype.clear=function(){var a;a=this;if(!(a.bytes.str===BX.nil)){a.bytes.str=BX.nil;}else if(!($interfaceIsEqual(a.reader.r,$ifaceNil))){a.reader.r=$ifaceNil;}else{a.string.str=\"\";}};U.prototype.clear=function(){return this.$val.clear();};U.ptr.prototype.init=function(a,b,c){var a,b,c,d;d=this;if(!($interfaceIsEqual(a,$ifaceNil))){return[d.newReader(a),0];}if(!(b===BX.nil)){return[d.newBytes(b),b.$length];}return[d.newString(c),c.length];};U.prototype.init=function(a,b,c){return this.$val.init(a,b,c);};T.ptr.prototype.init=function(a){var a,b,c,d,e;b=this;c=b.pool;d=0;while(true){if(!(d<c.$length)){break;}e=((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]);e.cap=$subslice(e.cap,0,a);d++;}b.matchcap=$subslice(b.matchcap,0,a);};T.prototype.init=function(a){return this.$val.init(a);};T.ptr.prototype.alloc=function(a){var a,b,c,d,e,f;b=this;c=BY.nil;d=b.pool.$length;if(d>0){c=(e=b.pool,f=d-1>>0,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));b.pool=$subslice(b.pool,0,(d-1>>0));}else{c=new S.ptr(BZ.nil,BV.nil);c.cap=$makeSlice(BV,b.matchcap.$length,b.matchcap.$capacity);}c.inst=a;return c;};T.prototype.alloc=function(a){return this.$val.alloc(a);};W=function(a,b){var a,b,c,d,e;return((c=(d=$shiftLeft64((new $Uint64(0,a)),32),e=(new $Uint64(0,((b>>>0)))),new $Uint64(d.$high|e.$high,(d.$low|e.$low)>>>0)),new V(c.$high,c.$low)));};V.prototype.match=function(a){var a,b,c,d;b=this;if(a===0){return true;}c=(($shiftRightUint64(b,32).$low>>0));if(!((((a&1)>>>0)===0))){if(!((c===10))&&c>=0){return false;}a=(a&~(1))<<24>>>24;}if(!((((a&4)>>>0)===0))){if(c>=0){return false;}a=(a&~(4))<<24>>>24;}if(a===0){return true;}d=((b.$low>>0));if(!((((a&2)>>>0)===0))){if(!((d===10))&&d>=0){return false;}a=(a&~(2))<<24>>>24;}if(!((((a&8)>>>0)===0))){if(d>=0){return false;}a=(a&~(8))<<24>>>24;}if(a===0){return true;}if(!(A.IsWordChar(c)===A.IsWordChar(d))){a=(a&~(16))<<24>>>24;}else{a=(a&~(32))<<24>>>24;}return a===0;};$ptrType(V).prototype.match=function(a){return this.$get().match(a);};T.ptr.prototype.match=function(a,b){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];d=this;e=d.re.cond;if(e===255){$s=-1;return false;}d.matched=false;f=d.matchcap;g=0;while(true){if(!(g<f.$length)){break;}h=g;(i=d.matchcap,((h<0||h>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+h]=-1));g++;}j=d.q0;k=d.q1;l=j;m=k;n=-1;o=-1;p=n;q=o;r=0;s=0;t=r;u=s;w=a.step(b);$s=1;case 1:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}v=w;p=v[0];t=v[1];if(!((p===-1))){$s=2;continue;}$s=3;continue;case 2:y=a.step(b+t>>0);$s=4;case 4:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;q=x[0];u=x[1];case 3:c[0]=new V(0,0);if(b===0){$s=5;continue;}$s=6;continue;case 5:c[0]=W(-1,p);$s=7;continue;case 6:z=a.context(b);$s=8;case 8:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}c[0]=z;case 7:case 9:if(l.dense.$length===0){$s=11;continue;}$s=12;continue;case 11:if(!((((e&4)>>>0)===0))&&!((b===0))){$s=10;continue;}if(d.matched){$s=10;continue;}if(!(d.re.prefix.length>0&&!((q===d.re.prefixRune)))){aa=false;$s=15;continue s;}ab=a.canCheckPrefix();$s=16;case 16:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=ab;case 15:if(aa){$s=13;continue;}$s=14;continue;case 13:ac=a.index(d.re,b);$s=17;case 17:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}ad=ac;if(ad<0){$s=10;continue;}b=b+(ad)>>0;af=a.step(b);$s=18;case 18:if($c){$c=false;af=af.$blk();}if(af&&af.$blk!==undefined){break s;}ae=af;p=ae[0];t=ae[1];ah=a.step(b+t>>0);$s=19;case 19:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ag=ah;q=ag[0];u=ag[1];case 14:case 12:if(!d.matched){if(d.matchcap.$length>0){(ai=d.matchcap,(0>=ai.$length?($throwRuntimeError(\"index out of range\"),undefined):ai.$array[ai.$offset+0]=b));}d.add(l,((d.p.Start>>>0)),b,d.matchcap,(c.$ptr||(c.$ptr=new CA(function(){return this.$target[0];},function($v){this.$target[0]=$v;},c))),BY.nil);}c[0]=W(p,q);d.step(l,m,b,b+t>>0,p,(c.$ptr||(c.$ptr=new CA(function(){return this.$target[0];},function($v){this.$target[0]=$v;},c))));if(t===0){$s=10;continue;}if((d.matchcap.$length===0)&&d.matched){$s=10;continue;}b=b+(t)>>0;aj=q;ak=u;p=aj;t=ak;if(!((p===-1))){$s=20;continue;}$s=21;continue;case 20:am=a.step(b+t>>0);$s=22;case 22:if($c){$c=false;am=am.$blk();}if(am&&am.$blk!==undefined){break s;}al=am;q=al[0];u=al[1];case 21:an=m;ao=l;l=an;m=ao;$s=9;continue;case 10:d.clear(m);$s=-1;return d.matched;}return;}if($f===undefined){$f={$blk:T.ptr.prototype.match};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};T.prototype.match=function(a,b){return this.$val.match(a,b);};T.ptr.prototype.clear=function(a){var a,b,c,d,e;b=this;c=a.dense;d=0;while(true){if(!(d<c.$length)){break;}e=$clone(((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]),R);if(!(e.t===BY.nil)){b.pool=$append(b.pool,e.t);}d++;}a.dense=$subslice(a.dense,0,0);};T.prototype.clear=function(a){return this.$val.clear(a);};T.ptr.prototype.step=function(a,b,c,d,e,f){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;g=this;h=g.re.longest;i=0;while(true){if(!(i<a.dense.$length)){break;}k=(j=a.dense,((i<0||i>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+i]));l=k.t;if(l===BY.nil){i=i+(1)>>0;continue;}if(h&&g.matched&&l.cap.$length>0&&(m=g.matchcap,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0]))<(n=l.cap,(0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0]))){g.pool=$append(g.pool,l);i=i+(1)>>0;continue;}o=l.inst;p=false;q=o.Op;if(q===(4)){if(l.cap.$length>0&&(!h||!g.matched||(r=g.matchcap,(1>=r.$length?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+1]))<c)){(s=l.cap,(1>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+1]=c));$copySlice(g.matchcap,l.cap);}if(!h){t=$subslice(a.dense,(i+1>>0));u=0;while(true){if(!(u<t.$length)){break;}v=$clone(((u<0||u>=t.$length)?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+u]),R);if(!(v.t===BY.nil)){g.pool=$append(g.pool,v.t);}u++;}a.dense=$subslice(a.dense,0,0);}g.matched=true;}else if(q===(7)){p=o.MatchRune(e);}else if(q===(8)){p=e===(w=o.Rune,(0>=w.$length?($throwRuntimeError(\"index out of range\"),undefined):w.$array[w.$offset+0]));}else if(q===(9)){p=true;}else if(q===(10)){p=!((e===10));}else{$panic(new $String(\"bad inst\"));}if(p){l=g.add(b,o.Out,d,l.cap,f,l);}if(!(l===BY.nil)){g.pool=$append(g.pool,l);}i=i+(1)>>0;}a.dense=$subslice(a.dense,0,0);};T.prototype.step=function(a,b,c,d,e,f){return this.$val.step(a,b,c,d,e,f);};T.ptr.prototype.add=function(a,b,c,d,e,f){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,$s;$s=0;s:while(true){switch($s){case 0:g=this;case 1:if(b===0){$s=-1;return f;}i=(h=a.sparse,((b<0||b>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+b]));if(i<((a.dense.$length>>>0))&&((j=a.dense,((i<0||i>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+i])).pc===b)){$s=-1;return f;}k=a.dense.$length;a.dense=$subslice(a.dense,0,(k+1>>0));m=(l=a.dense,((k<0||k>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+k]));m.t=BY.nil;m.pc=b;(n=a.sparse,((b<0||b>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+b]=((k>>>0))));p=(o=g.p.Inst,((b<0||b>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+b]));q=p.Op;if(q===(5)){$s=3;continue;}if((q===(0))||(q===(1))){$s=4;continue;}if(q===(3)){$s=5;continue;}if(q===(6)){$s=6;continue;}if(q===(2)){$s=7;continue;}if((q===(4))||(q===(7))||(q===(8))||(q===(9))||(q===(10))){$s=8;continue;}$s=9;continue;case 3:$s=10;continue;case 4:f=g.add(a,p.Out,c,d,e,f);b=p.Arg;$s=1;continue;$s=10;continue;case 5:if(e.match(((p.Arg<<24>>>24)))){$s=11;continue;}$s=12;continue;case 11:b=p.Out;$s=1;continue;case 12:$s=10;continue;case 6:b=p.Out;$s=1;continue;$s=10;continue;case 7:if(((p.Arg>>0))<d.$length){$s=13;continue;}$s=14;continue;case 13:s=(r=p.Arg,((r<0||r>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+r]));(t=p.Arg,((t<0||t>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+t]=c));g.add(a,p.Out,c,d,e,BY.nil);(u=p.Arg,((u<0||u>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+u]=s));$s=15;continue;case 14:b=p.Out;$s=1;continue;case 15:$s=10;continue;case 8:if(f===BY.nil){f=g.alloc(p);}else{f.inst=p;}if(d.$length>0&&!((v=f.cap,$indexPtr(v.$array,v.$offset+0,CB))===$indexPtr(d.$array,d.$offset+0,CB))){$copySlice(f.cap,d);}m.t=f;f=BY.nil;$s=10;continue;case 9:$panic(new $String(\"unhandled\"));case 10:case 2:$s=-1;return f;}return;}};T.prototype.add=function(a,b,c,d,e,f){return this.$val.add(a,b,c,d,e,f);};Z=function(){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=Y.Get();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}a=$assertType(b,CC,true);c=a[0];d=a[1];if(!d){c=new X.ptr(new U.ptr(new BE.ptr(BX.nil),new BD.ptr(\"\"),new BF.ptr($ifaceNil,false,0)),BV.nil);}$s=-1;return c;}return;}if($f===undefined){$f={$blk:Z};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AA=function(a){var a;a.inputs.clear();Y.Put(a);};AT.ptr.prototype.doOnePass=function(a,b,c,d,e,f){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,b,ba,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;b=$f.b;ba=$f.ba;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:g=[g];h=this;i=h.cond;if(i===255){$s=-1;return BV.nil;}j=Z();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;if(k.matchcap.$capacity<e){k.matchcap=$makeSlice(BV,e);}else{k.matchcap=$subslice(k.matchcap,0,e);}l=false;m=k.matchcap;n=0;while(true){if(!(n<m.$length)){break;}o=n;(p=k.matchcap,((o<0||o>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+o]=-1));n++;}q=k.inputs.init(a,b,c);r=q[0];s=-1;t=-1;u=s;v=t;w=0;x=0;y=w;z=x;ab=r.step(d);$s=2;case 2:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=ab;u=aa[0];y=aa[1];if(!((u===-1))){$s=3;continue;}$s=4;continue;case 3:ad=r.step(d+y>>0);$s=5;case 5:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ac=ad;v=ac[0];z=ac[1];case 4:ae=new V(0,0);if(d===0){$s=6;continue;}$s=7;continue;case 6:ae=W(-1,u);$s=8;continue;case 7:af=r.context(d);$s=9;case 9:if($c){$c=false;af=af.$blk();}if(af&&af.$blk!==undefined){break s;}ae=af;case 8:ag=h.onepass.Start;g[0]=$clone((ah=h.onepass.Inst,((ag<0||ag>=ah.$length)?($throwRuntimeError(\"index out of range\"),undefined):ah.$array[ah.$offset+ag])),AD);if(!((d===0)&&ae.match(((g[0].Inst.Arg<<24>>>24)))&&h.prefix.length>0)){ai=false;$s=12;continue s;}aj=r.canCheckPrefix();$s=13;case 13:if($c){$c=false;aj=aj.$blk();}if(aj&&aj.$blk!==undefined){break s;}ai=aj;case 12:if(ai){$s=10;continue;}$s=11;continue;case 10:ak=r.hasPrefix(h);$s=16;case 16:if($c){$c=false;ak=ak.$blk();}if(ak&&ak.$blk!==undefined){break s;}if(!ak){$s=14;continue;}$s=15;continue;case 14:$s=17;continue;case 15:d=d+(h.prefix.length)>>0;am=r.step(d);$s=18;case 18:if($c){$c=false;am=am.$blk();}if(am&&am.$blk!==undefined){break s;}al=am;u=al[0];y=al[1];ao=r.step(d+y>>0);$s=19;case 19:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}an=ao;v=an[0];z=an[1];ap=r.context(d);$s=20;case 20:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}ae=ap;ag=((h.prefixEnd>>0));case 11:case 21:AD.copy(g[0],(aq=h.onepass.Inst,((ag<0||ag>=aq.$length)?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+ag])));ag=((g[0].Inst.Out>>0));ar=g[0].Inst.Op;if(ar===(4)){$s=24;continue;}if(ar===(7)){$s=25;continue;}if(ar===(8)){$s=26;continue;}if(ar===(9)){$s=27;continue;}if(ar===(10)){$s=28;continue;}if((ar===(0))||(ar===(1))){$s=29;continue;}if(ar===(5)){$s=30;continue;}if(ar===(6)){$s=31;continue;}if(ar===(3)){$s=32;continue;}if(ar===(2)){$s=33;continue;}$s=34;continue;case 24:l=true;if(k.matchcap.$length>0){(as=k.matchcap,(0>=as.$length?($throwRuntimeError(\"index out of range\"),undefined):as.$array[as.$offset+0]=0));(at=k.matchcap,(1>=at.$length?($throwRuntimeError(\"index out of range\"),undefined):at.$array[at.$offset+1]=d));}$s=17;continue;$s=35;continue;case 25:if(!g[0].Inst.MatchRune(u)){$s=36;continue;}$s=37;continue;case 36:$s=17;continue;case 37:$s=35;continue;case 26:if(!((u===(au=g[0].Inst.Rune,(0>=au.$length?($throwRuntimeError(\"index out of range\"),undefined):au.$array[au.$offset+0]))))){$s=38;continue;}$s=39;continue;case 38:$s=17;continue;case 39:$s=35;continue;case 27:$s=35;continue;case 28:if(u===10){$s=40;continue;}$s=41;continue;case 40:$s=17;continue;case 41:$s=35;continue;case 29:ag=((AF(g[0],u)>>0));$s=21;continue;$s=35;continue;case 30:$s=17;continue;$s=35;continue;case 31:$s=21;continue;$s=35;continue;case 32:if(!ae.match(((g[0].Inst.Arg<<24>>>24)))){$s=42;continue;}$s=43;continue;case 42:$s=17;continue;case 43:$s=21;continue;$s=35;continue;case 33:if(((g[0].Inst.Arg>>0))<k.matchcap.$length){(av=k.matchcap,aw=g[0].Inst.Arg,((aw<0||aw>=av.$length)?($throwRuntimeError(\"index out of range\"),undefined):av.$array[av.$offset+aw]=d));}$s=21;continue;$s=35;continue;case 34:$panic(new $String(\"bad inst\"));case 35:case 23:if(y===0){$s=22;continue;}ae=W(u,v);d=d+(y)>>0;ax=v;ay=z;u=ax;y=ay;if(!((u===-1))){$s=44;continue;}$s=45;continue;case 44:ba=r.step(d+y>>0);$s=46;case 46:if($c){$c=false;ba=ba.$blk();}if(ba&&ba.$blk!==undefined){break s;}az=ba;v=az[0];z=az[1];case 45:$s=21;continue;case 22:case 17:if(!l){AA(k);$s=-1;return BV.nil;}f=$appendSlice(f,k.matchcap);AA(k);$s=-1;return f;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.doOnePass};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.b=b;$f.ba=ba;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.doOnePass=function(a,b,c,d,e,f){return this.$val.doOnePass(a,b,c,d,e,f);};AT.ptr.prototype.doMatch=function(a,b,c){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.doExecute(a,b,c,0,0,BV.nil);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return!(e===BV.nil);}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.doMatch};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.doMatch=function(a,b,c){return this.$val.doMatch(a,b,c);};AT.ptr.prototype.doExecute=function(a,b,c,d,e,f){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:g=this;if(f===BV.nil){f=$subslice(new BV(AB),0,0,0);}if(!(g.onepass===CD.nil)){$s=1;continue;}$s=2;continue;case 1:h=g.doOnePass(a,b,c,d,e,f);$s=3;case 3:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}$s=-1;return h;case 2:if($interfaceIsEqual(a,$ifaceNil)&&(b.$length+c.length>>0)<g.maxBitStateLen){$s=4;continue;}$s=5;continue;case 4:i=g.backtrack(b,c,d,e,f);$s=6;case 6:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}$s=-1;return i;case 5:j=g.get();$s=7;case 7:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;l=k.inputs.init(a,b,c);m=l[0];k.init(e);n=k.match(m,d);$s=10;case 10:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}if(!n){$s=8;continue;}$s=9;continue;case 8:g.put(k);$s=-1;return BV.nil;case 9:f=$appendSlice(f,k.matchcap);g.put(k);$s=-1;return f;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.doExecute};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.doExecute=function(a,b,c,d,e,f){return this.$val.doExecute(a,b,c,d,e,f);};AE=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=\"\";c=false;d=0;g=(e=a.Inst,f=a.Start,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f]));if(!((g.Op===3))||((((((g.Arg<<24>>>24)))&4)>>>0)===0)){h=\"\";i=g.Op===4;j=((a.Start>>>0));b=h;c=i;d=j;return[b,c,d];}d=g.Out;g=(k=a.Inst,((d<0||d>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+d]));while(true){if(!(g.Op===6)){break;}d=g.Out;g=(l=a.Inst,((d<0||d>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+d]));}if(!((AG(g)===7))||!((g.Rune.$length===1))){m=\"\";n=g.Op===4;o=((a.Start>>>0));b=m;c=n;d=o;return[b,c,d];}p=new E.Builder.ptr(CE.nil,BX.nil);while(true){if(!((AG(g)===7)&&(g.Rune.$length===1)&&(((((g.Arg<<16>>>16))&1)>>>0)===0))){break;}p.WriteRune((q=g.Rune,(0>=q.$length?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+0])));r=g.Out;s=(t=a.Inst,u=g.Out,((u<0||u>=t.$length)?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+u]));d=r;g=s;}if((g.Op===3)&&!((((((g.Arg<<24>>>24))&8)>>>0)===0))&&((v=a.Inst,w=g.Out,((w<0||w>=v.$length)?($throwRuntimeError(\"index out of range\"),undefined):v.$array[v.$offset+w])).Op===4)){c=true;}x=p.String();y=c;z=d;b=x;c=y;d=z;return[b,c,d];};AF=function(a,b){var a,b,c,d;c=a.Inst.MatchRunePos(b);if(c>=0){return(d=a.Next,((c<0||c>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+c]));}if(a.Inst.Op===1){return a.Inst.Out;}return 0;};AG=function(a){var a,b,c;b=a.Op;c=b;if((c===(8))||(c===(9))||(c===(10))){b=7;}return b;};AH.ptr.prototype.empty=function(){var a;a=this;return a.nextIndex>=a.size;};AH.prototype.empty=function(){return this.$val.empty();};AH.ptr.prototype.next=function(){var a,b,c,d;a=0;b=this;a=(c=b.dense,d=b.nextIndex,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]));b.nextIndex=b.nextIndex+(1)>>>0;return a;};AH.prototype.next=function(){return this.$val.next();};AH.ptr.prototype.clear=function(){var a;a=this;a.size=0;a.nextIndex=0;};AH.prototype.clear=function(){return this.$val.clear();};AH.ptr.prototype.contains=function(a){var a,b,c,d,e,f;b=this;if(a>=((b.sparse.$length>>>0))){return false;}return(c=b.sparse,((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]))<b.size&&((d=b.dense,e=(f=b.sparse,((a<0||a>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+a])),((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]))===a);};AH.prototype.contains=function(a){return this.$val.contains(a);};AH.ptr.prototype.insert=function(a){var a,b;b=this;if(!b.contains(a)){b.insertNew(a);}};AH.prototype.insert=function(a){return this.$val.insert(a);};AH.ptr.prototype.insertNew=function(a){var a,b,c,d,e;b=this;if(a>=((b.sparse.$length>>>0))){return;}(c=b.sparse,((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]=b.size));(d=b.dense,e=b.size,((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]=a));b.size=b.size+(1)>>>0;};AH.prototype.insertNew=function(a){return this.$val.insertNew(a);};AI=function(a){var a,b;b=CF.nil;b=new AH.ptr($makeSlice(BT,a),$makeSlice(BT,a),0,0);return b;};AL=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);e=[e];f=[f];g=[g];h=[h];i=[i];j=[j];k=a.$get().$length;l=b.$get().$length;if(!(((k&1)===0))||!(((l&1)===0))){$panic(new $String(\"mergeRuneSets odd length []rune\"));}m=0;n=0;f[0]=m;j[0]=n;g[0]=$makeSlice(BS,0);h[0]=$makeSlice(BT,0);i[0]=true;$deferred.push([(function(e,f,g,h,i,j){return function(){if(!i[0]){g[0]=BS.nil;h[0]=BT.nil;}};})(e,f,g,h,i,j),[]]);e[0]=-1;o=(function(e,f,g,h,i,j){return function(o,p,q){var o,p,q,r,s,t,u,v,w;if(e[0]>0&&(r=p.$get(),s=o.$get(),((s<0||s>=r.$length)?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+s]))<=((e[0]<0||e[0]>=g[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):g[0].$array[g[0].$offset+e[0]])){return false;}g[0]=$append(g[0],(t=p.$get(),u=o.$get(),((u<0||u>=t.$length)?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+u])),(v=p.$get(),w=o.$get()+1>>0,((w<0||w>=v.$length)?($throwRuntimeError(\"index out of range\"),undefined):v.$array[v.$offset+w])));o.$set(o.$get()+(2)>>0);e[0]=e[0]+(2)>>0;h[0]=$append(h[0],q);return true;};})(e,f,g,h,i,j);case 1:if(!(f[0]<k||j[0]<l)){$s=2;continue;}if(j[0]>=l){$s=4;continue;}if(f[0]>=k){$s=5;continue;}if((p=b.$get(),((j[0]<0||j[0]>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+j[0]]))<(q=a.$get(),((f[0]<0||f[0]>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+f[0]]))){$s=6;continue;}$s=7;continue;case 4:r=o((f.$ptr||(f.$ptr=new CB(function(){return this.$target[0];},function($v){this.$target[0]=$v;},f))),a,c);$s=9;case 9:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}i[0]=r;$s=8;continue;case 5:s=o((j.$ptr||(j.$ptr=new CB(function(){return this.$target[0];},function($v){this.$target[0]=$v;},j))),b,d);$s=10;case 10:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}i[0]=s;$s=8;continue;case 6:t=o((j.$ptr||(j.$ptr=new CB(function(){return this.$target[0];},function($v){this.$target[0]=$v;},j))),b,d);$s=11;case 11:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}i[0]=t;$s=8;continue;case 7:u=o((f.$ptr||(f.$ptr=new CB(function(){return this.$target[0];},function($v){this.$target[0]=$v;},f))),a,c);$s=12;case 12:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}i[0]=u;case 8:case 3:if(!i[0]){$s=-1;return[AJ,AK];}$s=1;continue;case 2:$s=-1;return[g[0],h[0]];}return;}}catch(err){$err=err;$s=-1;return[BS.nil,BT.nil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AL};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AM=function(a,b){var a,b,c,d,e,f,g,h,i,j;c=b.Inst;d=0;while(true){if(!(d<c.$length)){break;}e=d;f=$clone(((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]),A.Inst);g=f.Op;if((g===(0))||(g===(1))||(g===(7))){}else if((g===(2))||(g===(3))||(g===(6))||(g===(4))||(g===(5))){(h=a.Inst,((e<0||e>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+e])).Next=BT.nil;}else if((g===(8))||(g===(9))||(g===(10))){(i=a.Inst,((e<0||e>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+e])).Next=BT.nil;AD.copy((j=a.Inst,((e<0||e>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+e])),new AD.ptr($clone(f,A.Inst),BT.nil));}d++;}};AN=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;b=new AC.ptr($makeSlice(CG,a.Inst.$length),a.Start,a.NumCap);c=a.Inst;d=0;while(true){if(!(d<c.$length)){break;}e=d;f=$clone(((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]),A.Inst);AD.copy((g=b.Inst,((e<0||e>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+e])),new AD.ptr($clone(f,A.Inst),BT.nil));d++;}h=b.Inst;i=0;while(true){if(!(i<h.$length)){break;}j=i;l=(k=b.Inst,((j<0||j>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+j])).Inst.Op;if((l===(0))||(l===(1))){o=(m=(n=b.Inst,((j<0||j>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+j])),(m.$ptr_Out||(m.$ptr_Out=new CH(function(){return this.$target.Inst.Out;},function($v){this.$target.Inst.Out=$v;},m))));r=(p=(q=b.Inst,((j<0||j>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+j])),(p.$ptr_Arg||(p.$ptr_Arg=new CH(function(){return this.$target.Inst.Arg;},function($v){this.$target.Inst.Arg=$v;},p))));u=$clone((s=b.Inst,t=r.$get(),((t<0||t>=s.$length)?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+t])),AD);if(!((u.Inst.Op===0)||(u.Inst.Op===1))){v=o;w=r;r=v;o=w;AD.copy(u,(x=b.Inst,y=r.$get(),((y<0||y>=x.$length)?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+y])));if(!((u.Inst.Op===0)||(u.Inst.Op===1))){i++;continue;}}ab=$clone((z=b.Inst,aa=o.$get(),((aa<0||aa>=z.$length)?($throwRuntimeError(\"index out of range\"),undefined):z.$array[z.$offset+aa])),AD);if((ab.Inst.Op===0)||(ab.Inst.Op===1)){i++;continue;}af=(ac=(ad=b.Inst,ae=r.$get(),((ae<0||ae>=ad.$length)?($throwRuntimeError(\"index out of range\"),undefined):ad.$array[ad.$offset+ae])),(ac.$ptr_Out||(ac.$ptr_Out=new CH(function(){return this.$target.Inst.Out;},function($v){this.$target.Inst.Out=$v;},ac))));aj=(ag=(ah=b.Inst,ai=r.$get(),((ai<0||ai>=ah.$length)?($throwRuntimeError(\"index out of range\"),undefined):ah.$array[ah.$offset+ai])),(ag.$ptr_Arg||(ag.$ptr_Arg=new CH(function(){return this.$target.Inst.Arg;},function($v){this.$target.Inst.Arg=$v;},ag))));ak=false;if(u.Inst.Out===((j>>>0))){ak=true;}else if(u.Inst.Arg===((j>>>0))){ak=true;al=aj;am=af;af=al;aj=am;}if(ak){af.$set(o.$get());}if(o.$get()===af.$get()){r.$set(aj.$get());}}else{i++;continue;}i++;}return b;};AO.prototype.Len=function(){var a;a=this;return a.$length;};$ptrType(AO).prototype.Len=function(){return this.$get().Len();};AO.prototype.Less=function(a,b){var a,b,c;c=this;return((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a])<((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]);};$ptrType(AO).prototype.Less=function(a,b){return this.$get().Less(a,b);};AO.prototype.Swap=function(a,b){var a,b,c,d,e;c=this;d=((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]);e=((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]);((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]=d);((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]=e);};$ptrType(AO).prototype.Swap=function(a,b){return this.$get().Swap(a,b);};AR=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];c=[c];d=[d];e=[e];if(a[0].Inst.$length>=1000){$s=-1;return CD.nil;}c[0]=AI(a[0].Inst.$length);e[0]=AI(a[0].Inst.$length);b[0]=$throwNilPointerError;d[0]=$makeSlice(CI,a[0].Inst.$length);b[0]=(function(a,b,c,d,e){return function $b(f,g){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,az,ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;az=$f.az;ba=$f.ba;bb=$f.bb;bc=$f.bc;bd=$f.bd;be=$f.be;bf=$f.bf;bg=$f.bg;bh=$f.bh;bi=$f.bi;bj=$f.bj;bk=$f.bk;bl=$f.bl;bm=$f.bm;bn=$f.bn;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:h=false;h=true;j=(i=a[0].Inst,((f<0||f>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+f]));if(e[0].contains(f)){$s=-1;return h;}e[0].insert(f);k=j.Inst.Op;if((k===(0))||(k===(1))){$s=2;continue;}if((k===(2))||(k===(6))){$s=3;continue;}if(k===(3)){$s=4;continue;}if((k===(4))||(k===(5))){$s=5;continue;}if(k===(7)){$s=6;continue;}if(k===(8)){$s=7;continue;}if(k===(9)){$s=8;continue;}if(k===(10)){$s=9;continue;}$s=10;continue;case 2:m=b[0](j.Inst.Out,g);$s=12;case 12:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}if(!(m)){l=false;$s=11;continue s;}n=b[0](j.Inst.Arg,g);$s=13;case 13:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}l=n;case 11:h=l;p=(o=j.Inst.Out,((o<0||o>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+o]));r=(q=j.Inst.Arg,((q<0||q>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+q]));if(p&&r){h=false;$s=1;continue;}if(r){s=j.Inst.Arg;t=j.Inst.Out;j.Inst.Out=s;j.Inst.Arg=t;u=r;v=p;p=u;r=v;}if(p){((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=true);j.Inst.Op=1;}x=AL($indexPtr(d[0].$array,d[0].$offset+j.Inst.Out,CJ),$indexPtr(d[0].$array,d[0].$offset+j.Inst.Arg,CJ),j.Inst.Out,j.Inst.Arg);$s=14;case 14:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}w=x;((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=w[0]);j.Next=w[1];if(j.Next.$length>0&&((y=j.Next,(0>=y.$length?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+0]))===4294967295)){h=false;$s=1;continue;}$s=10;continue;case 3:z=b[0](j.Inst.Out,g);$s=15;case 15:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}h=z;((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=(aa=j.Inst.Out,((aa<0||aa>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+aa])));((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=$appendSlice(new BS([]),(ab=j.Inst.Out,((ab<0||ab>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+ab]))));j.Next=$makeSlice(BT,((ac=((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]).$length/2,(ac===ac&&ac!==1/0&&ac!==-1/0)?ac>>0:$throwRuntimeError(\"integer divide by zero\"))+1>>0));ad=j.Next;ae=0;while(true){if(!(ae<ad.$length)){break;}af=ae;(ag=j.Next,((af<0||af>=ag.$length)?($throwRuntimeError(\"index out of range\"),undefined):ag.$array[ag.$offset+af]=j.Inst.Out));ae++;}$s=10;continue;case 4:ah=b[0](j.Inst.Out,g);$s=16;case 16:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}h=ah;((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=(ai=j.Inst.Out,((ai<0||ai>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+ai])));((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=$appendSlice(new BS([]),(aj=j.Inst.Out,((aj<0||aj>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+aj]))));j.Next=$makeSlice(BT,((ak=((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]).$length/2,(ak===ak&&ak!==1/0&&ak!==-1/0)?ak>>0:$throwRuntimeError(\"integer divide by zero\"))+1>>0));al=j.Next;am=0;while(true){if(!(am<al.$length)){break;}an=am;(ao=j.Next,((an<0||an>=ao.$length)?($throwRuntimeError(\"index out of range\"),undefined):ao.$array[ao.$offset+an]=j.Inst.Out));am++;}$s=10;continue;case 5:((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=(j.Inst.Op===4));$s=10;continue;case 6:((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=false);if(j.Next.$length>0){$s=1;continue;}c[0].insert(j.Inst.Out);if(j.Inst.Rune.$length===0){((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=new BS([]));j.Next=new BT([j.Inst.Out]);$s=1;continue;}ap=$makeSlice(BS,0);if((j.Inst.Rune.$length===1)&&!((((((j.Inst.Arg<<16>>>16))&1)>>>0)===0))){$s=17;continue;}$s=18;continue;case 17:ar=(aq=j.Inst.Rune,(0>=aq.$length?($throwRuntimeError(\"index out of range\"),undefined):aq.$array[aq.$offset+0]));ap=$append(ap,ar,ar);as=F.SimpleFold(ar);while(true){if(!(!((as===ar)))){break;}ap=$append(ap,as,as);as=F.SimpleFold(as);}$r=D.Sort(($subslice(new AO(ap.$array),ap.$offset,ap.$offset+ap.$length)));$s=20;case 20:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=19;continue;case 18:ap=$appendSlice(ap,j.Inst.Rune);case 19:((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=ap);j.Next=$makeSlice(BT,((at=((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]).$length/2,(at===at&&at!==1/0&&at!==-1/0)?at>>0:$throwRuntimeError(\"integer divide by zero\"))+1>>0));au=j.Next;av=0;while(true){if(!(av<au.$length)){break;}aw=av;(ax=j.Next,((aw<0||aw>=ax.$length)?($throwRuntimeError(\"index out of range\"),undefined):ax.$array[ax.$offset+aw]=j.Inst.Out));av++;}j.Inst.Op=7;$s=10;continue;case 7:((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=false);if(j.Next.$length>0){$s=1;continue;}c[0].insert(j.Inst.Out);ay=new BS([]);if(!((((((j.Inst.Arg<<16>>>16))&1)>>>0)===0))){$s=21;continue;}$s=22;continue;case 21:ba=(az=j.Inst.Rune,(0>=az.$length?($throwRuntimeError(\"index out of range\"),undefined):az.$array[az.$offset+0]));ay=$append(ay,ba,ba);bb=F.SimpleFold(ba);while(true){if(!(!((bb===ba)))){break;}ay=$append(ay,bb,bb);bb=F.SimpleFold(bb);}$r=D.Sort(($subslice(new AO(ay.$array),ay.$offset,ay.$offset+ay.$length)));$s=24;case 24:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=23;continue;case 22:ay=$append(ay,(bc=j.Inst.Rune,(0>=bc.$length?($throwRuntimeError(\"index out of range\"),undefined):bc.$array[bc.$offset+0])),(bd=j.Inst.Rune,(0>=bd.$length?($throwRuntimeError(\"index out of range\"),undefined):bd.$array[bd.$offset+0])));case 23:((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=ay);j.Next=$makeSlice(BT,((be=((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]).$length/2,(be===be&&be!==1/0&&be!==-1/0)?be>>0:$throwRuntimeError(\"integer divide by zero\"))+1>>0));bf=j.Next;bg=0;while(true){if(!(bg<bf.$length)){break;}bh=bg;(bi=j.Next,((bh<0||bh>=bi.$length)?($throwRuntimeError(\"index out of range\"),undefined):bi.$array[bi.$offset+bh]=j.Inst.Out));bg++;}j.Inst.Op=7;$s=10;continue;case 8:((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=false);if(j.Next.$length>0){$s=1;continue;}c[0].insert(j.Inst.Out);((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=$appendSlice(new BS([]),AQ));j.Next=new BT([j.Inst.Out]);$s=10;continue;case 9:((f<0||f>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+f]=false);if(j.Next.$length>0){$s=1;continue;}c[0].insert(j.Inst.Out);((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]=$appendSlice(new BS([]),AP));j.Next=$makeSlice(BT,((bj=((f<0||f>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+f]).$length/2,(bj===bj&&bj!==1/0&&bj!==-1/0)?bj>>0:$throwRuntimeError(\"integer divide by zero\"))+1>>0));bk=j.Next;bl=0;while(true){if(!(bl<bk.$length)){break;}bm=bl;(bn=j.Next,((bm<0||bm>=bn.$length)?($throwRuntimeError(\"index out of range\"),undefined):bn.$array[bn.$offset+bm]=j.Inst.Out));bl++;}case 10:case 1:$s=-1;return h;}return;}if($f===undefined){$f={$blk:$b};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.az=az;$f.ba=ba;$f.bb=bb;$f.bc=bc;$f.bd=bd;$f.be=be;$f.bf=bf;$f.bg=bg;$f.bh=bh;$f.bi=bi;$f.bj=bj;$f.bk=bk;$f.bl=bl;$f.bm=bm;$f.bn=bn;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};})(a,b,c,d,e);c[0].clear();c[0].insert(((a[0].Start>>>0)));f=$makeSlice(CK,a[0].Inst.$length);case 1:if(!(!c[0].empty())){$s=2;continue;}e[0].clear();g=c[0].next();h=b[0](g,f);$s=5;case 5:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if(!h){$s=3;continue;}$s=4;continue;case 3:a[0]=CD.nil;$s=2;continue;case 4:$s=1;continue;case 2:if(!(a[0]===CD.nil)){i=a[0].Inst;j=0;while(true){if(!(j<i.$length)){break;}k=j;(l=a[0].Inst,((k<0||k>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+k])).Inst.Rune=((k<0||k>=d[0].$length)?($throwRuntimeError(\"index out of range\"),undefined):d[0].$array[d[0].$offset+k]);j++;}}$s=-1;return a[0];}return;}if($f===undefined){$f={$blk:AR};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AS=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=CD.nil;if(a.Start===0){b=CD.nil;$s=-1;return b;}if(!(((c=a.Inst,d=a.Start,((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d])).Op===3))||!(((((((e=a.Inst,f=a.Start,((f<0||f>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+f])).Arg<<24>>>24))&4)>>>0)===4))){b=CD.nil;$s=-1;return b;}g=a.Inst;h=0;case 1:if(!(h<g.$length)){$s=2;continue;}i=$clone(((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h]),A.Inst);l=(j=a.Inst,k=i.Out,((k<0||k>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+k])).Op;m=i.Op;if((m===(0))||(m===(1))){if((l===4)||((n=a.Inst,o=i.Arg,((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o])).Op===4)){b=CD.nil;$s=-1;return b;}}else if(m===(3)){if(l===4){if(((((i.Arg<<24>>>24))&8)>>>0)===8){h++;$s=1;continue;}b=CD.nil;$s=-1;return b;}}else if(l===4){b=CD.nil;$s=-1;return b;}h++;$s=1;continue;case 2:b=AN(a);p=AR(b);$s=3;case 3:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}b=p;if(!(b===CD.nil)){AM(b,a);}b=b;$s=-1;return b;}return;}if($f===undefined){$f={$blk:AS};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};AT.ptr.prototype.String=function(){var a;a=this;return a.expr;};AT.prototype.String=function(){return this.$val.String();};AT.ptr.prototype.Copy=function(){var a,b;a=this;b=$clone(a,AT);return b;};AT.prototype.Copy=function(){return this.$val.Copy();};AU=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=AW(a,212,false);$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return b;}return;}if($f===undefined){$f={$blk:AU};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Compile=AU;AT.ptr.prototype.Longest=function(){var a;a=this;a.longest=true;};AT.prototype.Longest=function(){return this.$val.Longest();};AW=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=A.Parse(a,b);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;f=d[0];g=d[1];if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[CL.nil,g];}h=f.MaxCap();i=f.CapNames();f=f.Simplify();j=A.Compile(f);k=j[0];g=j[1];if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[CL.nil,g];}l=k.NumCap;if(l<2){l=2;}m=AS(k);$s=2;case 2:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=new AT.ptr(a,k,m,h,0,i,\"\",BX.nil,0,0,0,l,false,k.StartCond(),c);if(n.onepass===CD.nil){o=k.Prefix();n.prefix=o[0];n.prefixComplete=o[1];n.maxBitStateLen=O(k);}else{p=AE(k);n.prefix=p[0];n.prefixComplete=p[1];n.prefixEnd=p[2];}if(!(n.prefix===\"\")){n.prefixBytes=(new BX($stringToBytes(n.prefix)));q=I.DecodeRuneInString(n.prefix);n.prefixRune=q[0];}r=k.Inst.$length;s=0;while(true){if(!(!((((s<0||s>=AX.length)?($throwRuntimeError(\"index out of range\"),undefined):AX[s])===0))&&((s<0||s>=AX.length)?($throwRuntimeError(\"index out of range\"),undefined):AX[s])<r)){break;}s=s+(1)>>0;}n.mpool=s;$s=-1;return[n,$ifaceNil];}return;}if($f===undefined){$f={$blk:AW};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};AT.ptr.prototype.get=function(){var a,b,c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;d=(c=a.mpool,((c<0||c>=AY.length)?($throwRuntimeError(\"index out of range\"),undefined):AY[c])).Get();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}b=$assertType(d,CO,true);e=b[0];f=b[1];if(!f){e=new T.ptr(CL.nil,CM.nil,new Q.ptr(BT.nil,CP.nil),new Q.ptr(BT.nil,CP.nil),CQ.nil,false,BV.nil,new U.ptr(new BE.ptr(BX.nil),new BD.ptr(\"\"),new BF.ptr($ifaceNil,false,0)));}e.re=a;e.p=a.prog;if(e.matchcap.$capacity<a.matchcap){e.matchcap=$makeSlice(BV,a.matchcap);g=e.pool;h=0;while(true){if(!(h<g.$length)){break;}i=((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h]);i.cap=$makeSlice(BV,a.matchcap);h++;}}k=(j=a.mpool,((j<0||j>=AX.length)?($throwRuntimeError(\"index out of range\"),undefined):AX[j]));if(k===0){k=a.prog.Inst.$length;}if(e.q0.sparse.$length<k){Q.copy(e.q0,new Q.ptr($makeSlice(BT,k),$makeSlice(CP,0,k)));Q.copy(e.q1,new Q.ptr($makeSlice(BT,k),$makeSlice(CP,0,k)));}$s=-1;return e;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.get};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.get=function(){return this.$val.get();};AT.ptr.prototype.put=function(a){var a,b,c;b=this;a.re=CL.nil;a.p=CM.nil;a.inputs.clear();(c=b.mpool,((c<0||c>=AY.length)?($throwRuntimeError(\"index out of range\"),undefined):AY[c])).Put(a);};AT.prototype.put=function(a){return this.$val.put(a);};AZ=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=AU(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}b=c;d=b[0];e=b[1];if(!($interfaceIsEqual(e,$ifaceNil))){$s=2;continue;}$s=3;continue;case 2:f=e.Error();$s=4;case 4:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$panic(new $String(\"regexp: Compile(\"+BB(a)+\"): \"+f));case 3:$s=-1;return d;}return;}if($f===undefined){$f={$blk:AZ};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};$pkg.MustCompile=AZ;BB=function(a){var a;if(H.CanBackquote(a)){return\"`\"+a+\"`\";}return H.Quote(a);};AT.ptr.prototype.NumSubexp=function(){var a;a=this;return a.numSubexp;};AT.prototype.NumSubexp=function(){return this.$val.NumSubexp();};AT.ptr.prototype.SubexpNames=function(){var a;a=this;return a.subexpNames;};AT.prototype.SubexpNames=function(){return this.$val.SubexpNames();};BD.ptr.prototype.step=function(a){var a,b,c;b=this;if(a<b.str.length){c=b.str.charCodeAt(a);if(c<128){return[((c>>0)),1];}return I.DecodeRuneInString($substring(b.str,a));}return[-1,0];};BD.prototype.step=function(a){return this.$val.step(a);};BD.ptr.prototype.canCheckPrefix=function(){var a;a=this;return true;};BD.prototype.canCheckPrefix=function(){return this.$val.canCheckPrefix();};BD.ptr.prototype.hasPrefix=function(a){var a,b;b=this;return E.HasPrefix(b.str,a.prefix);};BD.prototype.hasPrefix=function(a){return this.$val.hasPrefix(a);};BD.ptr.prototype.index=function(a,b){var a,b,c;c=this;return E.Index($substring(c.str,b),a.prefix);};BD.prototype.index=function(a,b){return this.$val.index(a,b);};BD.ptr.prototype.context=function(a){var a,b,c,d,e,f,g,h;b=this;c=-1;d=-1;e=c;f=d;if((((a-1>>0)>>>0))<((b.str.length>>>0))){e=((b.str.charCodeAt((a-1>>0))>>0));if(e>=128){g=I.DecodeLastRuneInString($substring(b.str,0,a));e=g[0];}}if(((a>>>0))<((b.str.length>>>0))){f=((b.str.charCodeAt(a)>>0));if(f>=128){h=I.DecodeRuneInString($substring(b.str,a));f=h[0];}}return W(e,f);};BD.prototype.context=function(a){return this.$val.context(a);};BE.ptr.prototype.step=function(a){var a,b,c,d;b=this;if(a<b.str.$length){d=(c=b.str,((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]));if(d<128){return[((d>>0)),1];}return I.DecodeRune($subslice(b.str,a));}return[-1,0];};BE.prototype.step=function(a){return this.$val.step(a);};BE.ptr.prototype.canCheckPrefix=function(){var a;a=this;return true;};BE.prototype.canCheckPrefix=function(){return this.$val.canCheckPrefix();};BE.ptr.prototype.hasPrefix=function(a){var a,b;b=this;return G.HasPrefix(b.str,a.prefixBytes);};BE.prototype.hasPrefix=function(a){return this.$val.hasPrefix(a);};BE.ptr.prototype.index=function(a,b){var a,b,c;c=this;return G.Index($subslice(c.str,b),a.prefixBytes);};BE.prototype.index=function(a,b){return this.$val.index(a,b);};BE.ptr.prototype.context=function(a){var a,b,c,d,e,f,g,h,i,j,k;b=this;c=-1;d=-1;e=c;f=d;if((((a-1>>0)>>>0))<((b.str.$length>>>0))){e=(((g=b.str,h=a-1>>0,((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h]))>>0));if(e>=128){i=I.DecodeLastRune($subslice(b.str,0,a));e=i[0];}}if(((a>>>0))<((b.str.$length>>>0))){f=(((j=b.str,((a<0||a>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+a]))>>0));if(f>=128){k=I.DecodeRune($subslice(b.str,a));f=k[0];}}return W(e,f);};BE.prototype.context=function(a){return this.$val.context(a);};BF.ptr.prototype.step=function(a){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(!b.atEOT&&!((a===b.pos))){$s=-1;return[-1,0];}d=b.r.ReadRune();$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}c=d;e=c[0];f=c[1];g=c[2];if(!($interfaceIsEqual(g,$ifaceNil))){b.atEOT=true;$s=-1;return[-1,0];}b.pos=b.pos+(f)>>0;$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:BF.ptr.prototype.step};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};BF.prototype.step=function(a){return this.$val.step(a);};BF.ptr.prototype.canCheckPrefix=function(){var a;a=this;return false;};BF.prototype.canCheckPrefix=function(){return this.$val.canCheckPrefix();};BF.ptr.prototype.hasPrefix=function(a){var a,b;b=this;return false;};BF.prototype.hasPrefix=function(a){return this.$val.hasPrefix(a);};BF.ptr.prototype.index=function(a,b){var a,b,c;c=this;return-1;};BF.prototype.index=function(a,b){return this.$val.index(a,b);};BF.ptr.prototype.context=function(a){var a,b;b=this;return new V(0,0);};BF.prototype.context=function(a){return this.$val.context(a);};AT.ptr.prototype.LiteralPrefix=function(){var a,b,c,d,e;a=\"\";b=false;c=this;d=c.prefix;e=c.prefixComplete;a=d;b=e;return[a,b];};AT.prototype.LiteralPrefix=function(){return this.$val.LiteralPrefix();};AT.ptr.prototype.MatchReader=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.doMatch(a,BX.nil,\"\");$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.MatchReader};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.MatchReader=function(a){return this.$val.MatchReader(a);};AT.ptr.prototype.MatchString=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.doMatch($ifaceNil,BX.nil,a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.MatchString};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.MatchString=function(a){return this.$val.MatchString(a);};AT.ptr.prototype.Match=function(a){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.doMatch($ifaceNil,a,\"\");$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.Match};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.Match=function(a){return this.$val.Match(a);};AT.ptr.prototype.ReplaceAllString=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];c=[c];c[0]=this;d=2;if(E.Contains(b[0],\"$\")){d=$imul(2,((c[0].numSubexp+1>>0)));}e=c[0].replaceAll(BX.nil,a[0],d,(function(a,b,c){return function(e,f){var e,f;return c[0].expand(e,b[0],BX.nil,a[0],f);};})(a,b,c));$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;$s=-1;return($bytesToString(f));}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.ReplaceAllString};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.ReplaceAllString=function(a,b){return this.$val.ReplaceAllString(a,b);};AT.ptr.prototype.ReplaceAllLiteralString=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=[b];c=this;d=c.replaceAll(BX.nil,a,2,(function(b){return function(d,e){var d,e;return $appendSlice(d,b[0]);};})(b));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return($bytesToString(d));}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.ReplaceAllLiteralString};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.ReplaceAllLiteralString=function(a,b){return this.$val.ReplaceAllLiteralString(a,b);};AT.ptr.prototype.ReplaceAllStringFunc=function(a,b){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];c=this;d=c.replaceAll(BX.nil,a[0],2,(function(a,b){return function $b(d,e){var d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=d;g=b[0]($substring(a[0],(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]),(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1])));$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;$s=-1;return $appendSlice(f,h);}return;}if($f===undefined){$f={$blk:$b};}$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};})(a,b));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;$s=-1;return($bytesToString(e));}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.ReplaceAllStringFunc};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.ReplaceAllStringFunc=function(a,b){return this.$val.ReplaceAllStringFunc(a,b);};AT.ptr.prototype.replaceAll=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=0;g=0;h=BX.nil;i=0;if(!(a===BX.nil)){i=a.$length;}else{i=b.length;}if(c>e.prog.NumCap){c=e.prog.NumCap;}j=CR.zero();case 1:if(!(g<=i)){$s=2;continue;}k=e.doExecute($ifaceNil,a,b,g,c,$subslice(new BV(j),0,0));$s=3;case 3:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}l=k;if(l.$length===0){$s=2;continue;}if(!(a===BX.nil)){h=$appendSlice(h,$subslice(a,f,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])));}else{h=$appendSlice(h,$substring(b,f,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])));}if((1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1])>f||((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])===0)){$s=4;continue;}$s=5;continue;case 4:m=d(h,l);$s=6;case 6:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}h=m;case 5:f=(1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1]);n=0;if(!(a===BX.nil)){o=I.DecodeRune($subslice(a,g));n=o[1];}else{p=I.DecodeRuneInString($substring(b,g));n=p[1];}if((g+n>>0)>(1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1])){g=g+(n)>>0;}else if((g+1>>0)>(1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1])){g=g+(1)>>0;}else{g=(1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1]);}$s=1;continue;case 2:if(!(a===BX.nil)){h=$appendSlice(h,$subslice(a,f));}else{h=$appendSlice(h,$substring(b,f));}$s=-1;return h;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.replaceAll};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.replaceAll=function(a,b,c,d){return this.$val.replaceAll(a,b,c,d);};AT.ptr.prototype.ReplaceAll=function(a,b){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];c=[c];d=[d];c[0]=this;e=2;if(G.IndexByte(b[0],36)>=0){e=$imul(2,((c[0].numSubexp+1>>0)));}d[0]=\"\";f=c[0].replaceAll(a[0],\"\",e,(function(a,b,c,d){return function(f,g){var f,g;if(!((d[0].length===b[0].$length))){d[0]=($bytesToString(b[0]));}return c[0].expand(f,d[0],a[0],\"\",g);};})(a,b,c,d));$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;$s=-1;return g;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.ReplaceAll};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.ReplaceAll=function(a,b){return this.$val.ReplaceAll(a,b);};AT.ptr.prototype.ReplaceAllLiteral=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=[b];c=this;d=c.replaceAll(a,\"\",2,(function(b){return function(d,e){var d,e;return $appendSlice(d,b[0]);};})(b));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.ReplaceAllLiteral};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.ReplaceAllLiteral=function(a,b){return this.$val.ReplaceAllLiteral(a,b);};AT.ptr.prototype.ReplaceAllFunc=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];c=this;d=c.replaceAll(a[0],\"\",2,(function(a,b){return function $b(d,e){var d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=d;g=b[0]($subslice(a[0],(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]),(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1])));$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;$s=-1;return $appendSlice(f,h);}return;}if($f===undefined){$f={$blk:$b};}$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};})(a,b));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.ReplaceAllFunc};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.ReplaceAllFunc=function(a,b){return this.$val.ReplaceAllFunc(a,b);};BL=function(){var a,b,c,d,e,f,g;a=(new BX($stringToBytes(\"\\\\.+*?()|[]{}^$\")));b=0;while(true){if(!(b<a.$length)){break;}c=((b<0||b>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+b]);e=(d=c%16,d===d?d:$throwRuntimeError(\"integer divide by zero\"));((e<0||e>=BJ.length)?($throwRuntimeError(\"index out of range\"),undefined):BJ[e]=((((e<0||e>=BJ.length)?($throwRuntimeError(\"index out of range\"),undefined):BJ[e])|(((f=((g=c/16,(g===g&&g!==1/0&&g!==-1/0)?g>>>0:$throwRuntimeError(\"integer divide by zero\"))),f<32?(1<<f):0)<<24>>>24)))>>>0));b++;}};AT.ptr.prototype.pad=function(a){var a,b,c;b=this;if(a===BV.nil){return BV.nil;}c=$imul(((1+b.numSubexp>>0)),2);while(true){if(!(a.$length<c)){break;}a=$append(a,-1);}return a;};AT.prototype.pad=function(a){return this.$val.pad(a);};AT.ptr.prototype.allMatches=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=0;if(b===BX.nil){f=a.length;}else{f=b.$length;}g=0;h=0;i=-1;j=g;k=h;l=i;case 1:if(!(k<c&&j<=f)){$s=2;continue;}m=e.doExecute($ifaceNil,b,a,j,e.prog.NumCap,BV.nil);$s=3;case 3:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=m;if(n.$length===0){$s=2;continue;}o=true;if((1>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+1])===j){if((0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0])===l){o=false;}p=0;if(b===BX.nil){q=I.DecodeRuneInString($substring(a,j,f));p=q[1];}else{r=I.DecodeRune($subslice(b,j,f));p=r[1];}if(p>0){j=j+(p)>>0;}else{j=f+1>>0;}}else{j=(1>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+1]);}l=(1>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+1]);if(o){$s=4;continue;}$s=5;continue;case 4:$r=d(e.pad(n));$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}k=k+(1)>>0;case 5:$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.allMatches};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.allMatches=function(a,b,c,d){return this.$val.allMatches(a,b,c,d);};AT.ptr.prototype.Find=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=CR.zero();d=b.doExecute($ifaceNil,a,\"\",0,2,$subslice(new BV(c),0,0));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){$s=-1;return BX.nil;}$s=-1;return $subslice(a,(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]),(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1]));}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.Find};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.Find=function(a){return this.$val.Find(a);};AT.ptr.prototype.FindIndex=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=BV.nil;c=this;d=c.doExecute($ifaceNil,a,\"\",0,2,BV.nil);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){b=BV.nil;$s=-1;return b;}b=$subslice(e,0,2);$s=-1;return b;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindIndex=function(a){return this.$val.FindIndex(a);};AT.ptr.prototype.FindString=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=CR.zero();d=b.doExecute($ifaceNil,BX.nil,a,0,2,$subslice(new BV(c),0,0));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){$s=-1;return\"\";}$s=-1;return $substring(a,(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]),(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1]));}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindString};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindString=function(a){return this.$val.FindString(a);};AT.ptr.prototype.FindStringIndex=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=BV.nil;c=this;d=c.doExecute($ifaceNil,BX.nil,a,0,2,BV.nil);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){b=BV.nil;$s=-1;return b;}b=$subslice(e,0,2);$s=-1;return b;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindStringIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindStringIndex=function(a){return this.$val.FindStringIndex(a);};AT.ptr.prototype.FindReaderIndex=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=BV.nil;c=this;d=c.doExecute(a,BX.nil,\"\",0,2,BV.nil);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){b=BV.nil;$s=-1;return b;}b=$subslice(e,0,2);$s=-1;return b;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindReaderIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindReaderIndex=function(a){return this.$val.FindReaderIndex(a);};AT.ptr.prototype.FindSubmatch=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=CS.zero();d=b.doExecute($ifaceNil,a,\"\",0,b.prog.NumCap,$subslice(new BV(c),0,0));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){$s=-1;return CT.nil;}f=$makeSlice(CT,(1+b.numSubexp>>0));g=f;h=0;while(true){if(!(h<g.$length)){break;}i=h;if(($imul(2,i))<e.$length&&(j=$imul(2,i),((j<0||j>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+j]))>=0){((i<0||i>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+i]=$subslice(a,(k=$imul(2,i),((k<0||k>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+k])),(l=($imul(2,i))+1>>0,((l<0||l>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+l]))));}h++;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindSubmatch};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindSubmatch=function(a){return this.$val.FindSubmatch(a);};AT.ptr.prototype.Expand=function(a,b,c,d){var a,b,c,d,e;e=this;return e.expand(a,($bytesToString(b)),c,\"\",d);};AT.prototype.Expand=function(a,b,c,d){return this.$val.Expand(a,b,c,d);};AT.ptr.prototype.ExpandString=function(a,b,c,d){var a,b,c,d,e;e=this;return e.expand(a,b,BX.nil,c,d);};AT.prototype.ExpandString=function(a,b,c,d){return this.$val.ExpandString(a,b,c,d);};AT.ptr.prototype.expand=function(a,b,c,d,e){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;f=this;while(true){if(!(b.length>0)){break;}g=E.Index(b,\"$\");if(g<0){break;}a=$appendSlice(a,$substring(b,0,g));b=$substring(b,g);if(b.length>1&&(b.charCodeAt(1)===36)){a=$append(a,36);b=$substring(b,2);continue;}h=BN(b);i=h[0];j=h[1];k=h[2];l=h[3];if(!l){a=$append(a,36);b=$substring(b,1);continue;}b=k;if(j>=0){if((($imul(2,j))+1>>0)<e.$length&&(m=$imul(2,j),((m<0||m>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+m]))>=0){if(!(c===BX.nil)){a=$appendSlice(a,$subslice(c,(n=$imul(2,j),((n<0||n>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+n])),(o=($imul(2,j))+1>>0,((o<0||o>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+o]))));}else{a=$appendSlice(a,$substring(d,(p=$imul(2,j),((p<0||p>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+p])),(q=($imul(2,j))+1>>0,((q<0||q>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+q]))));}}}else{r=f.subexpNames;s=0;while(true){if(!(s<r.$length)){break;}t=s;u=((s<0||s>=r.$length)?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+s]);if(i===u&&(($imul(2,t))+1>>0)<e.$length&&(v=$imul(2,t),((v<0||v>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+v]))>=0){if(!(c===BX.nil)){a=$appendSlice(a,$subslice(c,(w=$imul(2,t),((w<0||w>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+w])),(x=($imul(2,t))+1>>0,((x<0||x>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+x]))));}else{a=$appendSlice(a,$substring(d,(y=$imul(2,t),((y<0||y>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+y])),(z=($imul(2,t))+1>>0,((z<0||z>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+z]))));}break;}s++;}}}a=$appendSlice(a,b);return a;};AT.prototype.expand=function(a,b,c,d,e){return this.$val.expand(a,b,c,d,e);};BN=function(a){var a,b,c,d,e,f,g,h,i,j,k;b=\"\";c=0;d=\"\";e=false;if(a.length<2||!((a.charCodeAt(0)===36))){return[b,c,d,e];}f=false;if(a.charCodeAt(1)===123){f=true;a=$substring(a,2);}else{a=$substring(a,1);}g=0;while(true){if(!(g<a.length)){break;}h=I.DecodeRuneInString($substring(a,g));i=h[0];j=h[1];if(!F.IsLetter(i)&&!F.IsDigit(i)&&!((i===95))){break;}g=g+(j)>>0;}if(g===0){return[b,c,d,e];}b=$substring(a,0,g);if(f){if(g>=a.length||!((a.charCodeAt(g)===125))){return[b,c,d,e];}g=g+(1)>>0;}c=0;k=0;while(true){if(!(k<b.length)){break;}if(b.charCodeAt(k)<48||57<b.charCodeAt(k)||c>=100000000){c=-1;break;}c=(($imul(c,10))+((b.charCodeAt(k)>>0))>>0)-48>>0;k=k+(1)>>0;}if((b.charCodeAt(0)===48)&&b.length>1){c=-1;}d=$substring(a,g);e=true;return[b,c,d,e];};AT.ptr.prototype.FindSubmatchIndex=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.doExecute($ifaceNil,a,\"\",0,b.prog.NumCap,BV.nil);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=b.pad(c);$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindSubmatchIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindSubmatchIndex=function(a){return this.$val.FindSubmatchIndex(a);};AT.ptr.prototype.FindStringSubmatch=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=CS.zero();d=b.doExecute($ifaceNil,BX.nil,a,0,b.prog.NumCap,$subslice(new BV(c),0,0));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e===BV.nil){$s=-1;return CN.nil;}f=$makeSlice(CN,(1+b.numSubexp>>0));g=f;h=0;while(true){if(!(h<g.$length)){break;}i=h;if(($imul(2,i))<e.$length&&(j=$imul(2,i),((j<0||j>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+j]))>=0){((i<0||i>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+i]=$substring(a,(k=$imul(2,i),((k<0||k>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+k])),(l=($imul(2,i))+1>>0,((l<0||l>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+l]))));}h++;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindStringSubmatch};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindStringSubmatch=function(a){return this.$val.FindStringSubmatch(a);};AT.ptr.prototype.FindStringSubmatchIndex=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.doExecute($ifaceNil,BX.nil,a,0,b.prog.NumCap,BV.nil);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=b.pad(c);$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindStringSubmatchIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindStringSubmatchIndex=function(a){return this.$val.FindStringSubmatchIndex(a);};AT.ptr.prototype.FindReaderSubmatchIndex=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.doExecute(a,BX.nil,\"\",0,b.prog.NumCap,BV.nil);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=b.pad(c);$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindReaderSubmatchIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindReaderSubmatchIndex=function(a){return this.$val.FindReaderSubmatchIndex(a);};AT.ptr.prototype.FindAll=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];c=[c];d=this;if(b<0){b=a[0].$length+1>>0;}c[0]=CT.nil;$r=d.allMatches(\"\",a[0],b,(function(a,c){return function(e){var e;if(c[0]===CT.nil){c[0]=$makeSlice(CT,0,10);}c[0]=$append(c[0],$subslice(a[0],(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]),(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1])));};})(a,c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAll};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAll=function(a,b){return this.$val.FindAll(a,b);};AT.ptr.prototype.FindAllIndex=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];d=this;if(b<0){b=a.$length+1>>0;}c[0]=CU.nil;$r=d.allMatches(\"\",a,b,(function(c){return function(e){var e;if(c[0]===CU.nil){c[0]=$makeSlice(CU,0,10);}c[0]=$append(c[0],$subslice(e,0,2));};})(c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllIndex=function(a,b){return this.$val.FindAllIndex(a,b);};AT.ptr.prototype.FindAllString=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];c=[c];d=this;if(b<0){b=a[0].length+1>>0;}c[0]=CN.nil;$r=d.allMatches(a[0],BX.nil,b,(function(a,c){return function(e){var e;if(c[0]===CN.nil){c[0]=$makeSlice(CN,0,10);}c[0]=$append(c[0],$substring(a[0],(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]),(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1])));};})(a,c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllString};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllString=function(a,b){return this.$val.FindAllString(a,b);};AT.ptr.prototype.FindAllStringIndex=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];d=this;if(b<0){b=a.length+1>>0;}c[0]=CU.nil;$r=d.allMatches(a,BX.nil,b,(function(c){return function(e){var e;if(c[0]===CU.nil){c[0]=$makeSlice(CU,0,10);}c[0]=$append(c[0],$subslice(e,0,2));};})(c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllStringIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllStringIndex=function(a,b){return this.$val.FindAllStringIndex(a,b);};AT.ptr.prototype.FindAllSubmatch=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];c=[c];d=this;if(b<0){b=a[0].$length+1>>0;}c[0]=CV.nil;$r=d.allMatches(\"\",a[0],b,(function(a,c){return function(e){var e,f,g,h,i,j,k,l,m;if(c[0]===CV.nil){c[0]=$makeSlice(CV,0,10);}g=$makeSlice(CT,(f=e.$length/2,(f===f&&f!==1/0&&f!==-1/0)?f>>0:$throwRuntimeError(\"integer divide by zero\")));h=g;i=0;while(true){if(!(i<h.$length)){break;}j=i;if((k=$imul(2,j),((k<0||k>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+k]))>=0){((j<0||j>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+j]=$subslice(a[0],(l=$imul(2,j),((l<0||l>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+l])),(m=($imul(2,j))+1>>0,((m<0||m>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+m]))));}i++;}c[0]=$append(c[0],g);};})(a,c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllSubmatch};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllSubmatch=function(a,b){return this.$val.FindAllSubmatch(a,b);};AT.ptr.prototype.FindAllSubmatchIndex=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];d=this;if(b<0){b=a.$length+1>>0;}c[0]=CU.nil;$r=d.allMatches(\"\",a,b,(function(c){return function(e){var e;if(c[0]===CU.nil){c[0]=$makeSlice(CU,0,10);}c[0]=$append(c[0],e);};})(c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllSubmatchIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllSubmatchIndex=function(a,b){return this.$val.FindAllSubmatchIndex(a,b);};AT.ptr.prototype.FindAllStringSubmatch=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];c=[c];d=this;if(b<0){b=a[0].length+1>>0;}c[0]=CW.nil;$r=d.allMatches(a[0],BX.nil,b,(function(a,c){return function(e){var e,f,g,h,i,j,k,l,m;if(c[0]===CW.nil){c[0]=$makeSlice(CW,0,10);}g=$makeSlice(CN,(f=e.$length/2,(f===f&&f!==1/0&&f!==-1/0)?f>>0:$throwRuntimeError(\"integer divide by zero\")));h=g;i=0;while(true){if(!(i<h.$length)){break;}j=i;if((k=$imul(2,j),((k<0||k>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+k]))>=0){((j<0||j>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+j]=$substring(a[0],(l=$imul(2,j),((l<0||l>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+l])),(m=($imul(2,j))+1>>0,((m<0||m>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+m]))));}i++;}c[0]=$append(c[0],g);};})(a,c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllStringSubmatch};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllStringSubmatch=function(a,b){return this.$val.FindAllStringSubmatch(a,b);};AT.ptr.prototype.FindAllStringSubmatchIndex=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];d=this;if(b<0){b=a.length+1>>0;}c[0]=CU.nil;$r=d.allMatches(a,BX.nil,b,(function(c){return function(e){var e;if(c[0]===CU.nil){c[0]=$makeSlice(CU,0,10);}c[0]=$append(c[0],e);};})(c));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c[0];}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.FindAllStringSubmatchIndex};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.FindAllStringSubmatchIndex=function(a,b){return this.$val.FindAllStringSubmatchIndex(a,b);};AT.ptr.prototype.Split=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(b===0){$s=-1;return CN.nil;}if(c.expr.length>0&&(a.length===0)){$s=-1;return new CN([\"\"]);}d=c.FindAllStringIndex(a,b);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;f=$makeSlice(CN,0,e.$length);g=0;h=0;i=e;j=0;while(true){if(!(j<i.$length)){break;}k=((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]);if(b>0&&f.$length>=(b-1>>0)){break;}h=(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]);if(!(((1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1])===0))){f=$append(f,$substring(a,g,h));}g=(1>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+1]);j++;}if(!((h===a.length))){f=$append(f,$substring(a,g));}$s=-1;return f;}return;}if($f===undefined){$f={$blk:AT.ptr.prototype.Split};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};AT.prototype.Split=function(a,b){return this.$val.Split(a,b);};BU.methods=[{prop:\"reset\",name:\"reset\",pkg:\"regexp\",typ:$funcType([CM,$Int,$Int],[],false)},{prop:\"shouldVisit\",name:\"shouldVisit\",pkg:\"regexp\",typ:$funcType([$Uint32,$Int],[$Bool],false)},{prop:\"push\",name:\"push\",pkg:\"regexp\",typ:$funcType([CL,$Uint32,$Int,$Bool],[],false)}];CO.methods=[{prop:\"init\",name:\"init\",pkg:\"regexp\",typ:$funcType([$Int],[],false)},{prop:\"alloc\",name:\"alloc\",pkg:\"regexp\",typ:$funcType([BZ],[BY],false)},{prop:\"match\",name:\"match\",pkg:\"regexp\",typ:$funcType([BC,$Int],[$Bool],false)},{prop:\"clear\",name:\"clear\",pkg:\"regexp\",typ:$funcType([CX],[],false)},{prop:\"step\",name:\"step\",pkg:\"regexp\",typ:$funcType([CX,CX,$Int,$Int,$Int32,CA],[],false)},{prop:\"add\",name:\"add\",pkg:\"regexp\",typ:$funcType([CX,$Uint32,$Int,BV,CA,BY],[BY],false)}];CY.methods=[{prop:\"newBytes\",name:\"newBytes\",pkg:\"regexp\",typ:$funcType([BX],[BC],false)},{prop:\"newString\",name:\"newString\",pkg:\"regexp\",typ:$funcType([$String],[BC],false)},{prop:\"newReader\",name:\"newReader\",pkg:\"regexp\",typ:$funcType([C.RuneReader],[BC],false)},{prop:\"clear\",name:\"clear\",pkg:\"regexp\",typ:$funcType([],[],false)},{prop:\"init\",name:\"init\",pkg:\"regexp\",typ:$funcType([C.RuneReader,BX,$String],[BC,$Int],false)}];V.methods=[{prop:\"match\",name:\"match\",pkg:\"regexp\",typ:$funcType([A.EmptyOp],[$Bool],false)}];CF.methods=[{prop:\"empty\",name:\"empty\",pkg:\"regexp\",typ:$funcType([],[$Bool],false)},{prop:\"next\",name:\"next\",pkg:\"regexp\",typ:$funcType([],[$Uint32],false)},{prop:\"clear\",name:\"clear\",pkg:\"regexp\",typ:$funcType([],[],false)},{prop:\"contains\",name:\"contains\",pkg:\"regexp\",typ:$funcType([$Uint32],[$Bool],false)},{prop:\"insert\",name:\"insert\",pkg:\"regexp\",typ:$funcType([$Uint32],[],false)},{prop:\"insertNew\",name:\"insertNew\",pkg:\"regexp\",typ:$funcType([$Uint32],[],false)}];AO.methods=[{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)}];CL.methods=[{prop:\"tryBacktrack\",name:\"tryBacktrack\",pkg:\"regexp\",typ:$funcType([BU,BC,$Uint32,$Int],[$Bool],false)},{prop:\"backtrack\",name:\"backtrack\",pkg:\"regexp\",typ:$funcType([BX,$String,$Int,$Int,BV],[BV],false)},{prop:\"doOnePass\",name:\"doOnePass\",pkg:\"regexp\",typ:$funcType([C.RuneReader,BX,$String,$Int,$Int,BV],[BV],false)},{prop:\"doMatch\",name:\"doMatch\",pkg:\"regexp\",typ:$funcType([C.RuneReader,BX,$String],[$Bool],false)},{prop:\"doExecute\",name:\"doExecute\",pkg:\"regexp\",typ:$funcType([C.RuneReader,BX,$String,$Int,$Int,BV],[BV],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Copy\",name:\"Copy\",pkg:\"\",typ:$funcType([],[CL],false)},{prop:\"Longest\",name:\"Longest\",pkg:\"\",typ:$funcType([],[],false)},{prop:\"get\",name:\"get\",pkg:\"regexp\",typ:$funcType([],[CO],false)},{prop:\"put\",name:\"put\",pkg:\"regexp\",typ:$funcType([CO],[],false)},{prop:\"NumSubexp\",name:\"NumSubexp\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"SubexpNames\",name:\"SubexpNames\",pkg:\"\",typ:$funcType([],[CN],false)},{prop:\"LiteralPrefix\",name:\"LiteralPrefix\",pkg:\"\",typ:$funcType([],[$String,$Bool],false)},{prop:\"MatchReader\",name:\"MatchReader\",pkg:\"\",typ:$funcType([C.RuneReader],[$Bool],false)},{prop:\"MatchString\",name:\"MatchString\",pkg:\"\",typ:$funcType([$String],[$Bool],false)},{prop:\"Match\",name:\"Match\",pkg:\"\",typ:$funcType([BX],[$Bool],false)},{prop:\"ReplaceAllString\",name:\"ReplaceAllString\",pkg:\"\",typ:$funcType([$String,$String],[$String],false)},{prop:\"ReplaceAllLiteralString\",name:\"ReplaceAllLiteralString\",pkg:\"\",typ:$funcType([$String,$String],[$String],false)},{prop:\"ReplaceAllStringFunc\",name:\"ReplaceAllStringFunc\",pkg:\"\",typ:$funcType([$String,CZ],[$String],false)},{prop:\"replaceAll\",name:\"replaceAll\",pkg:\"regexp\",typ:$funcType([BX,$String,$Int,DA],[BX],false)},{prop:\"ReplaceAll\",name:\"ReplaceAll\",pkg:\"\",typ:$funcType([BX,BX],[BX],false)},{prop:\"ReplaceAllLiteral\",name:\"ReplaceAllLiteral\",pkg:\"\",typ:$funcType([BX,BX],[BX],false)},{prop:\"ReplaceAllFunc\",name:\"ReplaceAllFunc\",pkg:\"\",typ:$funcType([BX,DB],[BX],false)},{prop:\"pad\",name:\"pad\",pkg:\"regexp\",typ:$funcType([BV],[BV],false)},{prop:\"allMatches\",name:\"allMatches\",pkg:\"regexp\",typ:$funcType([$String,BX,$Int,DC],[],false)},{prop:\"Find\",name:\"Find\",pkg:\"\",typ:$funcType([BX],[BX],false)},{prop:\"FindIndex\",name:\"FindIndex\",pkg:\"\",typ:$funcType([BX],[BV],false)},{prop:\"FindString\",name:\"FindString\",pkg:\"\",typ:$funcType([$String],[$String],false)},{prop:\"FindStringIndex\",name:\"FindStringIndex\",pkg:\"\",typ:$funcType([$String],[BV],false)},{prop:\"FindReaderIndex\",name:\"FindReaderIndex\",pkg:\"\",typ:$funcType([C.RuneReader],[BV],false)},{prop:\"FindSubmatch\",name:\"FindSubmatch\",pkg:\"\",typ:$funcType([BX],[CT],false)},{prop:\"Expand\",name:\"Expand\",pkg:\"\",typ:$funcType([BX,BX,BX,BV],[BX],false)},{prop:\"ExpandString\",name:\"ExpandString\",pkg:\"\",typ:$funcType([BX,$String,$String,BV],[BX],false)},{prop:\"expand\",name:\"expand\",pkg:\"regexp\",typ:$funcType([BX,$String,BX,$String,BV],[BX],false)},{prop:\"FindSubmatchIndex\",name:\"FindSubmatchIndex\",pkg:\"\",typ:$funcType([BX],[BV],false)},{prop:\"FindStringSubmatch\",name:\"FindStringSubmatch\",pkg:\"\",typ:$funcType([$String],[CN],false)},{prop:\"FindStringSubmatchIndex\",name:\"FindStringSubmatchIndex\",pkg:\"\",typ:$funcType([$String],[BV],false)},{prop:\"FindReaderSubmatchIndex\",name:\"FindReaderSubmatchIndex\",pkg:\"\",typ:$funcType([C.RuneReader],[BV],false)},{prop:\"FindAll\",name:\"FindAll\",pkg:\"\",typ:$funcType([BX,$Int],[CT],false)},{prop:\"FindAllIndex\",name:\"FindAllIndex\",pkg:\"\",typ:$funcType([BX,$Int],[CU],false)},{prop:\"FindAllString\",name:\"FindAllString\",pkg:\"\",typ:$funcType([$String,$Int],[CN],false)},{prop:\"FindAllStringIndex\",name:\"FindAllStringIndex\",pkg:\"\",typ:$funcType([$String,$Int],[CU],false)},{prop:\"FindAllSubmatch\",name:\"FindAllSubmatch\",pkg:\"\",typ:$funcType([BX,$Int],[CV],false)},{prop:\"FindAllSubmatchIndex\",name:\"FindAllSubmatchIndex\",pkg:\"\",typ:$funcType([BX,$Int],[CU],false)},{prop:\"FindAllStringSubmatch\",name:\"FindAllStringSubmatch\",pkg:\"\",typ:$funcType([$String,$Int],[CW],false)},{prop:\"FindAllStringSubmatchIndex\",name:\"FindAllStringSubmatchIndex\",pkg:\"\",typ:$funcType([$String,$Int],[CU],false)},{prop:\"Split\",name:\"Split\",pkg:\"\",typ:$funcType([$String,$Int],[CN],false)}];DD.methods=[{prop:\"step\",name:\"step\",pkg:\"regexp\",typ:$funcType([$Int],[$Int32,$Int],false)},{prop:\"canCheckPrefix\",name:\"canCheckPrefix\",pkg:\"regexp\",typ:$funcType([],[$Bool],false)},{prop:\"hasPrefix\",name:\"hasPrefix\",pkg:\"regexp\",typ:$funcType([CL],[$Bool],false)},{prop:\"index\",name:\"index\",pkg:\"regexp\",typ:$funcType([CL,$Int],[$Int],false)},{prop:\"context\",name:\"context\",pkg:\"regexp\",typ:$funcType([$Int],[V],false)}];DE.methods=[{prop:\"step\",name:\"step\",pkg:\"regexp\",typ:$funcType([$Int],[$Int32,$Int],false)},{prop:\"canCheckPrefix\",name:\"canCheckPrefix\",pkg:\"regexp\",typ:$funcType([],[$Bool],false)},{prop:\"hasPrefix\",name:\"hasPrefix\",pkg:\"regexp\",typ:$funcType([CL],[$Bool],false)},{prop:\"index\",name:\"index\",pkg:\"regexp\",typ:$funcType([CL,$Int],[$Int],false)},{prop:\"context\",name:\"context\",pkg:\"regexp\",typ:$funcType([$Int],[V],false)}];DF.methods=[{prop:\"step\",name:\"step\",pkg:\"regexp\",typ:$funcType([$Int],[$Int32,$Int],false)},{prop:\"canCheckPrefix\",name:\"canCheckPrefix\",pkg:\"regexp\",typ:$funcType([],[$Bool],false)},{prop:\"hasPrefix\",name:\"hasPrefix\",pkg:\"regexp\",typ:$funcType([CL],[$Bool],false)},{prop:\"index\",name:\"index\",pkg:\"regexp\",typ:$funcType([CL,$Int],[$Int],false)},{prop:\"context\",name:\"context\",pkg:\"regexp\",typ:$funcType([$Int],[V],false)}];J.init(\"regexp\",[{prop:\"pc\",name:\"pc\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"arg\",name:\"arg\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"pos\",name:\"pos\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);K.init(\"regexp\",[{prop:\"end\",name:\"end\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"cap\",name:\"cap\",embedded:false,exported:false,typ:BV,tag:\"\"},{prop:\"matchcap\",name:\"matchcap\",embedded:false,exported:false,typ:BV,tag:\"\"},{prop:\"jobs\",name:\"jobs\",embedded:false,exported:false,typ:BW,tag:\"\"},{prop:\"visited\",name:\"visited\",embedded:false,exported:false,typ:BT,tag:\"\"},{prop:\"inputs\",name:\"inputs\",embedded:false,exported:false,typ:U,tag:\"\"}]);Q.init(\"regexp\",[{prop:\"sparse\",name:\"sparse\",embedded:false,exported:false,typ:BT,tag:\"\"},{prop:\"dense\",name:\"dense\",embedded:false,exported:false,typ:CP,tag:\"\"}]);R.init(\"regexp\",[{prop:\"pc\",name:\"pc\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"t\",name:\"t\",embedded:false,exported:false,typ:BY,tag:\"\"}]);S.init(\"regexp\",[{prop:\"inst\",name:\"inst\",embedded:false,exported:false,typ:BZ,tag:\"\"},{prop:\"cap\",name:\"cap\",embedded:false,exported:false,typ:BV,tag:\"\"}]);T.init(\"regexp\",[{prop:\"re\",name:\"re\",embedded:false,exported:false,typ:CL,tag:\"\"},{prop:\"p\",name:\"p\",embedded:false,exported:false,typ:CM,tag:\"\"},{prop:\"q0\",name:\"q0\",embedded:false,exported:false,typ:Q,tag:\"\"},{prop:\"q1\",name:\"q1\",embedded:false,exported:false,typ:Q,tag:\"\"},{prop:\"pool\",name:\"pool\",embedded:false,exported:false,typ:CQ,tag:\"\"},{prop:\"matched\",name:\"matched\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"matchcap\",name:\"matchcap\",embedded:false,exported:false,typ:BV,tag:\"\"},{prop:\"inputs\",name:\"inputs\",embedded:false,exported:false,typ:U,tag:\"\"}]);U.init(\"regexp\",[{prop:\"bytes\",name:\"bytes\",embedded:false,exported:false,typ:BE,tag:\"\"},{prop:\"string\",name:\"string\",embedded:false,exported:false,typ:BD,tag:\"\"},{prop:\"reader\",name:\"reader\",embedded:false,exported:false,typ:BF,tag:\"\"}]);X.init(\"regexp\",[{prop:\"inputs\",name:\"inputs\",embedded:false,exported:false,typ:U,tag:\"\"},{prop:\"matchcap\",name:\"matchcap\",embedded:false,exported:false,typ:BV,tag:\"\"}]);AC.init(\"\",[{prop:\"Inst\",name:\"Inst\",embedded:false,exported:true,typ:CG,tag:\"\"},{prop:\"Start\",name:\"Start\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"NumCap\",name:\"NumCap\",embedded:false,exported:true,typ:$Int,tag:\"\"}]);AD.init(\"\",[{prop:\"Inst\",name:\"Inst\",embedded:true,exported:true,typ:A.Inst,tag:\"\"},{prop:\"Next\",name:\"Next\",embedded:false,exported:true,typ:BT,tag:\"\"}]);AH.init(\"regexp\",[{prop:\"sparse\",name:\"sparse\",embedded:false,exported:false,typ:BT,tag:\"\"},{prop:\"dense\",name:\"dense\",embedded:false,exported:false,typ:BT,tag:\"\"},{prop:\"size\",name:\"size\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"nextIndex\",name:\"nextIndex\",embedded:false,exported:false,typ:$Uint32,tag:\"\"}]);AO.init($Int32);AT.init(\"regexp\",[{prop:\"expr\",name:\"expr\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"prog\",name:\"prog\",embedded:false,exported:false,typ:CM,tag:\"\"},{prop:\"onepass\",name:\"onepass\",embedded:false,exported:false,typ:CD,tag:\"\"},{prop:\"numSubexp\",name:\"numSubexp\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"maxBitStateLen\",name:\"maxBitStateLen\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"subexpNames\",name:\"subexpNames\",embedded:false,exported:false,typ:CN,tag:\"\"},{prop:\"prefix\",name:\"prefix\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"prefixBytes\",name:\"prefixBytes\",embedded:false,exported:false,typ:BX,tag:\"\"},{prop:\"prefixRune\",name:\"prefixRune\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"prefixEnd\",name:\"prefixEnd\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"mpool\",name:\"mpool\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"matchcap\",name:\"matchcap\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"prefixComplete\",name:\"prefixComplete\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"cond\",name:\"cond\",embedded:false,exported:false,typ:A.EmptyOp,tag:\"\"},{prop:\"longest\",name:\"longest\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);BC.init([{prop:\"canCheckPrefix\",name:\"canCheckPrefix\",pkg:\"regexp\",typ:$funcType([],[$Bool],false)},{prop:\"context\",name:\"context\",pkg:\"regexp\",typ:$funcType([$Int],[V],false)},{prop:\"hasPrefix\",name:\"hasPrefix\",pkg:\"regexp\",typ:$funcType([CL],[$Bool],false)},{prop:\"index\",name:\"index\",pkg:\"regexp\",typ:$funcType([CL,$Int],[$Int],false)},{prop:\"step\",name:\"step\",pkg:\"regexp\",typ:$funcType([$Int],[$Int32,$Int],false)}]);BD.init(\"regexp\",[{prop:\"str\",name:\"str\",embedded:false,exported:false,typ:$String,tag:\"\"}]);BE.init(\"regexp\",[{prop:\"str\",name:\"str\",embedded:false,exported:false,typ:BX,tag:\"\"}]);BF.init(\"regexp\",[{prop:\"r\",name:\"r\",embedded:false,exported:false,typ:C.RuneReader,tag:\"\"},{prop:\"atEOT\",name:\"atEOT\",embedded:false,exported:false,typ:$Bool,tag:\"\"},{prop:\"pos\",name:\"pos\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=G.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=I.$init();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}L=new B.Pool.ptr(BO.nil,$throwNilPointerError);Y=new B.Pool.ptr(BO.nil,$throwNilPointerError);AB=BP.zero();AY=BQ.zero();BJ=BR.zero();AJ=new BS([]);AK=new BT([4294967295]);AP=new BS([0,9,11,1114111]);AQ=new BS([0,1114111]);AX=$toNativeArray($kindInt,[128,512,2048,16384,0]);BL();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\"]=(function(){var $pkg={},$init,F,A,I,G,B,D,C,J,E,H,K,L,M,N,O,Q,R,V,AF,AP,AT,AU,AW,AY,AZ,BA,BB,BC,BD,BE,BF,BG,X,AA,AB,AC,AG,AQ,AR,AV,a,W,Y,Z,AD,AE,AH,AI,AL,AM,AS;F=$packages[\"bytes\"];A=$packages[\"encoding/binary\"];I=$packages[\"errors\"];G=$packages[\"fmt\"];B=$packages[\"io\"];D=$packages[\"math\"];C=$packages[\"reflect\"];J=$packages[\"regexp\"];E=$packages[\"strconv\"];H=$packages[\"strings\"];K=$packages[\"sync\"];L=$pkg.byteWriter=$newType(0,$kindStruct,\"struc.byteWriter\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",false,function(buf_,pos_){this.$val=this;if(arguments.length===0){this.buf=AW.nil;this.pos=0;return;}this.buf=buf_;this.pos=pos_;});M=$pkg.binaryFallback=$newType(0,$kindStruct,\"struc.binaryFallback\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",false,function(typ_,ptr_,flag_){this.$val=this;if(arguments.length===0){this.typ=BB.nil;this.ptr=0;this.flag=0;return;}this.typ=typ_;this.ptr=ptr_;this.flag=flag_;});N=$pkg.Custom=$newType(8,$kindInterface,\"struc.Custom\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,null);O=$pkg.customFallback=$newType(0,$kindStruct,\"struc.customFallback\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",false,function(custom_){this.$val=this;if(arguments.length===0){this.custom=$ifaceNil;return;}this.custom=custom_;});Q=$pkg.Field=$newType(0,$kindStruct,\"struc.Field\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,function(Name_,Ptr_,Index_,Type_,defType_,Array_,Slice_,Len_,Order_,Sizeof_,Sizefrom_,Fields_,kind_){this.$val=this;if(arguments.length===0){this.Name=\"\";this.Ptr=false;this.Index=0;this.Type=0;this.defType=0;this.Array=false;this.Slice=false;this.Len=0;this.Order=$ifaceNil;this.Sizeof=AZ.nil;this.Sizefrom=AZ.nil;this.Fields=R.nil;this.kind=0;return;}this.Name=Name_;this.Ptr=Ptr_;this.Index=Index_;this.Type=Type_;this.defType=defType_;this.Array=Array_;this.Slice=Slice_;this.Len=Len_;this.Order=Order_;this.Sizeof=Sizeof_;this.Sizefrom=Sizefrom_;this.Fields=Fields_;this.kind=kind_;});R=$pkg.Fields=$newType(12,$kindSlice,\"struc.Fields\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,null);V=$pkg.strucTag=$newType(0,$kindStruct,\"struc.strucTag\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",false,function(Type_,Order_,Sizeof_,Skip_,Sizefrom_){this.$val=this;if(arguments.length===0){this.Type=\"\";this.Order=$ifaceNil;this.Sizeof=\"\";this.Skip=false;this.Sizefrom=\"\";return;}this.Type=Type_;this.Order=Order_;this.Sizeof=Sizeof_;this.Skip=Skip_;this.Sizefrom=Sizefrom_;});AF=$pkg.Options=$newType(0,$kindStruct,\"struc.Options\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,function(ByteAlign_,PtrSize_,Order_){this.$val=this;if(arguments.length===0){this.ByteAlign=0;this.PtrSize=0;this.Order=$ifaceNil;return;}this.ByteAlign=ByteAlign_;this.PtrSize=PtrSize_;this.Order=Order_;});AP=$pkg.Type=$newType(4,$kindInt,\"struc.Type\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,null);AT=$pkg.Size_t=$newType(8,$kindUint64,\"struc.Size_t\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,null);AU=$pkg.Off_t=$newType(8,$kindInt64,\"struc.Off_t\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",true,null);AW=$sliceType($Uint8);AY=$sliceType($emptyInterface);AZ=$sliceType($Int);BA=$sliceType(C.Value);BB=$ptrType(C.rtype);BC=$ptrType(Q);BD=$sliceType($String);BE=$arrayType($Uint8,8);BF=$ptrType(V);BG=$ptrType(AF);L.ptr.prototype.Write=function(b){var b,c,d;c=this;d=c.buf.$length-c.pos>>0;if(d<b.$length){b=$subslice(b,0,d);}if(b.$length>0){$copySlice($subslice(c.buf,c.pos),b);c.pos=c.pos+(b.$length)>>0;}return[b.$length,$ifaceNil];};L.prototype.Write=function(b){return this.$val.Write(b);};M.ptr.prototype.String=function(){var b;b=this;return $clone(b,M).String();};M.prototype.String=function(){return this.$val.String();};M.ptr.prototype.Sizeof=function(b,c){var b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=$clone(b,C.Value).Interface();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=A.Size(e);$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Sizeof};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Sizeof=function(b,c){return this.$val.Sizeof(b,c);};M.ptr.prototype.Pack=function(b,c,d){var b,c,d,e,f,g,h,i,j,k,l,m,n,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=new L.ptr(b,0);h=(g=A.BigEndian,new g.constructor.elem(g));if(!($interfaceIsEqual(d.Order,$ifaceNil))){h=d.Order;}i=new f.constructor.elem(f);j=h;k=$clone(c,C.Value).Interface();$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}l=k;m=A.Write(i,j,l);$s=2;case 2:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=m;$s=-1;return[f.pos,n];}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Pack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Pack=function(b,c,d){return this.$val.Pack(b,c,d);};M.ptr.prototype.Unpack=function(b,c,d){var b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;g=(f=A.BigEndian,new f.constructor.elem(f));if(!($interfaceIsEqual(d.Order,$ifaceNil))){g=d.Order;}h=b;i=g;j=$clone(c,C.Value).Interface();$s=1;case 1:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j;l=A.Read(h,i,k);$s=2;case 2:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}$s=-1;return l;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Unpack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Unpack=function(b,c,d){return this.$val.Unpack(b,c,d);};O.ptr.prototype.Pack=function(b,c,d){var b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=e.custom.Pack(b,d);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.Pack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.Pack=function(b,c,d){return this.$val.Pack(b,c,d);};O.ptr.prototype.Unpack=function(b,c,d){var b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;f=e.custom.Unpack(b,1,d);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.Unpack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.Unpack=function(b,c,d){return this.$val.Unpack(b,c,d);};O.ptr.prototype.Sizeof=function(b,c){var b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=d.custom.Size(c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.Sizeof};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.Sizeof=function(b,c){return this.$val.Sizeof(b,c);};O.ptr.prototype.String=function(){var b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.custom.String();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:O.ptr.prototype.String};}$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};O.prototype.String=function(){return this.$val.String();};Q.ptr.prototype.String=function(){var b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=\"\";if(b.Type===1){$s=1;continue;}$s=2;continue;case 1:d=G.Sprintf(\"{type: Pad, len: %d}\",new AY([new $Int(b.Len)]));$s=4;case 4:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;case 2:e=G.Sprintf(\"type: %s, order: %v\",new AY([new $String(new AP(b.Type).String()),b.Order]));$s=5;case 5:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}c=e;case 3:if(!(b.Sizefrom===AZ.nil)){$s=6;continue;}if(b.Len>0){$s=7;continue;}$s=8;continue;case 6:f=G.Sprintf(\", sizefrom: %v\",new AY([b.Sizefrom]));$s=9;case 9:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}c=c+(f);$s=8;continue;case 7:g=G.Sprintf(\", len: %d\",new AY([new $Int(b.Len)]));$s=10;case 10:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}c=c+(g);case 8:if(!(b.Sizeof===AZ.nil)){$s=11;continue;}$s=12;continue;case 11:h=G.Sprintf(\", sizeof: %v\",new AY([b.Sizeof]));$s=13;case 13:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}c=c+(h);case 12:$s=-1;return\"{\"+c+\"}\";}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.String};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.String=function(){return this.$val.String();};Q.ptr.prototype.Size=function(b,c){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=new AP(d.Type).Resolve(c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;g=0;if(f===15){$s=2;continue;}if(f===1){$s=3;continue;}if(d.Slice||(d.kind===24)){$s=4;continue;}if(f===19){$s=5;continue;}$s=6;continue;case 2:h=new BA([$clone(b,C.Value)]);if(d.Slice){$s=8;continue;}$s=9;continue;case 8:h=$makeSlice(BA,$clone(b,C.Value).Len());i=0;case 10:if(!(i<$clone(b,C.Value).Len())){$s=11;continue;}j=$clone(b,C.Value).Index(i);$s=12;case 12:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=j);i=i+(1)>>0;$s=10;continue;case 11:case 9:k=h;l=0;case 13:if(!(l<k.$length)){$s=14;continue;}m=((l<0||l>=k.$length)?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+l]);n=d.Fields.Sizeof($clone(m,C.Value),c);$s=15;case 15:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}g=g+(n)>>0;l++;$s=13;continue;case 14:$s=7;continue;case 3:g=d.Len;$s=7;continue;case 4:o=$clone(b,C.Value).Len();if(d.Len>1){o=d.Len;}g=$imul(o,new AP(f).Size());$s=7;continue;case 5:p=$clone($clone(b,C.Value).Addr(),C.Value).Interface();$s=16;case 16:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=$assertType(p,N).Size(c);$s=17;case 17:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}$s=-1;return q;case 6:g=new AP(f).Size();case 7:r=c.ByteAlign;if(r>0&&g<r){g=r;}$s=-1;return g;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.Size};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.Size=function(b,c){return this.$val.Size(b,c);};Q.ptr.prototype.packVal=function(b,c,d,e){var aa,ab,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=0;g=$ifaceNil;h=this;i=h.Order;if(!($interfaceIsEqual(e.Order,$ifaceNil))){i=e.Order;}if(h.Ptr){$s=1;continue;}$s=2;continue;case 1:j=$clone(c,C.Value).Elem();$s=3;case 3:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}c=j;case 2:k=new AP(h.Type).Resolve(e);$s=4;case 4:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}l=k;m=l;if(m===(15)){$s=6;continue;}if((m===(2))||(m===(4))||(m===(6))||(m===(8))||(m===(10))||(m===(5))||(m===(7))||(m===(9))||(m===(11))){$s=7;continue;}if((m===(12))||(m===(13))){$s=8;continue;}if(m===(14)){$s=9;continue;}if(m===(19)){$s=10;continue;}$s=11;continue;case 6:o=h.Fields.Pack(b,$clone(c,C.Value),e);$s=13;case 13:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;f=n[0];g=n[1];$s=-1;return[f,g];case 7:f=new AP(l).Size();p=new $Uint64(0,0);q=h.kind;if(q===(1)){if($clone(c,C.Value).Bool()){p=new $Uint64(0,1);}else{p=new $Uint64(0,0);}}else if((q===(2))||(q===(3))||(q===(4))||(q===(5))||(q===(6))){p=((r=$clone(c,C.Value).Int(),new $Uint64(r.$high,r.$low)));}else{p=$clone(c,C.Value).Uint();}s=l;if(s===(2)){$s=15;continue;}if((s===(4))||(s===(5))){$s=16;continue;}if((s===(6))||(s===(7))){$s=17;continue;}if((s===(8))||(s===(9))){$s=18;continue;}if((s===(10))||(s===(11))){$s=19;continue;}$s=20;continue;case 15:if(!((p.$high===0&&p.$low===0))){(0>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+0]=1);}else{(0>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+0]=0);}$s=20;continue;case 16:(0>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+0]=((p.$low<<24>>>24)));$s=20;continue;case 17:$r=i.PutUint16(b,((p.$low<<16>>>16)));$s=21;case 21:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=20;continue;case 18:$r=i.PutUint32(b,((p.$low>>>0)));$s=22;case 22:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=20;continue;case 19:$r=i.PutUint64(b,(p));$s=23;case 23:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 20:case 14:$s=12;continue;case 8:f=new AP(l).Size();t=$clone(c,C.Value).Float();u=l;if(u===(12)){$s=25;continue;}if(u===(13)){$s=26;continue;}$s=27;continue;case 25:$r=i.PutUint32(b,D.Float32bits(($fround(t))));$s=28;case 28:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=27;continue;case 26:$r=i.PutUint64(b,D.Float64bits(t));$s=29;case 29:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 27:case 24:$s=12;continue;case 9:v=h.kind;if(v===(24)){$s=31;continue;}$s=32;continue;case 31:f=$clone(c,C.Value).Len();w=$clone(c,C.Value).String();$s=34;case 34:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}$copySlice(b,(new AW($stringToBytes(w))));$s=33;continue;case 32:f=$clone(c,C.Value).Len();x=$clone(c,C.Value).Bytes();$s=35;case 35:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}$copySlice(b,x);case 33:case 30:$s=12;continue;case 10:z=$clone($clone(c,C.Value).Addr(),C.Value).Interface();$s=36;case 36:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}aa=$assertType(z,N).Pack(b,e);$s=37;case 37:if($c){$c=false;aa=aa.$blk();}if(aa&&aa.$blk!==undefined){break s;}y=aa;f=y[0];g=y[1];$s=-1;return[f,g];case 11:ab=G.Sprintf(\"no pack handler for type: %s\",new AY([new AP(l)]));$s=38;case 38:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}$panic(new $String(ab));case 12:case 5:$s=-1;return[f,g];}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.packVal};}$f.aa=aa;$f.ab=ab;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.packVal=function(b,c,d,e){return this.$val.packVal(b,c,d,e);};Q.ptr.prototype.Pack=function(b,c,d,e){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=this;g=new AP(f.Type).Resolve(e);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;if(h===1){i=0;while(true){if(!(i<d)){break;}((i<0||i>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+i]=0);i=i+(1)>>0;}$s=-1;return[d,$ifaceNil];}if(f.Slice){$s=2;continue;}$s=3;continue;case 2:j=$clone(c,C.Value).Len();if(!f.Array&&(h===5)&&((f.defType===5)||(f.kind===24))){$s=5;continue;}$s=6;continue;case 5:k=AW.nil;if(f.kind===24){$s=7;continue;}$s=8;continue;case 7:l=$clone(c,C.Value).String();$s=10;case 10:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}k=(new AW($stringToBytes(l)));$s=9;continue;case 8:m=$clone(c,C.Value).Bytes();$s=11;case 11:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}k=m;case 9:$copySlice(b,k);if(j<d){n=F.Repeat(new AW([0]),d-j>>0);$copySlice($subslice(b,j),n);$s=-1;return[d,$ifaceNil];}$s=-1;return[$clone(c,C.Value).Len(),$ifaceNil];case 6:o=0;p=new C.Value.ptr(BB.nil,0,0);if(j<d){$s=12;continue;}$s=13;continue;case 12:q=$clone(c,C.Value).Type().Elem();$s=14;case 14:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=C.Zero(q);$s=15;case 15:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}p=r;case 13:s=0;case 16:if(!(s<d)){$s=17;continue;}t=p;if(s<j){$s=18;continue;}$s=19;continue;case 18:u=$clone(c,C.Value).Index(s);$s=20;case 20:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}t=u;case 19:w=f.packVal($subslice(b,o),$clone(t,C.Value),1,e);$s=21;case 21:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}v=w;x=v[0];y=v[1];if(!($interfaceIsEqual(y,$ifaceNil))){$s=-1;return[o,y];}else{o=o+(x)>>0;}s=s+(1)>>0;$s=16;continue;case 17:$s=-1;return[o,$ifaceNil];case 3:z=f.packVal(b,$clone(c,C.Value),d,e);$s=22;case 22:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}$s=-1;return z;case 4:$s=-1;return[0,$ifaceNil];}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.Pack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.Pack=function(b,c,d,e){return this.$val.Pack(b,c,d,e);};Q.ptr.prototype.unpackVal=function(b,c,d,e){var aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=this;g=f.Order;if(!($interfaceIsEqual(e.Order,$ifaceNil))){g=e.Order;}if(f.Ptr){$s=1;continue;}$s=2;continue;case 1:h=$clone(c,C.Value).Elem();$s=3;case 3:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}c=h;case 2:i=new AP(f.Type).Resolve(e);$s=4;case 4:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}j=i;k=j;if((k===(12))||(k===(13))){$s=6;continue;}if((k===(2))||(k===(4))||(k===(6))||(k===(8))||(k===(10))||(k===(5))||(k===(7))||(k===(9))||(k===(11))){$s=7;continue;}$s=8;continue;case 6:l=0;m=j;if(m===(12)){$s=11;continue;}if(m===(13)){$s=12;continue;}$s=13;continue;case 11:n=g.Uint32(b);$s=14;case 14:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=D.Float32frombits(n);$s=15;case 15:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}l=(o);$s=13;continue;case 12:p=g.Uint64(b);$s=16;case 16:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=D.Float64frombits(p);$s=17;case 17:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}l=q;case 13:case 10:r=f.kind;if((r===(13))||(r===(14))){$s=19;continue;}$s=20;continue;case 19:$clone(c,C.Value).SetFloat(l);$s=21;continue;case 20:s=G.Errorf(\"struc: refusing to unpack float into field %s of type %s\",new AY([new $String(f.Name),new $String(new C.Kind(f.kind).String())]));$s=22;case 22:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}$s=-1;return s;case 21:case 18:$s=9;continue;case 7:t=new $Uint64(0,0);u=j;if(u===(4)){$s=24;continue;}if(u===(6)){$s=25;continue;}if(u===(8)){$s=26;continue;}if(u===(10)){$s=27;continue;}if((u===(2))||(u===(5))){$s=28;continue;}if(u===(7)){$s=29;continue;}if(u===(9)){$s=30;continue;}if(u===(11)){$s=31;continue;}$s=32;continue;case 24:t=((v=(new $Int64(0,(((0>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+0])<<24>>24)))),new $Uint64(v.$high,v.$low)));$s=32;continue;case 25:x=g.Uint16(b);$s=33;case 33:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}t=((w=(new $Int64(0,((x<<16>>16)))),new $Uint64(w.$high,w.$low)));$s=32;continue;case 26:z=g.Uint32(b);$s=34;case 34:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}t=((y=(new $Int64(0,((z>>0)))),new $Uint64(y.$high,y.$low)));$s=32;continue;case 27:ac=g.Uint64(b);$s=35;case 35:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}t=((aa=((ab=ac,new $Int64(ab.$high,ab.$low))),new $Uint64(aa.$high,aa.$low)));$s=32;continue;case 28:t=(new $Uint64(0,(0>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+0])));$s=32;continue;case 29:ad=g.Uint16(b);$s=36;case 36:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}t=(new $Uint64(0,ad));$s=32;continue;case 30:ae=g.Uint32(b);$s=37;case 37:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}t=(new $Uint64(0,ae));$s=32;continue;case 31:af=g.Uint64(b);$s=38;case 38:if($c){$c=false;af=af.$blk();}if(af&&af.$blk!==undefined){break s;}t=(af);case 32:case 23:ag=f.kind;if(ag===(1)){$clone(c,C.Value).SetBool(!((t.$high===0&&t.$low===0)));}else if((ag===(2))||(ag===(3))||(ag===(4))||(ag===(5))||(ag===(6))){$clone(c,C.Value).SetInt((new $Int64(t.$high,t.$low)));}else{$clone(c,C.Value).SetUint(t);}$s=9;continue;case 8:ah=G.Sprintf(\"no unpack handler for type: %s\",new AY([new AP(j)]));$s=39;case 39:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}$panic(new $String(ah));case 9:case 5:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.unpackVal};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.unpackVal=function(b,c,d,e){return this.$val.unpackVal(b,c,d,e);};Q.ptr.prototype.Unpack=function(b,c,d,e){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:f=this;g=new AP(f.Type).Resolve(e);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;if((h===1)||(f.kind===24)){$s=2;continue;}if(f.Slice){$s=3;continue;}$s=4;continue;case 2:if(h===1){$s=-1;return $ifaceNil;}else{$clone(c,C.Value).SetString(($bytesToString(b)));$s=-1;return $ifaceNil;}$s=5;continue;case 3:if($clone(c,C.Value).Cap()<d){$s=6;continue;}if($clone(c,C.Value).Len()<d){$s=7;continue;}$s=8;continue;case 6:i=C.MakeSlice($clone(c,C.Value).Type(),d,d);$s=9;case 9:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}$r=$clone(c,C.Value).Set($clone(i,C.Value));$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=8;continue;case 7:j=$clone(c,C.Value).Slice(0,d);$s=11;case 11:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}$r=$clone(c,C.Value).Set($clone(j,C.Value));$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 8:if(!f.Array&&(h===5)&&(f.defType===5)){$s=13;continue;}$s=14;continue;case 13:k=$clone(c,C.Value).Bytes();$s=15;case 15:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}$copySlice(k,$subslice(b,0,d));$s=-1;return $ifaceNil;case 14:l=0;m=new AP(h).Size();n=0;case 16:if(!(n<d)){$s=17;continue;}o=$subslice(b,l,(l+m>>0));p=$clone(c,C.Value).Index(n);$s=18;case 18:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=$clone(p,C.Value);r=e;s=f.unpackVal(o,q,1,r);$s=19;case 19:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}t=s;if(!($interfaceIsEqual(t,$ifaceNil))){$s=-1;return t;}l=l+(m)>>0;n=n+(1)>>0;$s=16;continue;case 17:$s=-1;return $ifaceNil;case 4:u=f.unpackVal(b,$clone(c,C.Value),d,e);$s=20;case 20:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}$s=-1;return u;case 5:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:Q.ptr.prototype.Unpack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};Q.prototype.Unpack=function(b,c,d,e){return this.$val.Unpack(b,c,d,e);};R.prototype.SetByteOrder=function(b){var b,c,d,e,f;c=this;d=c;e=0;while(true){if(!(e<d.$length)){break;}f=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);if(!(f===BC.nil)){f.Order=b;}e++;}};$ptrType(R).prototype.SetByteOrder=function(b){return this.$get().SetByteOrder(b);};R.prototype.String=function(){var b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=$makeSlice(BD,b.$length);d=b;e=0;case 1:if(!(e<d.$length)){$s=2;continue;}f=e;g=((e<0||e>=d.$length)?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+e]);if(!(g===BC.nil)){$s=3;continue;}$s=4;continue;case 3:h=g.String();$s=5;case 5:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=h);case 4:e++;$s=1;continue;case 2:$s=-1;return\"{\"+H.Join(c,\", \")+\"}\";}return;}if($f===undefined){$f={$blk:R.prototype.String};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(R).prototype.String=function(){return this.$get().String();};R.prototype.Sizeof=function(b,c){var b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;case 1:if(!($clone(b,C.Value).Kind()===22)){$s=2;continue;}e=$clone(b,C.Value).Elem();$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}b=e;$s=1;continue;case 2:f=0;g=d;h=0;case 4:if(!(h<g.$length)){$s=5;continue;}i=h;j=((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h]);if(!(j===BC.nil)){$s=6;continue;}$s=7;continue;case 6:k=$clone(b,C.Value).Field(i);$s=8;case 8:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}l=j.Size($clone(k,C.Value),c);$s=9;case 9:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}f=f+(l)>>0;case 7:h++;$s=4;continue;case 5:$s=-1;return f;}return;}if($f===undefined){$f={$blk:R.prototype.Sizeof};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(R).prototype.Sizeof=function(b,c){return this.$get().Sizeof(b,c);};R.prototype.sizefrom=function(b,c){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=$clone(b,C.Value).FieldByIndex(c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;g=$clone(f,C.Value).Kind();if((g===(2))||(g===(3))||(g===(4))||(g===(5))||(g===(6))){$s=3;continue;}if((g===(7))||(g===(8))||(g===(9))||(g===(10))||(g===(11))){$s=4;continue;}$s=5;continue;case 3:$s=-1;return(((h=$clone(f,C.Value).Int(),h.$low+((h.$high>>31)*4294967296))>>0));case 4:i=(($clone(f,C.Value).Uint().$low>>0));if(i<0){$s=-1;return 0;}$s=-1;return i;case 5:j=$clone(b,C.Value).Type().FieldByIndex(c);$s=7;case 7:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j.Name;l=$clone(b,C.Value).Interface();$s=8;case 8:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}m=l;n=new $String(k);o=G.Sprintf(\"sizeof field %T.%s not an integer type\",new AY([m,n]));$s=9;case 9:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}$panic(new $String(o));case 6:case 2:$s=-1;return 0;}return;}if($f===undefined){$f={$blk:R.prototype.sizefrom};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(R).prototype.sizefrom=function(b,c){return this.$get().sizefrom(b,c);};R.prototype.Pack=function(b,c,d){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;case 1:if(!($clone(c,C.Value).Kind()===22)){$s=2;continue;}f=$clone(c,C.Value).Elem();$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}c=f;$s=1;continue;case 2:g=0;h=e;i=0;case 4:if(!(i<h.$length)){$s=5;continue;}j=i;k=((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]);if(k===BC.nil){$s=6;continue;}$s=7;continue;case 6:i++;$s=4;continue;case 7:l=$clone(c,C.Value).Field(j);$s=8;case 8:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}m=l;n=k.Len;if(!(k.Sizefrom===AZ.nil)){$s=9;continue;}$s=10;continue;case 9:o=e.sizefrom($clone(c,C.Value),k.Sizefrom);$s=11;case 11:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;case 10:if(n<=0&&k.Slice){n=$clone(m,C.Value).Len();}if(!(k.Sizeof===AZ.nil)){$s=12;continue;}$s=13;continue;case 12:p=$clone(c,C.Value).FieldByIndex(k.Sizeof);$s=14;case 14:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=$clone(p,C.Value).Len();$s=15;case 15:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}r=q;s=k.kind;if((s===(2))||(s===(3))||(s===(4))||(s===(5))||(s===(6))){$s=17;continue;}if((s===(7))||(s===(8))||(s===(9))||(s===(10))||(s===(11))){$s=18;continue;}$s=19;continue;case 17:t=$clone(C.New($clone(m,C.Value).Type()),C.Value).Elem();$s=21;case 21:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}m=t;$clone(m,C.Value).SetInt((new $Int64(0,r)));$s=20;continue;case 18:u=$clone(C.New($clone(m,C.Value).Type()),C.Value).Elem();$s=22;case 22:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}m=u;$clone(m,C.Value).SetUint((new $Uint64(0,r)));$s=20;continue;case 19:v=G.Sprintf(\"sizeof field is not int or uint type: %s, %s\",new AY([new $String(k.Name),$clone(m,C.Value).Type()]));$s=23;case 23:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}$panic(new $String(v));case 20:case 16:case 13:x=k.Pack($subslice(b,g),$clone(m,C.Value),n,d);$s=24;case 24:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}w=x;y=w[0];z=w[1];if(!($interfaceIsEqual(z,$ifaceNil))){$s=-1;return[y,z];}else{g=g+(y)>>0;}i++;$s=4;continue;case 5:$s=-1;return[g,$ifaceNil];}return;}if($f===undefined){$f={$blk:R.prototype.Pack};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(R).prototype.Pack=function(b,c,d){return this.$get().Pack(b,c,d);};R.prototype.Unpack=function(b,c,d){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,ao,ap,aq,ar,as,at,au,av,aw,ax,ay,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;ao=$f.ao;ap=$f.ap;aq=$f.aq;ar=$f.ar;as=$f.as;at=$f.at;au=$f.au;av=$f.av;aw=$f.aw;ax=$f.ax;ay=$f.ay;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;case 1:if(!($clone(c,C.Value).Kind()===22)){$s=2;continue;}f=$clone(c,C.Value).Elem();$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}c=f;$s=1;continue;case 2:g=BE.zero();h=AW.nil;i=e;j=0;case 4:if(!(j<i.$length)){$s=5;continue;}k=j;l=((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]);if(l===BC.nil){$s=6;continue;}$s=7;continue;case 6:j++;$s=4;continue;case 7:m=$clone(c,C.Value).Field(k);$s=8;case 8:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=m;o=l.Len;if(!(l.Sizefrom===AZ.nil)){$s=9;continue;}$s=10;continue;case 9:p=e.sizefrom($clone(c,C.Value),l.Sizefrom);$s=11;case 11:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}o=p;case 10:if(!($clone(n,C.Value).Kind()===22)){q=false;$s=14;continue s;}r=$clone(n,C.Value).Elem();$s=15;case 15:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}s=$clone(r,C.Value).IsValid();$s=16;case 16:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}q=!s;case 14:if(q){$s=12;continue;}$s=13;continue;case 12:t=$clone(n,C.Value).Type().Elem();$s=17;case 17:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}u=C.New(t);$s=18;case 18:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}$r=$clone(n,C.Value).Set($clone(u,C.Value));$s=19;case 19:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 13:if(l.Type===15){$s=20;continue;}$s=21;continue;case 20:if(l.Slice){$s=23;continue;}$s=24;continue;case 23:v=n;if(!l.Array){$s=26;continue;}$s=27;continue;case 26:w=C.MakeSlice($clone(n,C.Value).Type(),o,o);$s=28;case 28:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}v=w;case 27:x=0;case 29:if(!(x<o)){$s=30;continue;}y=$clone(v,C.Value).Index(x);$s=31;case 31:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}z=y;ab=AE($clone(z,C.Value));$s=32;case 32:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=ab;ac=aa[0];ad=aa[1];if(!($interfaceIsEqual(ad,$ifaceNil))){$s=-1;return ad;}ae=ac.Unpack(b,$clone(z,C.Value),d);$s=33;case 33:if($c){$c=false;ae=ae.$blk();}if(ae&&ae.$blk!==undefined){break s;}af=ae;if(!($interfaceIsEqual(af,$ifaceNil))){$s=-1;return af;}x=x+(1)>>0;$s=29;continue;case 30:if(!l.Array){$s=34;continue;}$s=35;continue;case 34:$r=$clone(n,C.Value).Set($clone(v,C.Value));$s=36;case 36:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 35:$s=25;continue;case 24:ah=AE($clone(n,C.Value));$s=37;case 37:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ag=ah;ai=ag[0];aj=ag[1];if(!($interfaceIsEqual(aj,$ifaceNil))){$s=-1;return aj;}ak=ai.Unpack(b,$clone(n,C.Value),d);$s=38;case 38:if($c){$c=false;ak=ak.$blk();}if(ak&&ak.$blk!==undefined){break s;}al=ak;if(!($interfaceIsEqual(al,$ifaceNil))){$s=-1;return al;}case 25:j++;$s=4;continue;$s=22;continue;case 21:am=new AP(l.Type).Resolve(d);$s=39;case 39:if($c){$c=false;am=am.$blk();}if(am&&am.$blk!==undefined){break s;}an=am;if(an===19){$s=40;continue;}$s=41;continue;case 40:ao=$clone($clone(n,C.Value).Addr(),C.Value).Interface();$s=43;case 43:if($c){$c=false;ao=ao.$blk();}if(ao&&ao.$blk!==undefined){break s;}ap=$assertType(ao,N).Unpack(b,o,d);$s=44;case 44:if($c){$c=false;ap=ap.$blk();}if(ap&&ap.$blk!==undefined){break s;}aq=ap;if(!($interfaceIsEqual(aq,$ifaceNil))){$s=-1;return aq;}$s=42;continue;case 41:ar=new AP(l.Type).Resolve(d);$s=45;case 45:if($c){$c=false;ar=ar.$blk();}if(ar&&ar.$blk!==undefined){break s;}as=new AP(ar).Size();$s=46;case 46:if($c){$c=false;as=as.$blk();}if(as&&as.$blk!==undefined){break s;}at=$imul(o,as);if(at<8){h=$subslice(new AW(g),0,at);}else{h=$makeSlice(AW,at);}av=B.ReadFull(b,h);$s=47;case 47:if($c){$c=false;av=av.$blk();}if(av&&av.$blk!==undefined){break s;}au=av;aw=au[1];if(!($interfaceIsEqual(aw,$ifaceNil))){$s=-1;return aw;}ax=l.Unpack($subslice(h,0,at),$clone(n,C.Value),o,d);$s=48;case 48:if($c){$c=false;ax=ax.$blk();}if(ax&&ax.$blk!==undefined){break s;}ay=ax;if(!($interfaceIsEqual(ay,$ifaceNil))){$s=-1;return ay;}case 42:case 22:j++;$s=4;continue;case 5:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:R.prototype.Unpack};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.ao=ao;$f.ap=ap;$f.aq=aq;$f.ar=ar;$f.as=as;$f.at=at;$f.au=au;$f.av=av;$f.aw=aw;$f.ax=ax;$f.ay=ay;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(R).prototype.Unpack=function(b,c,d){return this.$get().Unpack(b,c,d);};W=function(b){var b,c,d,e,f,g,h,i,j,k,l;d=new V.ptr(\"\",(c=A.BigEndian,new c.constructor.elem(c)),\"\",false,\"\");e=new C.StructTag(b).Get(\"struc\");if(e===\"\"){e=new C.StructTag(b).Get(\"struct\");}f=H.Split(e,\",\");g=0;while(true){if(!(g<f.$length)){break;}h=((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]);if(H.HasPrefix(h,\"sizeof=\")){i=H.SplitN(h,\"=\",2);d.Sizeof=(1>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+1]);}else if(H.HasPrefix(h,\"sizefrom=\")){j=H.SplitN(h,\"=\",2);d.Sizefrom=(1>=j.$length?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+1]);}else if(h===\"big\"){d.Order=(k=A.BigEndian,new k.constructor.elem(k));}else if(h===\"little\"){d.Order=(l=A.LittleEndian,new l.constructor.elem(l));}else if(h===\"skip\"){d.Skip=true;}else{d.Type=h;}g++;}return d;};Y=function(b){var aa,ab,ac,ad,ae,af,ag,ah,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=BC.nil;d=BF.nil;e=$ifaceNil;d=W(b.Tag);f=false;g=b.Type.Kind();$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}c=new Q.ptr(b.Name,false,0,0,0,false,false,1,d.Order,AZ.nil,AZ.nil,R.nil,g);h=c.kind;if(h===(17)){$s=3;continue;}if(h===(23)){$s=4;continue;}if(h===(22)){$s=5;continue;}$s=6;continue;case 3:c.Slice=true;c.Array=true;i=b.Type.Len();$s=7;case 7:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}c.Len=i;j=b.Type.Elem();$s=8;case 8:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=j.Kind();$s=9;case 9:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}c.kind=k;$s=6;continue;case 4:c.Slice=true;c.Len=-1;l=b.Type.Elem();$s=10;case 10:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}m=l.Kind();$s=11;case 11:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}c.kind=m;$s=6;continue;case 5:c.Ptr=true;n=b.Type.Elem();$s=12;case 12:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}o=n.Kind();$s=13;case 13:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}c.kind=o;case 6:case 2:p=C.New(b.Type);r=$clone(p,C.Value).Interface();$s=14;case 14:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}q=$assertType(r,N,true);s=q[1];if(s){c.Type=19;$s=-1;return[c,d,e];}t=false;u=(v=AV[C.Kind.keyFor(c.kind)],v!==undefined?[v.v,true]:[0,false]);c.defType=u[0];t=u[1];w=X.ReplaceAllLiteralString(d.Type,\"\");$s=15;case 15:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}x=w;y=(z=AQ[$String.keyFor(x)],z!==undefined?[z.v,true]:[0,false]);c.Type=y[0];f=y[1];if(f){$s=16;continue;}$s=17;continue;case 16:c.Len=1;aa=X.FindAllStringSubmatch(d.Type,-1);$s=18;case 18:if($c){$c=false;aa=aa.$blk();}if(aa&&aa.$blk!==undefined){break s;}ab=aa;if(ab.$length>0&&(0>=ab.$length?($throwRuntimeError(\"index out of range\"),undefined):ab.$array[ab.$offset+0]).$length>1){c.Slice=true;ad=(ac=(0>=ab.$length?($throwRuntimeError(\"index out of range\"),undefined):ab.$array[ab.$offset+0]),(1>=ac.$length?($throwRuntimeError(\"index out of range\"),undefined):ac.$array[ac.$offset+1]));if(ad===\"\"){c.Len=-1;}else{ae=E.Atoi(ad);c.Len=ae[0];e=ae[1];}}$s=-1;return[c,d,e];case 17:af=b.Type;if($interfaceIsEqual(af,(C.TypeOf(new AT(0,0))))){$s=20;continue;}if($interfaceIsEqual(af,(C.TypeOf(new AU(0,0))))){$s=21;continue;}if(t){$s=22;continue;}$s=23;continue;case 20:c.Type=17;$s=24;continue;case 21:c.Type=18;$s=24;continue;case 22:c.Type=c.defType;$s=24;continue;case 23:ag=G.Sprintf(\"struc: Could not resolve field '%v' type '%v'.\",new AY([new $String(b.Name),b.Type]));$s=25;case 25:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}ah=I.New(ag);$s=26;case 26:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}e=ah;case 24:case 19:$s=-1;return[c,d,e];}return;}if($f===undefined){$f={$blk:Y};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};Z=function(b){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:case 1:if(!($clone(b,C.Value).Kind()===22)){$s=2;continue;}c=$clone(b,C.Value).Elem();$s=3;case 3:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}b=c;$s=1;continue;case 2:d=$clone(b,C.Value).Type();if($clone(b,C.Value).NumField()<1){$s=-1;return[R.nil,I.New(\"struc: Struct has no fields.\")];}e={};f=$makeSlice(R,$clone(b,C.Value).NumField());g=0;case 4:h=d.NumField();$s=6;case 6:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if(!(g<h)){$s=5;continue;}i=d.Field(g);$s=7;case 7:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}j=$clone(i,C.StructField);l=Y($clone(j,C.StructField));$s=8;case 8:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}k=l;m=k[0];n=k[1];o=k[2];if(n.Skip){$s=9;continue;}$s=10;continue;case 9:g=g+(1)>>0;$s=4;continue;case 10:if(!($interfaceIsEqual(o,$ifaceNil))){$s=-1;return[R.nil,o];}p=$clone(b,C.Value).Field(g);$s=13;case 13:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=$clone(p,C.Value).CanSet();$s=14;case 14:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}if(!q){$s=11;continue;}$s=12;continue;case 11:g=g+(1)>>0;$s=4;continue;case 12:m.Index=g;if(!(n.Sizeof===\"\")){$s=15;continue;}$s=16;continue;case 15:s=d.FieldByName(n.Sizeof);$s=17;case 17:if($c){$c=false;s=s.$blk();}if(s&&s.$blk!==undefined){break s;}r=s;t=$clone(r[0],C.StructField);u=r[1];if(!u){$s=18;continue;}$s=19;continue;case 18:v=G.Errorf(\"struc: `sizeof=%s` field does not exist\",new AY([new $String(n.Sizeof)]));$s=20;case 20:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}$s=-1;return[R.nil,v];case 19:m.Sizeof=t.Index;w=n.Sizeof;(e||$throwRuntimeError(\"assignment to entry in nil map\"))[$String.keyFor(w)]={k:w,v:j.Index};case 16:x=(y=e[$String.keyFor(j.Name)],y!==undefined?[y.v,true]:[AZ.nil,false]);z=x[0];aa=x[1];if(aa){m.Sizefrom=z;}if(!(n.Sizefrom===\"\")){$s=21;continue;}$s=22;continue;case 21:ac=d.FieldByName(n.Sizefrom);$s=23;case 23:if($c){$c=false;ac=ac.$blk();}if(ac&&ac.$blk!==undefined){break s;}ab=ac;ad=$clone(ab[0],C.StructField);ae=ab[1];if(!ae){$s=24;continue;}$s=25;continue;case 24:af=G.Errorf(\"struc: `sizefrom=%s` field does not exist\",new AY([new $String(n.Sizefrom)]));$s=26;case 26:if($c){$c=false;af=af.$blk();}if(af&&af.$blk!==undefined){break s;}$s=-1;return[R.nil,af];case 25:m.Sizefrom=ad.Index;case 22:if((m.Len===-1)&&m.Sizefrom===AZ.nil){$s=27;continue;}$s=28;continue;case 27:ag=G.Errorf(\"struc: field `%s` is a slice with no length or sizeof field\",new AY([new $String(j.Name)]));$s=29;case 29:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}$s=-1;return[R.nil,ag];case 28:if(m.Type===15){$s=30;continue;}$s=31;continue;case 30:ah=j.Type;if(m.Ptr){$s=32;continue;}$s=33;continue;case 32:ai=ah.Elem();$s=34;case 34:if($c){$c=false;ai=ai.$blk();}if(ai&&ai.$blk!==undefined){break s;}ah=ai;case 33:if(m.Slice){$s=35;continue;}$s=36;continue;case 35:aj=ah.Elem();$s=37;case 37:if($c){$c=false;aj=aj.$blk();}if(aj&&aj.$blk!==undefined){break s;}ah=aj;case 36:al=Z($clone(C.New(ah),C.Value));$s=38;case 38:if($c){$c=false;al=al.$blk();}if(al&&al.$blk!==undefined){break s;}ak=al;m.Fields=ak[0];o=ak[1];if(!($interfaceIsEqual(o,$ifaceNil))){$s=-1;return[R.nil,o];}case 31:((g<0||g>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+g]=m);g=g+(1)>>0;$s=4;continue;case 5:$s=-1;return[f,$ifaceNil];}return;}if($f===undefined){$f={$blk:Z};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AD=function(b){var b,c,d,e,f,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);$r=AB.RLock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(AB,\"RUnlock\"),[]]);c=(d=AA[C.Type.keyFor(b)],d!==undefined?[d.v,true]:[R.nil,false]);e=c[0];f=c[1];if(f){$s=-1;return e;}$s=-1;return R.nil;}return;}}catch(err){$err=err;$s=-1;return R.nil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AD};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AE=function(b){var b,c,d,e,f,g,h,i,j,k,l,m,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);case 1:if(!($clone(b,C.Value).Kind()===22)){$s=2;continue;}c=$clone(b,C.Value).Elem();$s=3;case 3:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}b=c;$s=1;continue;case 2:d=$clone(b,C.Value).Type();e=AD(d);$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!(f===R.nil)){$s=-1;return[f,$ifaceNil];}$r=AC.Lock();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(AC,\"Unlock\"),[]]);g=AD(d);$s=6;case 6:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;if(!(h===R.nil)){$s=-1;return[h,$ifaceNil];}j=Z($clone(b,C.Value));$s=7;case 7:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;k=i[0];l=i[1];if(!($interfaceIsEqual(l,$ifaceNil))){$s=-1;return[R.nil,l];}$r=AB.Lock();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}m=d;(AA||$throwRuntimeError(\"assignment to entry in nil map\"))[C.Type.keyFor(m)]={k:m,v:k};$r=AB.Unlock();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return[k,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[R.nil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AE};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AF.ptr.prototype.Validate=function(){var b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(b.PtrSize===0){$s=1;continue;}$s=2;continue;case 1:b.PtrSize=32;$s=3;continue;case 2:c=b.PtrSize;if((c===(8))||(c===(16))||(c===(32))||(c===(64))){$s=5;continue;}$s=6;continue;case 5:$s=7;continue;case 6:d=G.Errorf(\"Invalid Options.PtrSize: %d. Must be in (8, 16, 32, 64)\",new AY([new $Int(b.PtrSize)]));$s=8;case 8:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;case 7:case 4:case 3:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.Validate};}$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.Validate=function(){return this.$val.Validate();};AH=function(){var b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=AG.Validate();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}b;$s=-1;return;}return;}if($f===undefined){$f={$blk:AH};}$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};AI=function(b){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=C.ValueOf(b);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;case 2:if(!($clone(d,C.Value).Kind()===22)){$s=3;continue;}e=$clone(d,C.Value).Elem();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=$clone(e,C.Value).Kind();$s=5;case 5:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;if((g===25)||(g===22)){$s=6;continue;}$s=7;continue;case 6:h=$clone(d,C.Value).Elem();$s=9;case 9:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}d=h;$s=8;continue;case 7:$s=3;continue;case 8:$s=2;continue;case 3:i=$clone(d,C.Value).Kind();if(i===(25)){$s=11;continue;}$s=12;continue;case 11:k=AE($clone(d,C.Value));$s=14;case 14:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[0];m=j[1];$s=-1;return[d,l,m];case 12:if(!$clone(d,C.Value).IsValid()){$s=15;continue;}$s=16;continue;case 15:n=G.Errorf(\"Invalid reflect.Value for %+v\",new AY([b]));$s=17;case 17:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}$s=-1;return[new C.Value.ptr(BB.nil,0,0),$ifaceNil,n];case 16:o=$assertType(b,N,true);p=o[0];q=o[1];if(q){$s=-1;return[d,(r=new O.ptr(p),new r.constructor.elem(r)),$ifaceNil];}$s=-1;return[d,(s=($clone(d,M)),new s.constructor.elem(s)),$ifaceNil];case 13:case 10:$s=-1;return[new C.Value.ptr(BB.nil,0,0),$ifaceNil,$ifaceNil];}return;}if($f===undefined){$f={$blk:AI};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};AL=function(b,c){var b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=AM(b,c,BG.nil);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return d;}return;}if($f===undefined){$f={$blk:AL};}$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Unpack=AL;AM=function(b,c,d){var b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(d===BG.nil){d=AG;}e=d.Validate();$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return f;}h=AI(c);$s=2;case 2:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;i=g[0];j=g[1];k=g[2];if(!($interfaceIsEqual(k,$ifaceNil))){$s=-1;return k;}l=j.Unpack(b,$clone(i,C.Value),d);$s=3;case 3:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}$s=-1;return l;}return;}if($f===undefined){$f={$blk:AM};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};$pkg.UnpackWithOptions=AM;AP.prototype.Resolve=function(b){var b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this.$val;d=c;if(d===(18)){$s=2;continue;}if(d===(17)){$s=3;continue;}$s=4;continue;case 2:e=b.PtrSize;if(e===(8)){$s=6;continue;}if(e===(16)){$s=7;continue;}if(e===(32)){$s=8;continue;}if(e===(64)){$s=9;continue;}$s=10;continue;case 6:$s=-1;return 4;case 7:$s=-1;return 6;case 8:$s=-1;return 8;case 9:$s=-1;return 10;case 10:f=G.Sprintf(\"unsupported ptr bits: %d\",new AY([new $Int(b.PtrSize)]));$s=12;case 12:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$panic(new $String(f));case 11:case 5:$s=4;continue;case 3:g=b.PtrSize;if(g===(8)){$s=14;continue;}if(g===(16)){$s=15;continue;}if(g===(32)){$s=16;continue;}if(g===(64)){$s=17;continue;}$s=18;continue;case 14:$s=-1;return 5;case 15:$s=-1;return 7;case 16:$s=-1;return 9;case 17:$s=-1;return 11;case 18:h=G.Sprintf(\"unsupported ptr bits: %d\",new AY([new $Int(b.PtrSize)]));$s=20;case 20:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}$panic(new $String(h));case 19:case 13:case 4:case 1:$s=-1;return c;}return;}if($f===undefined){$f={$blk:AP.prototype.Resolve};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(AP).prototype.Resolve=function(b){return new AP(this.$get()).Resolve(b);};AP.prototype.String=function(){var b,c;b=this.$val;return(c=AR[AP.keyFor(b)],c!==undefined?c.v:\"\");};$ptrType(AP).prototype.String=function(){return new AP(this.$get()).String();};AP.prototype.Size=function(){var b,c;b=this.$val;c=b;if((c===(17))||(c===(18))){$panic(new $String(\"Size_t/Off_t types must be converted to another type using options.PtrSize\"));}else if((c===(1))||(c===(14))||(c===(4))||(c===(5))||(c===(2))){return 1;}else if((c===(6))||(c===(7))){return 2;}else if((c===(8))||(c===(9))||(c===(12))){return 4;}else if((c===(10))||(c===(11))||(c===(13))){return 8;}else{$panic(new $String(\"Cannot resolve size of type:\"+new AP(b).String()));}};$ptrType(AP).prototype.Size=function(){return new AP(this.$get()).Size();};AS=function(){var b,c,d,e,f,g,h;b=AQ;c=0;d=$keys(b);while(true){if(!(c<d.length)){break;}e=b[d[c]];if(e===undefined){c++;continue;}f=e.k;g=e.v;h=g;(AR||$throwRuntimeError(\"assignment to entry in nil map\"))[AP.keyFor(h)]={k:h,v:f};c++;}};L.methods=[{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([AW],[$Int,$error],false)}];M.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Sizeof\",name:\"Sizeof\",pkg:\"\",typ:$funcType([C.Value,BG],[$Int],false)},{prop:\"Pack\",name:\"Pack\",pkg:\"\",typ:$funcType([AW,C.Value,BG],[$Int,$error],false)},{prop:\"Unpack\",name:\"Unpack\",pkg:\"\",typ:$funcType([B.Reader,C.Value,BG],[$error],false)}];O.methods=[{prop:\"Pack\",name:\"Pack\",pkg:\"\",typ:$funcType([AW,C.Value,BG],[$Int,$error],false)},{prop:\"Unpack\",name:\"Unpack\",pkg:\"\",typ:$funcType([B.Reader,C.Value,BG],[$error],false)},{prop:\"Sizeof\",name:\"Sizeof\",pkg:\"\",typ:$funcType([C.Value,BG],[$Int],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];BC.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([C.Value,BG],[$Int],false)},{prop:\"packVal\",name:\"packVal\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",typ:$funcType([AW,C.Value,$Int,BG],[$Int,$error],false)},{prop:\"Pack\",name:\"Pack\",pkg:\"\",typ:$funcType([AW,C.Value,$Int,BG],[$Int,$error],false)},{prop:\"unpackVal\",name:\"unpackVal\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",typ:$funcType([AW,C.Value,$Int,BG],[$error],false)},{prop:\"Unpack\",name:\"Unpack\",pkg:\"\",typ:$funcType([AW,C.Value,$Int,BG],[$error],false)}];R.methods=[{prop:\"SetByteOrder\",name:\"SetByteOrder\",pkg:\"\",typ:$funcType([A.ByteOrder],[],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Sizeof\",name:\"Sizeof\",pkg:\"\",typ:$funcType([C.Value,BG],[$Int],false)},{prop:\"sizefrom\",name:\"sizefrom\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",typ:$funcType([C.Value,AZ],[$Int],false)},{prop:\"Pack\",name:\"Pack\",pkg:\"\",typ:$funcType([AW,C.Value,BG],[$Int,$error],false)},{prop:\"Unpack\",name:\"Unpack\",pkg:\"\",typ:$funcType([B.Reader,C.Value,BG],[$error],false)}];BG.methods=[{prop:\"Validate\",name:\"Validate\",pkg:\"\",typ:$funcType([],[$error],false)}];AP.methods=[{prop:\"Resolve\",name:\"Resolve\",pkg:\"\",typ:$funcType([BG],[AP],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Int],false)}];L.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",[{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:AW,tag:\"\"},{prop:\"pos\",name:\"pos\",embedded:false,exported:false,typ:$Int,tag:\"\"}]);M.init(\"reflect\",[{prop:\"typ\",name:\"typ\",embedded:false,exported:false,typ:BB,tag:\"\"},{prop:\"ptr\",name:\"ptr\",embedded:false,exported:false,typ:$UnsafePointer,tag:\"\"},{prop:\"flag\",name:\"flag\",embedded:true,exported:false,typ:C.flag,tag:\"\"}]);N.init([{prop:\"Pack\",name:\"Pack\",pkg:\"\",typ:$funcType([AW,BG],[$Int,$error],false)},{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([BG],[$Int],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Unpack\",name:\"Unpack\",pkg:\"\",typ:$funcType([B.Reader,$Int,BG],[$error],false)}]);O.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",[{prop:\"custom\",name:\"custom\",embedded:false,exported:false,typ:N,tag:\"\"}]);Q.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\",[{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Ptr\",name:\"Ptr\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"Index\",name:\"Index\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:AP,tag:\"\"},{prop:\"defType\",name:\"defType\",embedded:false,exported:false,typ:AP,tag:\"\"},{prop:\"Array\",name:\"Array\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"Slice\",name:\"Slice\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"Len\",name:\"Len\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Order\",name:\"Order\",embedded:false,exported:true,typ:A.ByteOrder,tag:\"\"},{prop:\"Sizeof\",name:\"Sizeof\",embedded:false,exported:true,typ:AZ,tag:\"\"},{prop:\"Sizefrom\",name:\"Sizefrom\",embedded:false,exported:true,typ:AZ,tag:\"\"},{prop:\"Fields\",name:\"Fields\",embedded:false,exported:true,typ:R,tag:\"\"},{prop:\"kind\",name:\"kind\",embedded:false,exported:false,typ:C.Kind,tag:\"\"}]);R.init(BC);V.init(\"\",[{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Order\",name:\"Order\",embedded:false,exported:true,typ:A.ByteOrder,tag:\"\"},{prop:\"Sizeof\",name:\"Sizeof\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Skip\",name:\"Skip\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"Sizefrom\",name:\"Sizefrom\",embedded:false,exported:true,typ:$String,tag:\"\"}]);AF.init(\"\",[{prop:\"ByteAlign\",name:\"ByteAlign\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"PtrSize\",name:\"PtrSize\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Order\",name:\"Order\",embedded:false,exported:true,typ:A.ByteOrder,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=F.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=I.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=J.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=K.$init();$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}AB=new K.RWMutex.ptr(new K.Mutex.ptr(0,0),0,0,0,0);AC=new K.Mutex.ptr(0,0);a=J.MustCompile(\"^\\\\[(\\\\d*)\\\\]\");$s=12;case 12:if($c){$c=false;a=a.$blk();}if(a&&a.$blk!==undefined){break s;}X=a;AA={};AG=new AF.ptr(0,0,$ifaceNil);AQ=$makeMap($String.keyFor,[{k:\"pad\",v:1},{k:\"bool\",v:2},{k:\"byte\",v:5},{k:\"int8\",v:4},{k:\"uint8\",v:5},{k:\"int16\",v:6},{k:\"uint16\",v:7},{k:\"int32\",v:8},{k:\"uint32\",v:9},{k:\"int64\",v:10},{k:\"uint64\",v:11},{k:\"float32\",v:12},{k:\"float64\",v:13},{k:\"size_t\",v:17},{k:\"off_t\",v:18}]);AR=$makeMap(AP.keyFor,[{k:19,v:\"Custom\"}]);AV=$makeMap(C.Kind.keyFor,[{k:1,v:2},{k:3,v:4},{k:4,v:6},{k:2,v:8},{k:5,v:8},{k:6,v:10},{k:8,v:5},{k:9,v:7},{k:7,v:9},{k:10,v:9},{k:11,v:11},{k:13,v:12},{k:14,v:13},{k:24,v:14},{k:25,v:15},{k:22,v:16}]);$r=AH();$s=13;case 13:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}AS();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/proto\"]=(function(){var $pkg={},$init,A,C,B,D,E,H,I,F;A=$packages[\"bytes\"];C=$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/lunixbochs/struc\"];B=$packages[\"io\"];D=$pkg.WebsocketLength=$newType(0,$kindStruct,\"proto.WebsocketLength\",true,\"github.com/v2fly/BrowserBridge/proto\",true,function(Length_,Data_){this.$val=this;if(arguments.length===0){this.Length=0;this.Data=H.nil;return;}this.Length=Length_;this.Data=Data_;});E=$pkg.WebsocketConnectionRequest=$newType(0,$kindStruct,\"proto.WebsocketConnectionRequest\",true,\"github.com/v2fly/BrowserBridge/proto\",true,function(DestinationSize_,Destination_,ProtocolStringSize_,ProtocolString_){this.$val=this;if(arguments.length===0){this.DestinationSize=0;this.Destination=\"\";this.ProtocolStringSize=0;this.ProtocolString=\"\";return;}this.DestinationSize=DestinationSize_;this.Destination=Destination_;this.ProtocolStringSize=ProtocolStringSize_;this.ProtocolString=ProtocolString_;});H=$sliceType($Uint8);I=$ptrType(E);F=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=[b];c=[c];d=$ifaceNil;c[0]=new D.ptr(0,H.nil);e=C.Unpack(a,c[0]);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return[d,I.nil];}b[0]=new E.ptr(0,\"\",0,\"\");f=C.Unpack(A.NewReader(c[0].Data),b[0]);$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}d=f;if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return[d,I.nil];}$s=-1;return[$ifaceNil,b[0]];}return;}if($f===undefined){$f={$blk:F};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};$pkg.ReadRequest=F;D.init(\"\",[{prop:\"Length\",name:\"Length\",embedded:false,exported:true,typ:$Uint32,tag:\"struc:\\\"uint32,big,sizeof=Data\\\"\"},{prop:\"Data\",name:\"Data\",embedded:false,exported:true,typ:H,tag:\"\"}]);E.init(\"\",[{prop:\"DestinationSize\",name:\"DestinationSize\",embedded:false,exported:true,typ:$Uint32,tag:\"struc:\\\"uint32,big,sizeof=Destination\\\"\"},{prop:\"Destination\",name:\"Destination\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"ProtocolStringSize\",name:\"ProtocolStringSize\",embedded:false,exported:true,typ:$Uint32,tag:\"struc:\\\"uint32,big,sizeof=ProtocolString\\\"\"},{prop:\"ProtocolString\",name:\"ProtocolString\",embedded:false,exported:true,typ:$String,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket/websocketjs\"]=(function(){var $pkg={},$init,A,B,E,F,G,H,I,C,D;A=$packages[\"github.com/gopherjs/gopherjs/js\"];B=$pkg.ReadyState=$newType(2,$kindUint16,\"websocketjs.ReadyState\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket/websocketjs\",true,null);E=$pkg.WebSocket=$newType(0,$kindStruct,\"websocketjs.WebSocket\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket/websocketjs\",true,function(Object_,URL_,ReadyState_,BufferedAmount_,Extensions_,Protocol_,BinaryType_){this.$val=this;if(arguments.length===0){this.Object=null;this.URL=\"\";this.ReadyState=0;this.BufferedAmount=0;this.Extensions=\"\";this.Protocol=\"\";this.BinaryType=\"\";return;}this.Object=Object_;this.URL=URL_;this.ReadyState=ReadyState_;this.BufferedAmount=BufferedAmount_;this.Extensions=Extensions_;this.Protocol=Protocol_;this.BinaryType=BinaryType_;});F=$ptrType(E);G=$ptrType(A.Error);H=$ptrType(A.Object);I=$funcType([H],[],false);B.prototype.String=function(){var a,b;a=this.$val;b=a;if(b===(0)){return\"Connecting\";}else if(b===(1)){return\"Open\";}else if(b===(2)){return\"Closing\";}else if(b===(3)){return\"Closed\";}else{return\"Unknown\";}};$ptrType(B).prototype.String=function(){return new B(this.$get()).String();};C=function(a){var a,b,c,d,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=F.nil;c=$ifaceNil;$deferred.push([(function(){var d,e,f,g;d=$recover();if($interfaceIsEqual(d,$ifaceNil)){return;}e=$assertType(d,G,true);f=e[0];g=e[1];if(g&&!(f===G.nil)){b=F.nil;c=f;}else{$panic(d);}}),[]]);d=new($global.WebSocket)($externalize(a,$String));b=new E.ptr(d,\"\",0,0,\"\",\"\",\"\");return[b,c];}catch(err){$err=err;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return[b,c];}}};$pkg.New=C;D=function(a,b){var a,b,c,d,e,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=F.nil;d=$ifaceNil;$deferred.push([(function(){var e,f,g,h;e=$recover();if($interfaceIsEqual(e,$ifaceNil)){return;}f=$assertType(e,G,true);g=f[0];h=f[1];if(h&&!(g===G.nil)){c=F.nil;d=g;}else{$panic(e);}}),[]]);e=new($global.WebSocket)($externalize(a,$String),$externalize(b,$String));c=new E.ptr(e,\"\",0,0,\"\",\"\",\"\");return[c,d];}catch(err){$err=err;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return[c,d];}}};$pkg.New2=D;E.ptr.prototype.AddEventListener=function(a,b,c){var a,b,c,d;d=this;d.Object.addEventListener($externalize(a,$String),$externalize(c,I),$externalize(b,$Bool));};E.prototype.AddEventListener=function(a,b,c){return this.$val.AddEventListener(a,b,c);};E.ptr.prototype.RemoveEventListener=function(a,b,c){var a,b,c,d;d=this;d.Object.removeEventListener($externalize(a,$String),$externalize(c,I),$externalize(b,$Bool));};E.prototype.RemoveEventListener=function(a,b,c){return this.$val.RemoveEventListener(a,b,c);};E.ptr.prototype.Send=function(a){var a,b,c,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=$ifaceNil;c=this;$deferred.push([(function(){var d,e,f,g;d=$recover();if($interfaceIsEqual(d,$ifaceNil)){return;}e=$assertType(d,G,true);f=e[0];g=e[1];if(g&&!(f===G.nil)){b=f;}else{$panic(d);}}),[]]);c.Object.send($externalize(a,$emptyInterface));return b;}catch(err){$err=err;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return b;}}};E.prototype.Send=function(a){return this.$val.Send(a);};E.ptr.prototype.Close=function(){var a,b,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=$ifaceNil;b=this;$deferred.push([(function(){var c,d,e,f;c=$recover();if($interfaceIsEqual(c,$ifaceNil)){return;}d=$assertType(c,G,true);e=d[0];f=d[1];if(f&&!(e===G.nil)){a=e;}else{$panic(c);}}),[]]);b.Object.close(1000);return a;}catch(err){$err=err;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return a;}}};E.prototype.Close=function(){return this.$val.Close();};B.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];F.methods=[{prop:\"AddEventListener\",name:\"AddEventListener\",pkg:\"\",typ:$funcType([$String,$Bool,I],[],false)},{prop:\"RemoveEventListener\",name:\"RemoveEventListener\",pkg:\"\",typ:$funcType([$String,$Bool,I],[],false)},{prop:\"Send\",name:\"Send\",pkg:\"\",typ:$funcType([$emptyInterface],[$error],false)},{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[$error],false)}];E.init(\"\",[{prop:\"Object\",name:\"Object\",embedded:true,exported:true,typ:H,tag:\"\"},{prop:\"URL\",name:\"URL\",embedded:false,exported:true,typ:$String,tag:\"js:\\\"url\\\"\"},{prop:\"ReadyState\",name:\"ReadyState\",embedded:false,exported:true,typ:B,tag:\"js:\\\"readyState\\\"\"},{prop:\"BufferedAmount\",name:\"BufferedAmount\",embedded:false,exported:true,typ:$Uint32,tag:\"js:\\\"bufferedAmount\\\"\"},{prop:\"Extensions\",name:\"Extensions\",embedded:false,exported:true,typ:$String,tag:\"js:\\\"extensions\\\"\"},{prop:\"Protocol\",name:\"Protocol\",embedded:false,exported:true,typ:$String,tag:\"js:\\\"protocol\\\"\"},{prop:\"BinaryType\",name:\"BinaryType\",embedded:false,exported:true,typ:$String,tag:\"js:\\\"binaryType\\\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"context\"]=(function(){var $pkg={},$init,A,B,C,D,E,H,AB,AC,AD,AJ,I,J,T,U;A=$packages[\"errors\"];B=$packages[\"fmt\"];C=$packages[\"reflect\"];D=$packages[\"sync\"];E=$packages[\"time\"];H=$pkg.emptyCtx=$newType(4,$kindInt,\"context.emptyCtx\",true,\"context\",false,null);AB=$ptrType(H);AC=$structType(\"\",[]);AD=$ptrType(E.Location);AJ=$chanType(AC,false,true);$ptrType(H).prototype.Deadline=function(){var b,c;b=new E.Time.ptr(new $Uint64(0,0),new $Int64(0,0),AD.nil);c=false;return[b,c];};$ptrType(H).prototype.Done=function(){return $chanNil;};$ptrType(H).prototype.Err=function(){return $ifaceNil;};$ptrType(H).prototype.Value=function(b){var b;return $ifaceNil;};$ptrType(H).prototype.String=function(){var b,c;b=this;c=b;if(c===(I)){return\"context.Background\";}else if(c===(J)){return\"context.TODO\";}return\"unknown empty Context\";};U=function(){$close(T);};AB.methods=[{prop:\"Deadline\",name:\"Deadline\",pkg:\"\",typ:$funcType([],[E.Time,$Bool],false)},{prop:\"Done\",name:\"Done\",pkg:\"\",typ:$funcType([],[AJ],false)},{prop:\"Err\",name:\"Err\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"Value\",name:\"Value\",pkg:\"\",typ:$funcType([$emptyInterface],[$emptyInterface],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.Canceled=A.New(\"context canceled\");I=$newDataPointer(0,AB);J=$newDataPointer(0,AB);T=new $Chan(AC,0);U();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/nettrace\"]=(function(){var $pkg={},$init;$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/singleflight\"]=(function(){var $pkg={},$init,A;A=$packages[\"sync\"];$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"internal/x/net/dns/dnsmessage\"]=(function(){var $pkg={},$init,A,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V;A=$packages[\"errors\"];$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$pkg.ErrNotStarted=A.New(\"parsing/packing of this type isn't available yet\");$pkg.ErrSectionDone=A.New(\"parsing/packing of this section has completed\");F=A.New(\"insufficient data for base length type\");G=A.New(\"insufficient data for calculated length type\");H=A.New(\"segment prefix is reserved\");I=A.New(\"too many pointers (>10)\");J=A.New(\"invalid pointer\");K=A.New(\"nil resource body\");L=A.New(\"insufficient data for resource body length\");M=A.New(\"segment length too long\");N=A.New(\"zero length segment\");O=A.New(\"resource length too long\");P=A.New(\"too many Questions to pack (>65535)\");Q=A.New(\"too many Answers to pack (>65535)\");R=A.New(\"too many Authorities to pack (>65535)\");S=A.New(\"too many Additionals to pack (>65535)\");T=A.New(\"name is not in canonical format (it must end with a .)\");U=A.New(\"character string exceeds maximum length (255)\");V=A.New(\"compressed name in SRV resource data\");}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"math/rand\"]=(function(){var $pkg={},$init,B,A,J,K,M,AG,AI,AM,AN,AO,AP,AQ,AR,AT,AU,AV,C,D,E,G,H,I,P,AH,F,L,N,O,AJ;B=$packages[\"github.com/gopherjs/gopherjs/nosync\"];A=$packages[\"math\"];J=$pkg.Source=$newType(8,$kindInterface,\"rand.Source\",true,\"math/rand\",true,null);K=$pkg.Source64=$newType(8,$kindInterface,\"rand.Source64\",true,\"math/rand\",true,null);M=$pkg.Rand=$newType(0,$kindStruct,\"rand.Rand\",true,\"math/rand\",true,function(src_,s64_,readVal_,readPos_){this.$val=this;if(arguments.length===0){this.src=$ifaceNil;this.s64=$ifaceNil;this.readVal=new $Int64(0,0);this.readPos=0;return;}this.src=src_;this.s64=s64_;this.readVal=readVal_;this.readPos=readPos_;});AG=$pkg.lockedSource=$newType(0,$kindStruct,\"rand.lockedSource\",true,\"math/rand\",false,function(lk_,src_){this.$val=this;if(arguments.length===0){this.lk=new B.Mutex.ptr(false);this.src=$ifaceNil;return;}this.lk=lk_;this.src=src_;});AI=$pkg.rngSource=$newType(0,$kindStruct,\"rand.rngSource\",true,\"math/rand\",false,function(tap_,feed_,vec_){this.$val=this;if(arguments.length===0){this.tap=0;this.feed=0;this.vec=AM.zero();return;}this.tap=tap_;this.feed=feed_;this.vec=vec_;});AM=$arrayType($Int64,607);AN=$ptrType(AG);AO=$ptrType($Int8);AP=$sliceType($Int);AQ=$ptrType($Int64);AR=$ptrType(M);AT=$funcType([$Int,$Int],[],false);AU=$sliceType($Uint8);AV=$ptrType(AI);M.ptr.prototype.ExpFloat64=function(){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;case 1:b=a.Uint32();$s=3;case 3:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;d=(c&255)>>>0;e=(c)*(((d<0||d>=D.length)?($throwRuntimeError(\"index out of range\"),undefined):D[d]));if(c<((d<0||d>=C.length)?($throwRuntimeError(\"index out of range\"),undefined):C[d])){$s=-1;return e;}if(d===0){$s=4;continue;}$s=5;continue;case 4:f=a.Float64();$s=6;case 6:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=A.Log(f);$s=7;case 7:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}$s=-1;return 7.69711747013105-g;case 5:h=a.Float64();$s=10;case 10:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}if($fround(((d<0||d>=E.length)?($throwRuntimeError(\"index out of range\"),undefined):E[d])+$fround(($fround(h))*($fround((i=d-1>>>0,((i<0||i>=E.length)?($throwRuntimeError(\"index out of range\"),undefined):E[i]))-((d<0||d>=E.length)?($throwRuntimeError(\"index out of range\"),undefined):E[d])))))<($fround(A.Exp(-e)))){$s=8;continue;}$s=9;continue;case 8:$s=-1;return e;case 9:$s=1;continue;case 2:$s=-1;return 0;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.ExpFloat64};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.ExpFloat64=function(){return this.$val.ExpFloat64();};F=function(a){var a;if(a<0){return((-a>>>0));}return((a>>>0));};M.ptr.prototype.NormFloat64=function(){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;case 1:b=a.Uint32();$s=3;case 3:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=((b>>0));d=c&127;e=(c)*(((d<0||d>=H.length)?($throwRuntimeError(\"index out of range\"),undefined):H[d]));if(F(c)<((d<0||d>=G.length)?($throwRuntimeError(\"index out of range\"),undefined):G[d])){$s=-1;return e;}if(d===0){$s=4;continue;}$s=5;continue;case 4:case 6:f=a.Float64();$s=8;case 8:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=A.Log(f);$s=9;case 9:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}e=-g*0.29047645161474317;h=a.Float64();$s=10;case 10:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}i=A.Log(h);$s=11;case 11:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}j=-i;if(j+j>=e*e){$s=7;continue;}$s=6;continue;case 7:if(c>0){$s=-1;return 3.442619855899+e;}$s=-1;return-3.442619855899-e;case 5:k=a.Float64();$s=14;case 14:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}if($fround(((d<0||d>=I.length)?($throwRuntimeError(\"index out of range\"),undefined):I[d])+$fround(($fround(k))*($fround((l=d-1>>0,((l<0||l>=I.length)?($throwRuntimeError(\"index out of range\"),undefined):I[l]))-((d<0||d>=I.length)?($throwRuntimeError(\"index out of range\"),undefined):I[d])))))<($fround(A.Exp(-0.5*e*e)))){$s=12;continue;}$s=13;continue;case 12:$s=-1;return e;case 13:$s=1;continue;case 2:$s=-1;return 0;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.NormFloat64};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.NormFloat64=function(){return this.$val.NormFloat64();};L=function(a){var a,b;b=new AI.ptr(0,0,AM.zero());b.Seed(a);return b;};$pkg.NewSource=L;N=function(a){var a,b,c;b=$assertType(a,K,true);c=b[0];return new M.ptr(a,c,new $Int64(0,0),0);};$pkg.New=N;M.ptr.prototype.Seed=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=$assertType(b.src,AN,true);d=c[0];e=c[1];if(e){$s=1;continue;}$s=2;continue;case 1:$r=d.seedPos(a,(b.$ptr_readPos||(b.$ptr_readPos=new AO(function(){return this.$target.readPos;},function($v){this.$target.readPos=$v;},b))));$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 2:$r=b.src.Seed(a);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b.readPos=0;$s=-1;return;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Seed};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Seed=function(a){return this.$val.Seed(a);};M.ptr.prototype.Int63=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.src.Int63();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return b;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Int63};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Int63=function(){return this.$val.Int63();};M.ptr.prototype.Uint32=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.Int63();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return(($shiftRightInt64(b,31).$low>>>0));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Uint32};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Uint32=function(){return this.$val.Uint32();};M.ptr.prototype.Uint64=function(){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;if(!($interfaceIsEqual(a.s64,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:b=a.s64.Uint64();$s=3;case 3:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return b;case 2:e=a.Int63();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}h=a.Int63();$s=5;case 5:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}$s=-1;return(c=$shiftRightUint64(((d=e,new $Uint64(d.$high,d.$low))),31),f=$shiftLeft64(((g=h,new $Uint64(g.$high,g.$low))),32),new $Uint64(c.$high|f.$high,(c.$low|f.$low)>>>0));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Uint64};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Uint64=function(){return this.$val.Uint64();};M.ptr.prototype.Int31=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;c=a.Int63();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return(((b=$shiftRightInt64(c,32),b.$low+((b.$high>>31)*4294967296))>>0));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Int31};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Int31=function(){return this.$val.Int31();};M.ptr.prototype.Int=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.Int63();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=((b.$low>>>0));$s=-1;return((((c<<1>>>0)>>>1>>>0)>>0));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Int};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Int=function(){return this.$val.Int();};M.ptr.prototype.Int63n=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if((a.$high<0||(a.$high===0&&a.$low<=0))){$panic(new $String(\"invalid argument to Int63n\"));}if((c=(d=new $Int64(a.$high-0,a.$low-1),new $Int64(a.$high&d.$high,(a.$low&d.$low)>>>0)),(c.$high===0&&c.$low===0))){$s=1;continue;}$s=2;continue;case 1:f=b.Int63();$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return(e=f,g=new $Int64(a.$high-0,a.$low-1),new $Int64(e.$high&g.$high,(e.$low&g.$low)>>>0));case 2:j=((h=(i=$div64(new $Uint64(2147483648,0),(new $Uint64(a.$high,a.$low)),true),new $Uint64(2147483647-i.$high,4294967295-i.$low)),new $Int64(h.$high,h.$low)));k=b.Int63();$s=4;case 4:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}l=k;case 5:if(!((l.$high>j.$high||(l.$high===j.$high&&l.$low>j.$low)))){$s=6;continue;}m=b.Int63();$s=7;case 7:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;$s=5;continue;case 6:$s=-1;return $div64(l,a,true);}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Int63n};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Int63n=function(a){return this.$val.Int63n(a);};M.ptr.prototype.Int31n=function(a){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(a<=0){$panic(new $String(\"invalid argument to Int31n\"));}if((a&((a-1>>0)))===0){$s=1;continue;}$s=2;continue;case 1:c=b.Int31();$s=3;case 3:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c&((a-1>>0));case 2:e=(((2147483647-(d=2147483648%((a>>>0)),d===d?d:$throwRuntimeError(\"integer divide by zero\"))>>>0)>>0));f=b.Int31();$s=4;case 4:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=f;case 5:if(!(g>e)){$s=6;continue;}h=b.Int31();$s=7;case 7:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;$s=5;continue;case 6:$s=-1;return(i=g%a,i===i?i:$throwRuntimeError(\"integer divide by zero\"));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Int31n};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Int31n=function(a){return this.$val.Int31n(a);};M.ptr.prototype.int31n=function(a){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=b.Uint32();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=$mul64((new $Uint64(0,d)),(new $Uint64(0,a)));f=((e.$low>>>0));if(f<((a>>>0))){$s=2;continue;}$s=3;continue;case 2:h=(g=((-a>>>0))%((a>>>0)),g===g?g:$throwRuntimeError(\"integer divide by zero\"));case 4:if(!(f<h)){$s=5;continue;}i=b.Uint32();$s=6;case 6:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}d=i;e=$mul64((new $Uint64(0,d)),(new $Uint64(0,a)));f=((e.$low>>>0));$s=4;continue;case 5:case 3:$s=-1;return(($shiftRightUint64(e,32).$low>>0));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.int31n};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.int31n=function(a){return this.$val.int31n(a);};M.ptr.prototype.Intn=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(a<=0){$panic(new $String(\"invalid argument to Intn\"));}if(a<=2147483647){$s=1;continue;}$s=2;continue;case 1:c=b.Int31n(((a>>0)));$s=3;case 3:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return((c>>0));case 2:e=b.Int63n((new $Int64(0,a)));$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return(((d=e,d.$low+((d.$high>>31)*4294967296))>>0));}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Intn};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Intn=function(a){return this.$val.Intn(a);};M.ptr.prototype.Float64=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;case 1:b=a.Int63();$s=2;case 2:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=($flatten64(b))/9.223372036854776e+18;if(c===1){$s=3;continue;}$s=4;continue;case 3:$s=1;continue;case 4:$s=-1;return c;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Float64};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Float64=function(){return this.$val.Float64();};M.ptr.prototype.Float32=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;case 1:b=a.Float64();$s=2;case 2:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=($fround(b));if(c===1){$s=3;continue;}$s=4;continue;case 3:$s=1;continue;case 4:$s=-1;return c;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Float32};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Float32=function(){return this.$val.Float32();};M.ptr.prototype.Perm=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=$makeSlice(AP,a);d=0;case 1:if(!(d<a)){$s=2;continue;}e=b.Intn(d+1>>0);$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=e;((d<0||d>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+d]=((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]));((f<0||f>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+f]=d);d=d+(1)>>0;$s=1;continue;case 2:$s=-1;return c;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Perm};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Perm=function(a){return this.$val.Perm(a);};M.ptr.prototype.Shuffle=function(a,b){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;if(a<0){$panic(new $String(\"invalid argument to Shuffle\"));}d=a-1>>0;case 1:if(!(d>2147483646)){$s=2;continue;}f=c.Int63n((new $Int64(0,(d+1>>0))));$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=(((e=f,e.$low+((e.$high>>31)*4294967296))>>0));$r=b(d,g);$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=d-(1)>>0;$s=1;continue;case 2:case 5:if(!(d>0)){$s=6;continue;}h=c.int31n((((d+1>>0)>>0)));$s=7;case 7:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}i=((h>>0));$r=b(d,i);$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=d-(1)>>0;$s=5;continue;case 6:$s=-1;return;}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Shuffle};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Shuffle=function(a,b){return this.$val.Shuffle(a,b);};M.ptr.prototype.Read=function(a){var a,b,c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;e=$assertType(d.src,AN,true);f=e[0];g=e[1];if(g){$s=1;continue;}$s=2;continue;case 1:i=f.read(a,(d.$ptr_readVal||(d.$ptr_readVal=new AQ(function(){return this.$target.readVal;},function($v){this.$target.readVal=$v;},d))),(d.$ptr_readPos||(d.$ptr_readPos=new AO(function(){return this.$target.readPos;},function($v){this.$target.readPos=$v;},d))));$s=3;case 3:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;b=h[0];c=h[1];$s=-1;return[b,c];case 2:k=O(a,$methodVal(d,\"Int63\"),(d.$ptr_readVal||(d.$ptr_readVal=new AQ(function(){return this.$target.readVal;},function($v){this.$target.readVal=$v;},d))),(d.$ptr_readPos||(d.$ptr_readPos=new AO(function(){return this.$target.readPos;},function($v){this.$target.readPos=$v;},d))));$s=4;case 4:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;b=j[0];c=j[1];$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:M.ptr.prototype.Read};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};M.prototype.Read=function(a){return this.$val.Read(a);};O=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=0;f=$ifaceNil;g=d.$get();h=c.$get();e=0;case 1:if(!(e<a.$length)){$s=2;continue;}if(g===0){$s=3;continue;}$s=4;continue;case 3:i=b();$s=5;case 5:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;g=7;case 4:((e<0||e>=a.$length)?($throwRuntimeError(\"index out of range\"),undefined):a.$array[a.$offset+e]=((h.$low<<24>>>24)));h=$shiftRightInt64(h,(8));g=g-(1)<<24>>24;e=e+(1)>>0;$s=1;continue;case 2:d.$set(g);c.$set(h);$s=-1;return[e,f];}return;}if($f===undefined){$f={$blk:O};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};AG.ptr.prototype.Int63=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=new $Int64(0,0);b=this;b.lk.Lock();c=b.src.Int63();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}a=c;b.lk.Unlock();$s=-1;return a;}return;}if($f===undefined){$f={$blk:AG.ptr.prototype.Int63};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AG.prototype.Int63=function(){return this.$val.Int63();};AG.ptr.prototype.Uint64=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=new $Uint64(0,0);b=this;b.lk.Lock();c=b.src.Uint64();$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}a=c;b.lk.Unlock();$s=-1;return a;}return;}if($f===undefined){$f={$blk:AG.ptr.prototype.Uint64};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AG.prototype.Uint64=function(){return this.$val.Uint64();};AG.ptr.prototype.Seed=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;b.lk.Lock();$r=b.src.Seed(a);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b.lk.Unlock();$s=-1;return;}return;}if($f===undefined){$f={$blk:AG.ptr.prototype.Seed};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};AG.prototype.Seed=function(a){return this.$val.Seed(a);};AG.ptr.prototype.seedPos=function(a,b){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;c.lk.Lock();$r=c.src.Seed(a);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b.$set(0);c.lk.Unlock();$s=-1;return;}return;}if($f===undefined){$f={$blk:AG.ptr.prototype.seedPos};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AG.prototype.seedPos=function(a,b){return this.$val.seedPos(a,b);};AG.ptr.prototype.read=function(a,b,c){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=0;e=$ifaceNil;f=this;f.lk.Lock();h=O(a,$methodVal(f.src,\"Int63\"),b,c);$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;d=g[0];e=g[1];f.lk.Unlock();$s=-1;return[d,e];}return;}if($f===undefined){$f={$blk:AG.ptr.prototype.read};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};AG.prototype.read=function(a,b,c){return this.$val.read(a,b,c);};AJ=function(a){var a,b,c,d,e;c=(b=a/44488,(b===b&&b!==1/0&&b!==-1/0)?b>>0:$throwRuntimeError(\"integer divide by zero\"));e=(d=a%44488,d===d?d:$throwRuntimeError(\"integer divide by zero\"));a=($imul(48271,e))-($imul(3399,c))>>0;if(a<0){a=a+(2147483647)>>0;}return a;};AI.ptr.prototype.Seed=function(a){var a,b,c,d,e,f,g,h,i,j;b=this;b.tap=0;b.feed=334;a=$div64(a,new $Int64(0,2147483647),true);if((a.$high<0||(a.$high===0&&a.$low<0))){a=(c=new $Int64(0,2147483647),new $Int64(a.$high+c.$high,a.$low+c.$low));}if((a.$high===0&&a.$low===0)){a=new $Int64(0,89482311);}d=(((a.$low+((a.$high>>31)*4294967296))>>0));e=-20;while(true){if(!(e<607)){break;}d=AJ(d);if(e>=0){f=new $Int64(0,0);f=$shiftLeft64((new $Int64(0,d)),40);d=AJ(d);f=(g=$shiftLeft64((new $Int64(0,d)),20),new $Int64(f.$high^g.$high,(f.$low^g.$low)>>>0));d=AJ(d);f=(h=(new $Int64(0,d)),new $Int64(f.$high^h.$high,(f.$low^h.$low)>>>0));f=(i=((e<0||e>=AH.length)?($throwRuntimeError(\"index out of range\"),undefined):AH[e]),new $Int64(f.$high^i.$high,(f.$low^i.$low)>>>0));(j=b.vec,((e<0||e>=j.length)?($throwRuntimeError(\"index out of range\"),undefined):j[e]=f));}e=e+(1)>>0;}};AI.prototype.Seed=function(a){return this.$val.Seed(a);};AI.ptr.prototype.Int63=function(){var a,b,c;a=this;return((b=(c=a.Uint64(),new $Uint64(c.$high&2147483647,(c.$low&4294967295)>>>0)),new $Int64(b.$high,b.$low)));};AI.prototype.Int63=function(){return this.$val.Int63();};AI.ptr.prototype.Uint64=function(){var a,b,c,d,e,f,g,h,i,j;a=this;a.tap=a.tap-(1)>>0;if(a.tap<0){a.tap=a.tap+(607)>>0;}a.feed=a.feed-(1)>>0;if(a.feed<0){a.feed=a.feed+(607)>>0;}h=(b=(c=a.vec,d=a.feed,((d<0||d>=c.length)?($throwRuntimeError(\"index out of range\"),undefined):c[d])),e=(f=a.vec,g=a.tap,((g<0||g>=f.length)?($throwRuntimeError(\"index out of range\"),undefined):f[g])),new $Int64(b.$high+e.$high,b.$low+e.$low));(i=a.vec,j=a.feed,((j<0||j>=i.length)?($throwRuntimeError(\"index out of range\"),undefined):i[j]=h));return(new $Uint64(h.$high,h.$low));};AI.prototype.Uint64=function(){return this.$val.Uint64();};AR.methods=[{prop:\"ExpFloat64\",name:\"ExpFloat64\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"NormFloat64\",name:\"NormFloat64\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Seed\",name:\"Seed\",pkg:\"\",typ:$funcType([$Int64],[],false)},{prop:\"Int63\",name:\"Int63\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Uint32\",name:\"Uint32\",pkg:\"\",typ:$funcType([],[$Uint32],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([],[$Uint64],false)},{prop:\"Int31\",name:\"Int31\",pkg:\"\",typ:$funcType([],[$Int32],false)},{prop:\"Int\",name:\"Int\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Int63n\",name:\"Int63n\",pkg:\"\",typ:$funcType([$Int64],[$Int64],false)},{prop:\"Int31n\",name:\"Int31n\",pkg:\"\",typ:$funcType([$Int32],[$Int32],false)},{prop:\"int31n\",name:\"int31n\",pkg:\"math/rand\",typ:$funcType([$Int32],[$Int32],false)},{prop:\"Intn\",name:\"Intn\",pkg:\"\",typ:$funcType([$Int],[$Int],false)},{prop:\"Float64\",name:\"Float64\",pkg:\"\",typ:$funcType([],[$Float64],false)},{prop:\"Float32\",name:\"Float32\",pkg:\"\",typ:$funcType([],[$Float32],false)},{prop:\"Perm\",name:\"Perm\",pkg:\"\",typ:$funcType([$Int],[AP],false)},{prop:\"Shuffle\",name:\"Shuffle\",pkg:\"\",typ:$funcType([$Int,AT],[],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([AU],[$Int,$error],false)}];AN.methods=[{prop:\"Int63\",name:\"Int63\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([],[$Uint64],false)},{prop:\"Seed\",name:\"Seed\",pkg:\"\",typ:$funcType([$Int64],[],false)},{prop:\"seedPos\",name:\"seedPos\",pkg:\"math/rand\",typ:$funcType([$Int64,AO],[],false)},{prop:\"read\",name:\"read\",pkg:\"math/rand\",typ:$funcType([AU,AQ,AO],[$Int,$error],false)}];AV.methods=[{prop:\"Seed\",name:\"Seed\",pkg:\"\",typ:$funcType([$Int64],[],false)},{prop:\"Int63\",name:\"Int63\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([],[$Uint64],false)}];J.init([{prop:\"Int63\",name:\"Int63\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Seed\",name:\"Seed\",pkg:\"\",typ:$funcType([$Int64],[],false)}]);K.init([{prop:\"Int63\",name:\"Int63\",pkg:\"\",typ:$funcType([],[$Int64],false)},{prop:\"Seed\",name:\"Seed\",pkg:\"\",typ:$funcType([$Int64],[],false)},{prop:\"Uint64\",name:\"Uint64\",pkg:\"\",typ:$funcType([],[$Uint64],false)}]);M.init(\"math/rand\",[{prop:\"src\",name:\"src\",embedded:false,exported:false,typ:J,tag:\"\"},{prop:\"s64\",name:\"s64\",embedded:false,exported:false,typ:K,tag:\"\"},{prop:\"readVal\",name:\"readVal\",embedded:false,exported:false,typ:$Int64,tag:\"\"},{prop:\"readPos\",name:\"readPos\",embedded:false,exported:false,typ:$Int8,tag:\"\"}]);AG.init(\"math/rand\",[{prop:\"lk\",name:\"lk\",embedded:false,exported:false,typ:B.Mutex,tag:\"\"},{prop:\"src\",name:\"src\",embedded:false,exported:false,typ:K,tag:\"\"}]);AI.init(\"math/rand\",[{prop:\"tap\",name:\"tap\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"feed\",name:\"feed\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"vec\",name:\"vec\",embedded:false,exported:false,typ:AM,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}C=$toNativeArray($kindUint32,[3801129273,0,2615860924,3279400049,3571300752,3733536696,3836274812,3906990442,3958562475,3997804264,4028649213,4053523342,4074002619,4091154507,4105727352,4118261130,4129155133,4138710916,4147160435,4154685009,4161428406,4167506077,4173011791,4178022498,4182601930,4186803325,4190671498,4194244443,4197554582,4200629752,4203493986,4206168142,4208670408,4211016720,4213221098,4215295924,4217252177,4219099625,4220846988,4222502074,4224071896,4225562770,4226980400,4228329951,4229616109,4230843138,4232014925,4233135020,4234206673,4235232866,4236216336,4237159604,4238064994,4238934652,4239770563,4240574564,4241348362,4242093539,4242811568,4243503822,4244171579,4244816032,4245438297,4246039419,4246620374,4247182079,4247725394,4248251127,4248760037,4249252839,4249730206,4250192773,4250641138,4251075867,4251497493,4251906522,4252303431,4252688672,4253062674,4253425844,4253778565,4254121205,4254454110,4254777611,4255092022,4255397640,4255694750,4255983622,4256264513,4256537670,4256803325,4257061702,4257313014,4257557464,4257795244,4258026541,4258251531,4258470383,4258683258,4258890309,4259091685,4259287526,4259477966,4259663135,4259843154,4260018142,4260188212,4260353470,4260514019,4260669958,4260821380,4260968374,4261111028,4261249421,4261383632,4261513736,4261639802,4261761900,4261880092,4261994441,4262105003,4262211835,4262314988,4262414513,4262510454,4262602857,4262691764,4262777212,4262859239,4262937878,4263013162,4263085118,4263153776,4263219158,4263281289,4263340187,4263395872,4263448358,4263497660,4263543789,4263586755,4263626565,4263663224,4263696735,4263727099,4263754314,4263778377,4263799282,4263817020,4263831582,4263842955,4263851124,4263856071,4263857776,4263856218,4263851370,4263843206,4263831695,4263816804,4263798497,4263776735,4263751476,4263722676,4263690284,4263654251,4263614520,4263571032,4263523724,4263472530,4263417377,4263358192,4263294892,4263227394,4263155608,4263079437,4262998781,4262913534,4262823581,4262728804,4262629075,4262524261,4262414220,4262298801,4262177846,4262051187,4261918645,4261780032,4261635148,4261483780,4261325704,4261160681,4260988457,4260808763,4260621313,4260425802,4260221905,4260009277,4259787550,4259556329,4259315195,4259063697,4258801357,4258527656,4258242044,4257943926,4257632664,4257307571,4256967906,4256612870,4256241598,4255853155,4255446525,4255020608,4254574202,4254106002,4253614578,4253098370,4252555662,4251984571,4251383021,4250748722,4250079132,4249371435,4248622490,4247828790,4246986404,4246090910,4245137315,4244119963,4243032411,4241867296,4240616155,4239269214,4237815118,4236240596,4234530035,4232664930,4230623176,4228378137,4225897409,4223141146,4220059768,4216590757,4212654085,4208145538,4202926710,4196809522,4189531420,4180713890,4169789475,4155865042,4137444620,4111806704,4073393724,4008685917,3873074895]);D=$toNativeArray($kindFloat32,[2.0249555365836613e-09,1.4866739783681027e-11,2.4409616689036184e-11,3.1968806074589295e-11,3.844677007314168e-11,4.42282044321729e-11,4.951644302919611e-11,5.443358958023836e-11,5.905943789574764e-11,6.34494193296753e-11,6.764381416113352e-11,7.167294535648239e-11,7.556032188826833e-11,7.932458162551725e-11,8.298078890689453e-11,8.654132271912474e-11,9.001651507523079e-11,9.341507428706208e-11,9.674443190998971e-11,1.0001099254308699e-10,1.0322031424037093e-10,1.0637725422757427e-10,1.0948611461891744e-10,1.1255067711157807e-10,1.1557434870246297e-10,1.1856014781042035e-10,1.2151082917633005e-10,1.2442885610752796e-10,1.2731647680563896e-10,1.3017574518325858e-10,1.330085347417409e-10,1.3581656632677408e-10,1.386014220061682e-10,1.413645728254309e-10,1.4410737880776736e-10,1.4683107507629245e-10,1.4953686899854546e-10,1.522258291641876e-10,1.5489899640730442e-10,1.575573282952547e-10,1.6020171300645814e-10,1.628330109637588e-10,1.6545202707884954e-10,1.68059510752272e-10,1.7065616975120435e-10,1.73242697965037e-10,1.758197337720091e-10,1.783878739169964e-10,1.8094774290045024e-10,1.834998542005195e-10,1.8604476292871652e-10,1.8858298256319017e-10,1.9111498494872592e-10,1.9364125580789704e-10,1.9616222535212557e-10,1.9867835154840918e-10,2.011900368525943e-10,2.0369768372052732e-10,2.062016807302669e-10,2.0870240258208383e-10,2.1120022397624894e-10,2.136955057352452e-10,2.1618855317040442e-10,2.1867974098199738e-10,2.2116936060356807e-10,2.2365774510202385e-10,2.2614519978869652e-10,2.2863201609713002e-10,2.3111849933865614e-10,2.3360494094681883e-10,2.3609159072179864e-10,2.3857874009713953e-10,2.4106666662859766e-10,2.4355562011635357e-10,2.460458781161634e-10,2.485376904282077e-10,2.5103127909709144e-10,2.5352694943414633e-10,2.560248957284017e-10,2.585253955356137e-10,2.610286709003873e-10,2.6353494386732734e-10,2.6604446423661443e-10,2.6855745405285347e-10,2.71074163116225e-10,2.7359478571575835e-10,2.7611959940720965e-10,2.786487707240326e-10,2.8118254946640775e-10,2.8372118543451563e-10,2.8626484516180994e-10,2.8881380620404684e-10,2.9136826285025563e-10,2.9392840938946563e-10,2.96494523377433e-10,2.990667713476114e-10,3.016454031001814e-10,3.042306406797479e-10,3.068226783753403e-10,3.09421765987139e-10,3.12028125559749e-10,3.1464195138219964e-10,3.17263521010247e-10,3.1989300097734485e-10,3.225306410836737e-10,3.2517669112941405e-10,3.2783134540359526e-10,3.3049485370639786e-10,3.3316743808242677e-10,3.3584937608743815e-10,3.385408342548857e-10,3.4124211789610115e-10,3.4395342130011386e-10,3.4667499426710435e-10,3.494071143528288e-10,3.521500313574677e-10,3.54903967325626e-10,3.576691720574843e-10,3.6044595086437425e-10,3.632345535464765e-10,3.660352021483959e-10,3.688482297370399e-10,3.716738583570134e-10,3.7451239331964814e-10,3.773641121807003e-10,3.802292924959261e-10,3.831082673322328e-10,3.8600128648980103e-10,3.8890865527996255e-10,3.9183070676962473e-10,3.9476774627011935e-10,3.977200790927782e-10,4.006880383045086e-10,4.0367195697221803e-10,4.066721681628138e-10,4.0968900494320337e-10,4.127228558914453e-10,4.15774054074447e-10,4.188429603146915e-10,4.2192993543466173e-10,4.25035395767992e-10,4.2815970213716525e-10,4.313032986313914e-10,4.3446651831757777e-10,4.376498607960855e-10,4.408536868893975e-10,4.4407846844229937e-10,4.4732464954400086e-10,4.5059267428371186e-10,4.538830145062178e-10,4.5719619756745544e-10,4.605326675566346e-10,4.638929240741163e-10,4.672775499869886e-10,4.706869893844612e-10,4.74121908400349e-10,4.775827511238617e-10,4.810701836888143e-10,4.845848167178701e-10,4.881271498113904e-10,4.916979601254923e-10,4.952977472605369e-10,4.989272883726414e-10,5.025872495956207e-10,5.062783525744408e-10,5.100013189540675e-10,5.13756870379467e-10,5.175458395179078e-10,5.21369003525507e-10,5.252272505806843e-10,5.29121357839557e-10,5.330522134805449e-10,5.3702081670437e-10,5.41028055689452e-10,5.450749851476644e-10,5.491624932574268e-10,5.532918012640664e-10,5.574638528571541e-10,5.616799247931681e-10,5.659410717839819e-10,5.702485705860738e-10,5.746036979559221e-10,5.790077306500052e-10,5.83462111958255e-10,5.879682296594524e-10,5.925275825546805e-10,5.971417249561739e-10,6.01812211176167e-10,6.065408175714992e-10,6.113292094767075e-10,6.16179329782085e-10,6.21092954844471e-10,6.260721940876124e-10,6.311191569352559e-10,6.362359528111483e-10,6.414249686947926e-10,6.466885360545405e-10,6.520292639144998e-10,6.574497612987784e-10,6.629528592760892e-10,6.685415554485985e-10,6.742187919073217e-10,6.799880103436351e-10,6.858525969377638e-10,6.918161599145378e-10,6.978825850545434e-10,7.040559801829716e-10,7.103406751696184e-10,7.167412219288849e-10,7.232625609532306e-10,7.2990985477972e-10,7.366885990123251e-10,7.436047333442275e-10,7.506645305355164e-10,7.57874762946642e-10,7.652426470272644e-10,7.727759543385559e-10,7.804830115532013e-10,7.883728114777e-10,7.964550685635174e-10,8.047402189070851e-10,8.132396422944055e-10,8.219657177122031e-10,8.309318788590758e-10,8.401527806789488e-10,8.496445214056791e-10,8.594246980742071e-10,8.695127395874636e-10,8.799300732498239e-10,8.90700457834015e-10,9.01850316648023e-10,9.134091816243028e-10,9.254100818978372e-10,9.37890431984556e-10,9.508922538259412e-10,9.64463842123564e-10,9.78660263939446e-10,9.935448019859905e-10,1.0091912860943353e-09,1.0256859805934937e-09,1.0431305819125214e-09,1.0616465484503124e-09,1.0813799855569073e-09,1.1025096391392708e-09,1.1252564435793033e-09,1.149898620766976e-09,1.176793218427008e-09,1.2064089727203964e-09,1.2393785997488749e-09,1.2765849488616254e-09,1.319313880365769e-09,1.36954347862428e-09,1.4305497897382224e-09,1.5083649884672923e-09,1.6160853766322703e-09,1.7921247819074893e-09]);E=$toNativeArray($kindFloat32,[1,0.9381436705589294,0.900469958782196,0.8717043399810791,0.847785472869873,0.8269932866096497,0.8084216713905334,0.7915276288986206,0.7759568691253662,0.7614634037017822,0.7478685975074768,0.7350381016731262,0.7228676676750183,0.7112747430801392,0.7001926302909851,0.6895664930343628,0.6793505549430847,0.669506311416626,0.6600008606910706,0.6508058309555054,0.6418967247009277,0.633251965045929,0.62485271692276,0.6166821718215942,0.608725368976593,0.6009689569473267,0.5934008955955505,0.5860103368759155,0.5787873864173889,0.5717230439186096,0.5648092031478882,0.5580382943153381,0.5514034032821655,0.5448982119560242,0.5385168790817261,0.5322538614273071,0.526104211807251,0.5200631618499756,0.5141264200210571,0.5082897543907166,0.5025495290756226,0.4969019889831543,0.4913438558578491,0.4858720004558563,0.48048335313796997,0.4751752018928528,0.4699448347091675,0.4647897481918335,0.4597076177597046,0.4546961486339569,0.4497532546520233,0.44487687945365906,0.4400651156902313,0.4353161156177521,0.4306281507015228,0.42599955201148987,0.42142874002456665,0.4169141948223114,0.4124544560909271,0.40804818272590637,0.4036940038204193,0.39939069747924805,0.3951369822025299,0.39093172550201416,0.38677382469177246,0.38266217708587646,0.378595769405365,0.37457355856895447,0.37059465050697327,0.366658091545105,0.362762987613678,0.358908474445343,0.35509374737739563,0.35131800174713135,0.3475804924964905,0.34388044476509094,0.34021714329719543,0.33658990263938904,0.3329980671405792,0.3294409513473511,0.32591795921325684,0.32242849469184875,0.3189719021320343,0.3155476748943329,0.31215524673461914,0.3087940812110901,0.30546361207962036,0.30216339230537415,0.29889291524887085,0.29565170407295227,0.2924392819404602,0.2892552316188812,0.28609907627105713,0.2829704284667969,0.27986884117126465,0.2767939269542694,0.2737452983856201,0.2707225978374481,0.26772540807724,0.26475343108177185,0.2618062496185303,0.258883535861969,0.2559850215911865,0.25311028957366943,0.25025907158851624,0.24743106961250305,0.2446259707212448,0.24184346199035645,0.23908329010009766,0.23634515702724457,0.2336287796497345,0.23093391954898834,0.22826029360294342,0.22560766339302063,0.22297576069831848,0.22036437690258026,0.21777324378490448,0.21520215272903442,0.212650865316391,0.21011915802955627,0.20760682225227356,0.20511364936828613,0.20263944566249847,0.20018397271633148,0.19774706661701202,0.1953285187482834,0.19292815029621124,0.19054576754570007,0.18818120658397675,0.18583425879478455,0.18350479006767273,0.18119260668754578,0.17889754474163055,0.17661945521831512,0.17435817420482635,0.1721135377883911,0.16988539695739746,0.16767361760139465,0.16547803580760956,0.16329853236675262,0.16113494336605072,0.1589871346950531,0.15685498714447021,0.15473836660385132,0.15263713896274567,0.1505511850118637,0.1484803706407547,0.14642459154129028,0.1443837285041809,0.14235764741897583,0.1403462439775467,0.13834942877292633,0.136367067694664,0.13439907133579254,0.1324453204870224,0.1305057406425476,0.12858019769191742,0.12666863203048706,0.12477091699838638,0.12288697808980942,0.1210167184472084,0.11916005611419678,0.11731690168380737,0.11548716574907303,0.11367076635360718,0.11186762899160385,0.11007767915725708,0.1083008274435997,0.10653700679540634,0.10478614270687103,0.1030481606721878,0.10132300108671188,0.0996105819940567,0.09791085124015808,0.09622374176979065,0.09454918652772903,0.09288713335990906,0.09123751521110535,0.08960027992725372,0.08797537535429001,0.08636274188756943,0.0847623273730278,0.08317409455776215,0.08159798383712769,0.08003395050764084,0.07848194986581802,0.07694194465875626,0.07541389018297195,0.07389774918556213,0.07239348441362381,0.070901058614254,0.06942043453454971,0.06795158982276917,0.06649449467658997,0.06504911929368973,0.06361543387174606,0.06219341605901718,0.06078304722905159,0.0593843050301075,0.05799717456102371,0.05662164092063904,0.05525768920779228,0.05390531197190285,0.05256449431180954,0.05123523622751236,0.04991753399372101,0.04861138388514519,0.047316793352365494,0.04603376239538193,0.044762298464775085,0.04350241273641586,0.04225412383675575,0.04101744294166565,0.039792392402887344,0.03857899457216263,0.03737728297710419,0.03618728369474411,0.03500903770327568,0.03384258225560188,0.0326879620552063,0.031545232981443405,0.030414443463087082,0.0292956605553627,0.028188949450850487,0.027094384655356407,0.02601204626262188,0.024942025542259216,0.023884421214461327,0.022839335724711418,0.021806888282299042,0.020787203684449196,0.019780423492193222,0.018786700442433357,0.017806200310587883,0.016839107498526573,0.015885621309280396,0.014945968054234982,0.01402039173990488,0.013109165243804455,0.012212592177093029,0.011331013403832912,0.010464809834957123,0.009614413604140282,0.008780314587056637,0.007963077165186405,0.007163353264331818,0.0063819061033427715,0.005619642324745655,0.004877655766904354,0.004157294984906912,0.003460264764726162,0.0027887988835573196,0.0021459676790982485,0.001536299823783338,0.0009672692976891994,0.0004541343660093844]);G=$toNativeArray($kindUint32,[1991057938,0,1611602771,1826899878,1918584482,1969227037,2001281515,2023368125,2039498179,2051788381,2061460127,2069267110,2075699398,2081089314,2085670119,2089610331,2093034710,2096037586,2098691595,2101053571,2103168620,2105072996,2106796166,2108362327,2109791536,2111100552,2112303493,2113412330,2114437283,2115387130,2116269447,2117090813,2117856962,2118572919,2119243101,2119871411,2120461303,2121015852,2121537798,2122029592,2122493434,2122931299,2123344971,2123736059,2124106020,2124456175,2124787725,2125101763,2125399283,2125681194,2125948325,2126201433,2126441213,2126668298,2126883268,2127086657,2127278949,2127460589,2127631985,2127793506,2127945490,2128088244,2128222044,2128347141,2128463758,2128572095,2128672327,2128764606,2128849065,2128925811,2128994934,2129056501,2129110560,2129157136,2129196237,2129227847,2129251929,2129268426,2129277255,2129278312,2129271467,2129256561,2129233410,2129201800,2129161480,2129112170,2129053545,2128985244,2128906855,2128817916,2128717911,2128606255,2128482298,2128345305,2128194452,2128028813,2127847342,2127648860,2127432031,2127195339,2126937058,2126655214,2126347546,2126011445,2125643893,2125241376,2124799783,2124314271,2123779094,2123187386,2122530867,2121799464,2120980787,2120059418,2119015917,2117825402,2116455471,2114863093,2112989789,2110753906,2108037662,2104664315,2100355223,2094642347,2086670106,2074676188,2054300022,2010539237]);H=$toNativeArray($kindFloat32,[1.7290404663583558e-09,1.2680928529462676e-10,1.689751810696194e-10,1.9862687883343e-10,2.223243117382978e-10,2.4244936613904144e-10,2.601613091623989e-10,2.761198769629658e-10,2.9073962681813725e-10,3.042996965518796e-10,3.169979556627567e-10,3.289802041894774e-10,3.4035738116777736e-10,3.5121602848242617e-10,3.61625090983253e-10,3.7164057942185025e-10,3.813085680537398e-10,3.906675816178762e-10,3.997501218933053e-10,4.0858399996679395e-10,4.1719308563337165e-10,4.255982233303257e-10,4.3381759295968436e-10,4.4186720948857783e-10,4.497613115272969e-10,4.57512583373898e-10,4.6513240481438345e-10,4.726310454117311e-10,4.800177477726209e-10,4.873009773476156e-10,4.944885056978876e-10,5.015873272284921e-10,5.086040477664255e-10,5.155446070048697e-10,5.224146670812502e-10,5.292193350214802e-10,5.359634958068682e-10,5.426517013518151e-10,5.492881705038144e-10,5.558769555769061e-10,5.624218868405251e-10,5.689264614971989e-10,5.75394121238304e-10,5.818281967329142e-10,5.882316855831959e-10,5.946076964136182e-10,6.009590047817426e-10,6.072883862451306e-10,6.135985053390414e-10,6.19892026598734e-10,6.261713370037114e-10,6.324390455780815e-10,6.386973727678935e-10,6.449488165749528e-10,6.511955974453087e-10,6.574400468473129e-10,6.636843297158634e-10,6.699307220081607e-10,6.761814441702541e-10,6.824387166481927e-10,6.887046488657234e-10,6.949815167800466e-10,7.012714853260604e-10,7.075767749498141e-10,7.13899661608508e-10,7.202424212593428e-10,7.266072743483676e-10,7.329966078550854e-10,7.394128087589991e-10,7.458582640396116e-10,7.523354716987285e-10,7.588469852493063e-10,7.653954137154528e-10,7.719834771435785e-10,7.786139510912449e-10,7.852897221383159e-10,7.920137878869582e-10,7.987892014504894e-10,8.056192379868321e-10,8.125072836762115e-10,8.194568912323064e-10,8.264716688799467e-10,8.3355555791087e-10,8.407127216614185e-10,8.479473234679347e-10,8.552640262671218e-10,8.626675485068347e-10,8.701631637464402e-10,8.777562010564566e-10,8.854524335966119e-10,8.932581896381464e-10,9.011799639857543e-10,9.092249730890956e-10,9.174008219758889e-10,9.25715837318819e-10,9.341788453909317e-10,9.42799727177146e-10,9.515889187738935e-10,9.605578554783278e-10,9.697193048552322e-10,9.790869226478094e-10,9.886760299337993e-10,9.985036131254788e-10,1.008588212947359e-09,1.0189509236369076e-09,1.0296150598776421e-09,1.040606933955246e-09,1.0519566329136865e-09,1.0636980185552147e-09,1.0758701707302976e-09,1.0885182755160372e-09,1.101694735439196e-09,1.115461056855338e-09,1.1298901814171813e-09,1.1450695946990663e-09,1.1611052119775422e-09,1.178127595480305e-09,1.1962995039027646e-09,1.2158286599728285e-09,1.2369856250415978e-09,1.2601323318151003e-09,1.2857697129220469e-09,1.3146201904845611e-09,1.3477839955200466e-09,1.3870635751089821e-09,1.43574030442295e-09,1.5008658760251592e-09,1.6030947680434338e-09]);I=$toNativeArray($kindFloat32,[1,0.963599681854248,0.9362826943397522,0.9130436182022095,0.8922816514968872,0.8732430338859558,0.8555005788803101,0.8387836217880249,0.8229072093963623,0.8077383041381836,0.7931770086288452,0.7791460752487183,0.7655841708183289,0.7524415850639343,0.7396772503852844,0.7272568941116333,0.7151514887809753,0.7033361196517944,0.6917891502380371,0.6804918646812439,0.6694276928901672,0.6585819721221924,0.6479418277740479,0.6374954581260681,0.6272324919700623,0.6171433925628662,0.6072195172309875,0.5974531769752502,0.5878370404243469,0.5783646702766418,0.5690299868583679,0.5598273873329163,0.550751805305481,0.5417983531951904,0.5329626798629761,0.5242405533790588,0.5156282186508179,0.5071220397949219,0.49871864914894104,0.4904148280620575,0.48220765590667725,0.47409430146217346,0.466072142124176,0.45813870429992676,0.45029163360595703,0.44252872467041016,0.4348478317260742,0.42724698781967163,0.41972434520721436,0.41227802634239197,0.40490642189979553,0.39760786294937134,0.3903807997703552,0.3832238018512726,0.3761354684829712,0.3691144585609436,0.36215949058532715,0.3552693724632263,0.3484429717063904,0.3416791558265686,0.33497685194015503,0.32833510637283325,0.3217529058456421,0.3152293860912323,0.30876362323760986,0.3023548424243927,0.2960021495819092,0.2897048592567444,0.28346219658851624,0.2772735059261322,0.271138072013855,0.2650552988052368,0.25902456045150757,0.25304529070854187,0.24711695313453674,0.24123899638652802,0.23541094362735748,0.22963231801986694,0.22390270233154297,0.21822164952754974,0.21258877217769623,0.20700371265411377,0.20146611332893372,0.1959756463766098,0.19053204357624054,0.18513499200344086,0.17978426814079285,0.1744796335697174,0.16922089457511902,0.16400785744190216,0.1588403731584549,0.15371830761432648,0.14864157140254974,0.14361007511615753,0.13862377405166626,0.13368265330791473,0.12878671288490295,0.12393598258495331,0.11913054436445236,0.11437050998210907,0.10965602099895477,0.1049872562289238,0.10036443918943405,0.09578784555196762,0.09125780314207077,0.08677466958761215,0.08233889937400818,0.07795098423957825,0.07361150532960892,0.06932111829519272,0.06508058309555054,0.06089077144861221,0.05675266310572624,0.05266740173101425,0.048636294901371,0.044660862535238266,0.040742866694927216,0.03688438981771469,0.03308788686990738,0.029356317594647408,0.025693291798233986,0.02210330404341221,0.018592102453112602,0.015167297795414925,0.011839478276669979,0.0086244847625494,0.005548994988203049,0.0026696291752159595]);AH=$toNativeArray($kindInt64,[new $Int64(-973649357,3952672746),new $Int64(-1065661887,3130416987),new $Int64(324977939,3414273807),new $Int64(1241840476,2806224363),new $Int64(-1477934308,1997590414),new $Int64(2103305448,2402795971),new $Int64(1663160183,1140819369),new $Int64(1120601685,1788868961),new $Int64(1848035537,1089001426),new $Int64(1235702047,873593504),new $Int64(1911387977,581324885),new $Int64(-1654874170,1609182556),new $Int64(1069394745,1241596776),new $Int64(1895445337,1771189259),new $Int64(-1374618802,3467012610),new $Int64(-140526423,2344407434),new $Int64(-1745367887,782467244),new $Int64(26335124,3404933915),new $Int64(1063924276,618867887),new $Int64(-968700782,520164395),new $Int64(-1591572833,1341358184),new $Int64(-1515085039,665794848),new $Int64(1527227641,3183648150),new $Int64(1781176124,696329606),new $Int64(1789146075,4151988961),new $Int64(-2087444114,998951326),new $Int64(-612324923,1364957564),new $Int64(63173359,4090230633),new $Int64(-1498029007,4009697548),new $Int64(248009524,2569622517),new $Int64(778703922,3742421481),new $Int64(-1109106023,1506914633),new $Int64(1738099768,1983412561),new $Int64(236311649,1436266083),new $Int64(-1111517500,3922894967),new $Int64(-1336974714,1792680179),new $Int64(563141142,1188796351),new $Int64(1349617468,405968250),new $Int64(1044074554,433754187),new $Int64(870549669,4073162024),new $Int64(-1094251604,433121399),new $Int64(2451824,4162580594),new $Int64(-137262572,4132415622),new $Int64(-1536231048,3033822028),new $Int64(2016407895,824682382),new $Int64(2366218,3583765414),new $Int64(-624604839,535386927),new $Int64(1637219058,2286693689),new $Int64(1453075389,2968466525),new $Int64(193683513,1351410206),new $Int64(-283806096,1412813499),new $Int64(492736522,4126267639),new $Int64(512765208,2105529399),new $Int64(2132966268,2413882233),new $Int64(947457634,32226200),new $Int64(1149341356,2032329073),new $Int64(106485445,1356518208),new $Int64(-2067810156,3430061722),new $Int64(-1484435135,3820169661),new $Int64(-1665985194,2981816134),new $Int64(1017155588,4184371017),new $Int64(206574701,2119206761),new $Int64(-852109057,2472200560),new $Int64(-560457548,2853524696),new $Int64(1307803389,1681119904),new $Int64(-174986835,95608918),new $Int64(392686347,3690479145),new $Int64(-1205570926,1397922290),new $Int64(-1159314025,1516129515),new $Int64(-320178155,1547420459),new $Int64(1311333971,1470949486),new $Int64(-1953469798,1336785672),new $Int64(-45086614,4131677129),new $Int64(-1392278100,4246329084),new $Int64(-1142500187,3788585631),new $Int64(-66478285,3080389532),new $Int64(-646438364,2215402037),new $Int64(391002300,1171593935),new $Int64(1408774047,1423855166),new $Int64(-519177718,2276716302),new $Int64(-368453140,2068027241),new $Int64(1369359303,3427553297),new $Int64(189241615,3289637845),new $Int64(1057480830,3486407650),new $Int64(-1512910664,3071877822),new $Int64(1159653919,3363620705),new $Int64(-934256930,4159821533),new $Int64(-76621938,1894661),new $Int64(-674493898,1156868282),new $Int64(348271067,776219088),new $Int64(-501428838,2425634259),new $Int64(1716021749,680510161),new $Int64(-574263456,1310101429),new $Int64(1095885995,2964454134),new $Int64(-325695512,3467098407),new $Int64(1990672920,2109628894),new $Int64(-2139648704,1232604732),new $Int64(-1838070714,3261916179),new $Int64(1699175360,434597899),new $Int64(235436061,1624796439),new $Int64(-1626402839,3589632480),new $Int64(1198416575,864579159),new $Int64(-1938748161,1380889830),new $Int64(619206309,2654509477),new $Int64(1419738251,1468209306),new $Int64(-1744284772,100794388),new $Int64(-1191421458,2991674471),new $Int64(-208666741,2224662036),new $Int64(-173659161,977097250),new $Int64(1351320195,726419512),new $Int64(-183459897,1747974366),new $Int64(-753095183,1556430604),new $Int64(-1049492215,1080776742),new $Int64(-385846958,280794874),new $Int64(117767733,919835643),new $Int64(-967009426,3434019658),new $Int64(-1951414480,2461941785),new $Int64(133215641,3615001066),new $Int64(417204809,3103414427),new $Int64(790056561,3380809712),new $Int64(-1267681408,2724693469),new $Int64(547796833,598827710),new $Int64(-1846559452,3452273442),new $Int64(-75778224,649274915),new $Int64(-801301329,2585724112),new $Int64(-1510934263,3165579553),new $Int64(1185578221,2635894283),new $Int64(-52910178,2053289721),new $Int64(985976581,3169337108),new $Int64(1170569632,144717764),new $Int64(1079216270,1383666384),new $Int64(-124804942,681540375),new $Int64(1375448925,537050586),new $Int64(-1964768344,315246468),new $Int64(226402871,849323088),new $Int64(-885062465,45543944),new $Int64(-946445250,2319052083),new $Int64(-40708194,3613090841),new $Int64(560472520,2992171180),new $Int64(-381863169,2068244785),new $Int64(917538188,4239862634),new $Int64(-1369555809,3892253031),new $Int64(720683925,958186149),new $Int64(-423297785,1877702262),new $Int64(1357886971,837674867),new $Int64(1837048883,1507589294),new $Int64(1905518400,873336795),new $Int64(-1879761037,2764496274),new $Int64(-1806480530,4196182374),new $Int64(-1066765755,550964545),new $Int64(818747069,420611474),new $Int64(-1924830376,204265180),new $Int64(1549974541,1787046383),new $Int64(1215581865,3102292318),new $Int64(418321538,1552199393),new $Int64(1243493047,980542004),new $Int64(267284263,3293718720),new $Int64(1179528763,3771917473),new $Int64(599484404,2195808264),new $Int64(252818753,3894702887),new $Int64(-1367475956,2099949527),new $Int64(1424094358,338442522),new $Int64(490737398,637158004),new $Int64(-1727621530,281976339),new $Int64(574970164,3619802330),new $Int64(-431930823,3084554784),new $Int64(-1264611183,4129772886),new $Int64(-2104399043,1680378557),new $Int64(-1621962591,3339087776),new $Int64(1680500332,4220317857),new $Int64(-1935828963,2959322499),new $Int64(1675600481,1488354890),new $Int64(-834863562,3958162143),new $Int64(-1226511573,2773705983),new $Int64(1876039582,225908689),new $Int64(-1183735113,908216283),new $Int64(-605696219,3574646075),new $Int64(-1827723091,1936937569),new $Int64(1519770881,75492235),new $Int64(816689472,1935193178),new $Int64(2142521206,2018250883),new $Int64(455141620,3943126022),new $Int64(-601399488,3066544345),new $Int64(1932392669,2793082663),new $Int64(-1239009361,3297036421),new $Int64(1640597065,2206987825),new $Int64(-553246738,807894872),new $Int64(-1781325307,766252117),new $Int64(2060649606,3833114345),new $Int64(845619743,1255067973),new $Int64(1201145605,741697208),new $Int64(-1476242608,2810093753),new $Int64(1109032642,4229340371),new $Int64(1462188720,1361684224),new $Int64(-1159399429,1906263026),new $Int64(475781207,3904421704),new $Int64(-623537128,1769075545),new $Int64(1062308525,2621599764),new $Int64(1279509432,3431891480),new $Int64(-1742751146,1871896503),new $Int64(128756421,1412808876),new $Int64(1605404688,952876175),new $Int64(-230443691,1824438899),new $Int64(1662295856,1005035476),new $Int64(-156574141,527508597),new $Int64(1288873303,3066806859),new $Int64(565995893,3244940914),new $Int64(-889746188,209092916),new $Int64(-247669406,1242699167),new $Int64(-713830396,456723774),new $Int64(1776978905,1001252870),new $Int64(1468772157,2026725874),new $Int64(857254202,2137562569),new $Int64(765939740,3183366709),new $Int64(1533887628,2612072960),new $Int64(56977098,1727148468),new $Int64(-1197583895,3803658212),new $Int64(1883670356,479946959),new $Int64(685713571,1562982345),new $Int64(-1946242443,1766109365),new $Int64(700596547,3257093788),new $Int64(-184714929,2365720207),new $Int64(93384808,3742754173),new $Int64(-458385235,2878193673),new $Int64(1096135042,2174002182),new $Int64(-834260953,3573511231),new $Int64(-754572527,1760299077),new $Int64(-1375627191,2260779833),new $Int64(-866019274,1452805722),new $Int64(-1229671918,2940011802),new $Int64(1890251082,1886183802),new $Int64(893897673,2514369088),new $Int64(1644345561,3924317791),new $Int64(-1974867432,500935732),new $Int64(1403501753,676580929),new $Int64(-1565912283,1184984890),new $Int64(-691968413,1271474274),new $Int64(-1828754738,3163791473),new $Int64(2051027584,2842487377),new $Int64(1511537551,2170968612),new $Int64(573262976,3535856740),new $Int64(-2053227187,1488599718),new $Int64(-1180531831,3408913763),new $Int64(-2086531912,2501050084),new $Int64(-875130448,1639124157),new $Int64(-2009482504,4088176393),new $Int64(1574896563,3989947576),new $Int64(-165243708,3414355209),new $Int64(-792329287,2275136352),new $Int64(-2057774345,2151835223),new $Int64(-931144933,1654534827),new $Int64(-679921451,377892833),new $Int64(-482716010,660204544),new $Int64(85706799,390828249),new $Int64(-1422172693,3402783878),new $Int64(-1468634160,3717936603),new $Int64(1113532086,2211058823),new $Int64(1564224320,2692150867),new $Int64(1952770442,1928910388),new $Int64(788716862,3931011137),new $Int64(1083670504,1112701047),new $Int64(-68150572,2452299106),new $Int64(-896164822,2337204777),new $Int64(1774877857,273889282),new $Int64(1798719843,1462008793),new $Int64(2138834788,1554494002),new $Int64(-1194967131,182675323),new $Int64(-1598554764,1882802136),new $Int64(589279648,3700220025),new $Int64(381039426,3083431543),new $Int64(-851859191,3622207527),new $Int64(338126939,432729309),new $Int64(-1667470126,2391914317),new $Int64(-1849558151,235747924),new $Int64(2120733629,3088823825),new $Int64(-745079795,2314658321),new $Int64(1165929723,2957634338),new $Int64(501323675,4117056981),new $Int64(1564699815,1482500298),new $Int64(-740826490,840489337),new $Int64(799522364,3483178565),new $Int64(532129761,2074004656),new $Int64(724246478,3643392642),new $Int64(-665153481,1583624461),new $Int64(-885822954,287473085),new $Int64(1667835381,3136843981),new $Int64(1138806821,1266970974),new $Int64(135185781,1998688839),new $Int64(392094735,1492900209),new $Int64(1031326774,1538112737),new $Int64(-2070568842,2207265429),new $Int64(-1886797613,963263315),new $Int64(1671145500,2295892134),new $Int64(1068469660,2002560897),new $Int64(-356250305,1369254035),new $Int64(33436120,3353312708),new $Int64(57507843,947771099),new $Int64(-1945755145,1747061399),new $Int64(1507240140,2047354631),new $Int64(720000810,4165367136),new $Int64(479265078,3388864963),new $Int64(-952181250,286492130),new $Int64(2045622690,2795735007),new $Int64(-715730566,3703961339),new $Int64(-148436487,1797825479),new $Int64(1429039600,1116589674),new $Int64(-1665420098,2593309206),new $Int64(1329049334,3404995677),new $Int64(-750579440,3453462936),new $Int64(1014767077,3016498634),new $Int64(75698599,1650371545),new $Int64(1592007860,212344364),new $Int64(1127766888,3843932156),new $Int64(-748019856,3573129983),new $Int64(-890581831,665897820),new $Int64(1071492673,1675628772),new $Int64(243225682,2831752928),new $Int64(2120298836,1486294219),new $Int64(-1954407413,268782709),new $Int64(-1002123503,4186179080),new $Int64(624342951,1613720397),new $Int64(857179861,2703686015),new $Int64(-911618704,2205342611),new $Int64(-672703993,1411666394),new $Int64(-1528454899,677744900),new $Int64(-1876628533,4172867247),new $Int64(135494707,2163418403),new $Int64(849547544,2841526879),new $Int64(-1117516959,1082141470),new $Int64(-1770111792,4046134367),new $Int64(51415528,2142943655),new $Int64(-249824333,3124627521),new $Int64(998228909,219992939),new $Int64(-1078790951,1756846531),new $Int64(1283749206,1225118210),new $Int64(-525858006,1647770243),new $Int64(-2035959705,444807907),new $Int64(2036369448,3952076173),new $Int64(53201823,1461839639),new $Int64(315761893,3699250910),new $Int64(702974850,1373688981),new $Int64(734022261,147523747),new $Int64(-2047330906,1211276581),new $Int64(1294440951,2548832680),new $Int64(1144696256,1995631888),new $Int64(-1992983070,2011457303),new $Int64(-1351022674,3057425772),new $Int64(667839456,81484597),new $Int64(-1681980888,3646681560),new $Int64(-1372462725,635548515),new $Int64(602489502,2508044581),new $Int64(-1794220117,1014917157),new $Int64(719992433,3214891315),new $Int64(-1294799037,959582252),new $Int64(226415134,3347040449),new $Int64(-362868096,4102971975),new $Int64(397887437,4078022210),new $Int64(-536803826,2851767182),new $Int64(-1398321012,1540160644),new $Int64(-1549098876,1057290595),new $Int64(-112592988,3907769253),new $Int64(579300318,4248952684),new $Int64(-1054576049,132554364),new $Int64(-1085862414,1029351092),new $Int64(697840928,2583007416),new $Int64(298619124,1486185789),new $Int64(55905697,2871589073),new $Int64(2017643612,723203291),new $Int64(146250550,2494333952),new $Int64(-1082993397,2230939180),new $Int64(-1804568072,3943232912),new $Int64(1768732449,2181367922),new $Int64(-729261111,2889274791),new $Int64(1824032949,2046728161),new $Int64(1653899792,1376052477),new $Int64(1022327048,381236993),new $Int64(-1113097690,3188942166),new $Int64(-74480109,350070824),new $Int64(144881592,61758415),new $Int64(-741824226,3492950336),new $Int64(-2030042720,3093818430),new $Int64(-453590535,2962480613),new $Int64(-1912050708,3154871160),new $Int64(-1636478569,3228564679),new $Int64(610731502,888276216),new $Int64(-946702974,3574998604),new $Int64(-1277068380,1967526716),new $Int64(-1556147941,1554691298),new $Int64(-1573024234,339944798),new $Int64(1223764147,1154515356),new $Int64(1825645307,967516237),new $Int64(1546195135,596588202),new $Int64(-1867600880,3764362170),new $Int64(-1655392592,266611402),new $Int64(-393255880,2047856075),new $Int64(-1000726433,21444105),new $Int64(-949424754,3065563181),new $Int64(-232418803,1140663212),new $Int64(633187674,2323741028),new $Int64(2126290159,3103873707),new $Int64(1008658319,2766828349),new $Int64(-485587503,1970872996),new $Int64(1628585413,3766615585),new $Int64(-595148528,2036813414),new $Int64(-1994877121,3105536507),new $Int64(13954645,3396176938),new $Int64(-721402003,1377154485),new $Int64(-61839181,3807014186),new $Int64(543009040,3710110597),new $Int64(-1751425519,916420443),new $Int64(734556788,2103831255),new $Int64(-1766161494,717331943),new $Int64(-1574598896,3550505941),new $Int64(45939673,378749927),new $Int64(-1997615719,611017331),new $Int64(592130075,758907650),new $Int64(1012992349,154266815),new $Int64(-1040454942,1407468696),new $Int64(-1678191250,970098704),new $Int64(-285057486,1971660656),new $Int64(998365243,3332747885),new $Int64(1947089649,1935189867),new $Int64(1510248801,203520055),new $Int64(-1305165746,3916463034),new $Int64(-388598655,3474113316),new $Int64(1036101639,316544223),new $Int64(-1773744891,1650844677),new $Int64(-907191419,4267565603),new $Int64(-1070275024,2501167616),new $Int64(-1520651863,3929401789),new $Int64(-2091360852,337170252),new $Int64(-960502090,2061966842),new $Int64(-304190848,2508461464),new $Int64(-1941471116,2791377107),new $Int64(1240791848,1227227588),new $Int64(1813978778,1709681848),new $Int64(1153692192,3768820575),new $Int64(-1002297449,2887126398),new $Int64(-1447111334,296561685),new $Int64(700300844,3729960077),new $Int64(-1572311344,372833036),new $Int64(2078875613,2409779288),new $Int64(1829161290,555274064),new $Int64(-1105595719,4239804901),new $Int64(1839403216,3723486978),new $Int64(-1649093095,2145871984),new $Int64(-1582765715,3565480803),new $Int64(-1568653827,2197313814),new $Int64(974785092,3613674566),new $Int64(438638731,3042093666),new $Int64(-96556264,3324034321),new $Int64(869420878,3708873369),new $Int64(946682149,1698090092),new $Int64(1618900382,4213940712),new $Int64(-1843479747,2087477361),new $Int64(-1766167800,2407950639),new $Int64(-1296225558,3942568569),new $Int64(-1223900450,4088074412),new $Int64(723260036,2964773675),new $Int64(-673921829,1539178386),new $Int64(1062961552,2694849566),new $Int64(460977733,2120273838),new $Int64(-1604570740,2484608657),new $Int64(880846449,2956190677),new $Int64(1970902366,4223313749),new $Int64(662161910,3502682327),new $Int64(705634754,4133891139),new $Int64(-1031359300,1166449596),new $Int64(1038247601,3362705993),new $Int64(93734798,3892921029),new $Int64(1876124043,786869787),new $Int64(1057490746,1046342263),new $Int64(242763728,493777327),new $Int64(-853573201,3304827646),new $Int64(616460742,125356352),new $Int64(499300063,74094113),new $Int64(-795586925,2500816079),new $Int64(-490248444,514015239),new $Int64(1377565129,543520454),new $Int64(-2039776725,3614531153),new $Int64(2056746300,2356753985),new $Int64(1390062617,2018141668),new $Int64(131272971,2087974891),new $Int64(-1502927041,3166972343),new $Int64(372256200,1517638666),new $Int64(-935275664,173466846),new $Int64(-695774461,4241513471),new $Int64(-1413550842,2783126920),new $Int64(1972004134,4167264826),new $Int64(29260506,3907395640),new $Int64(-910901561,1539634186),new $Int64(-595957298,178241987),new $Int64(-113277636,182168164),new $Int64(-1102530459,2386154934),new $Int64(1379126408,4077374341),new $Int64(-2114679722,1732699140),new $Int64(-421057745,1041306002),new $Int64(1860414813,2068001749),new $Int64(1005320202,3208962910),new $Int64(844054010,697710380),new $Int64(-1509359403,2228431183),new $Int64(-810313977,3554678728),new $Int64(-750989047,173470263),new $Int64(-85886265,3848297795),new $Int64(-926936977,246236185),new $Int64(-1984190461,2066374846),new $Int64(1771673660,312890749),new $Int64(703378057,3573310289),new $Int64(-598851901,143166754),new $Int64(613554316,2081511079),new $Int64(1197802104,486038032),new $Int64(-1906483789,2982218564),new $Int64(364901986,1000939191),new $Int64(1902782651,2750454885),new $Int64(-671844857,3375313137),new $Int64(-1643868040,881302957),new $Int64(-1508784745,2514186393),new $Int64(-1703622845,360024739),new $Int64(1399671872,292500025),new $Int64(1381210821,2276300752),new $Int64(521803381,4069087683),new $Int64(-1938982667,1637778212),new $Int64(720490469,1676670893),new $Int64(1067262482,3855174429),new $Int64(2114075974,2067248671),new $Int64(-89426259,2884561259),new $Int64(-805741095,2456511185),new $Int64(983726246,561175414),new $Int64(-1719489563,432588903),new $Int64(885133709,4059399550),new $Int64(-93096266,1075014784),new $Int64(-1733832628,2728058415),new $Int64(1839142064,1299703678),new $Int64(1262333188,2347583393),new $Int64(1285481956,2468164145),new $Int64(-1158354011,1140014346),new $Int64(2033889184,1936972070),new $Int64(-1737578993,3870530098),new $Int64(-484494257,1717789158),new $Int64(-232997156,1153452491),new $Int64(-990424416,3948827651),new $Int64(-1357145630,2101413152),new $Int64(1495744672,3854091229),new $Int64(83644069,4215565463),new $Int64(-1385277313,1202710438),new $Int64(-564909037,2072216740),new $Int64(705690639,2066751068),new $Int64(-2113583312,173902580),new $Int64(-741983806,142459001),new $Int64(172391592,1889151926),new $Int64(-498943125,3034199774),new $Int64(1618587731,516490102),new $Int64(93114264,3692577783),new $Int64(-2078821353,2953948865),new $Int64(-320938673,4041040923),new $Int64(-1942517976,592046130),new $Int64(-705643640,384297211),new $Int64(-2051649464,265863924),new $Int64(2101717619,1333136237),new $Int64(1499611781,1406273556),new $Int64(1074670496,426305476),new $Int64(125704633,2750898176),new $Int64(488068495,1633944332),new $Int64(2037723464,3236349343),new $Int64(-1703423246,4013676611),new $Int64(1718532237,2265047407),new $Int64(1433593806,875071080),new $Int64(-343047503,1418843655),new $Int64(2009228711,451657300),new $Int64(1229446621,1866374663),new $Int64(1653472867,1551455622),new $Int64(577191481,3560962459),new $Int64(1669204077,3347903778),new $Int64(-298327194,2675874918),new $Int64(-1831355577,2762991672),new $Int64(530492383,3689068477),new $Int64(844089962,4071997905),new $Int64(1508155730,1381702441),new $Int64(2089931018,2373284878),new $Int64(-864267462,2143983064),new $Int64(308739063,1938207195),new $Int64(1754949306,1188152253),new $Int64(1272345009,615870490),new $Int64(742653194,2662252621),new $Int64(1477718295,3839976789),new $Int64(-2091334213,306752547),new $Int64(-1426688067,2162363077),new $Int64(-57052633,2767224719),new $Int64(-1471624099,2628837712),new $Int64(1678405918,2967771969),new $Int64(1694285728,499792248),new $Int64(-1744131281,4285253508),new $Int64(962357072,2856511070),new $Int64(679471692,2526409716),new $Int64(-1793706473,1240875658),new $Int64(-914893422,2577342868),new $Int64(-1001298215,4136853496),new $Int64(-1477114974,2403540137),new $Int64(1372824515,1371410668),new $Int64(-176562048,371758825),new $Int64(-441063112,1528834084),new $Int64(-71688630,1504757260),new $Int64(-1461820072,699052551),new $Int64(-505543539,3347789870),new $Int64(1951619734,3430604759),new $Int64(2119672219,1935601723),new $Int64(966789690,834676166)]);P=N(new AG.ptr(new B.Mutex.ptr(false),$assertType(L(new $Int64(0,1)),K)));}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"net\"]=(function(){var $pkg={},$init,E,A,C,F,J,K,Q,N,O,M,G,H,D,I,P,B,L,AG,AH,AK,EE,EF,EM,EX,EY,EZ,FU,HS,HW,II,IM,IN,IO,IP,JJ,LC,NE,NG,NM,NP,NX,OE,OM,OQ,OR,OS,OT,OU,OV,OW,PM,PN,PP,QL,QM,QN,QO,QT,AI,BX,BY,BZ,CA,CB,CC,CD,DM,DZ,EA,EB,EC,ED,EG,EN,FB,FF,FG,FH,HU,IE,IF,IG,IJ,IT,c,d,e,f,g,h,i,j,k,AJ,AL,AP,CY,EK,EO,EP,EQ,ER,ES,ET,EU,EV,EW,FA,FC,FD,FE,FI,FJ,FK,FL,FM,FN,FO,FQ,FR,FT,JK,JM,JN,JP,JQ,JR,JT,JU;E=$packages[\"context\"];A=$packages[\"errors\"];C=$packages[\"github.com/gopherjs/gopherjs/js\"];F=$packages[\"internal/bytealg\"];J=$packages[\"internal/nettrace\"];K=$packages[\"internal/poll\"];Q=$packages[\"internal/singleflight\"];N=$packages[\"internal/x/net/dns/dnsmessage\"];O=$packages[\"io\"];M=$packages[\"math/rand\"];G=$packages[\"os\"];H=$packages[\"runtime\"];D=$packages[\"sort\"];I=$packages[\"sync\"];P=$packages[\"sync/atomic\"];B=$packages[\"syscall\"];L=$packages[\"time\"];AG=$pkg.policyTableEntry=$newType(0,$kindStruct,\"net.policyTableEntry\",true,\"net\",false,function(Prefix_,Precedence_,Label_){this.$val=this;if(arguments.length===0){this.Prefix=NP.nil;this.Precedence=0;this.Label=0;return;}this.Prefix=Prefix_;this.Precedence=Precedence_;this.Label=Label_;});AH=$pkg.policyTable=$newType(12,$kindSlice,\"net.policyTable\",true,\"net\",false,null);AK=$pkg.byMaskLength=$newType(12,$kindSlice,\"net.byMaskLength\",true,\"net\",false,null);EE=$pkg.Interface=$newType(0,$kindStruct,\"net.Interface\",true,\"net\",true,function(Index_,MTU_,Name_,HardwareAddr_,Flags_){this.$val=this;if(arguments.length===0){this.Index=0;this.MTU=0;this.Name=\"\";this.HardwareAddr=HS.nil;this.Flags=0;return;}this.Index=Index_;this.MTU=MTU_;this.Name=Name_;this.HardwareAddr=HardwareAddr_;this.Flags=Flags_;});EF=$pkg.Flags=$newType(4,$kindUint,\"net.Flags\",true,\"net\",true,null);EM=$pkg.ipv6ZoneCache=$newType(0,$kindStruct,\"net.ipv6ZoneCache\",true,\"net\",false,function(RWMutex_,lastFetched_,toIndex_,toName_){this.$val=this;if(arguments.length===0){this.RWMutex=new I.RWMutex.ptr(new I.Mutex.ptr(0,0),0,0,0,0);this.lastFetched=new L.Time.ptr(new $Uint64(0,0),new $Int64(0,0),NE.nil);this.toIndex=false;this.toName=false;return;}this.RWMutex=RWMutex_;this.lastFetched=lastFetched_;this.toIndex=toIndex_;this.toName=toName_;});EX=$pkg.IP=$newType(12,$kindSlice,\"net.IP\",true,\"net\",true,null);EY=$pkg.IPMask=$newType(12,$kindSlice,\"net.IPMask\",true,\"net\",true,null);EZ=$pkg.IPNet=$newType(0,$kindStruct,\"net.IPNet\",true,\"net\",true,function(IP_,Mask_){this.$val=this;if(arguments.length===0){this.IP=EX.nil;this.Mask=EY.nil;return;}this.IP=IP_;this.Mask=Mask_;});FU=$pkg.IPAddr=$newType(0,$kindStruct,\"net.IPAddr\",true,\"net\",true,function(IP_,Zone_){this.$val=this;if(arguments.length===0){this.IP=EX.nil;this.Zone=\"\";return;}this.IP=IP_;this.Zone=Zone_;});HS=$pkg.HardwareAddr=$newType(12,$kindSlice,\"net.HardwareAddr\",true,\"net\",true,null);HW=$pkg.Addr=$newType(8,$kindInterface,\"net.Addr\",true,\"net\",true,null);II=$pkg.OpError=$newType(0,$kindStruct,\"net.OpError\",true,\"net\",true,function(Op_,Net_,Source_,Addr_,Err_){this.$val=this;if(arguments.length===0){this.Op=\"\";this.Net=\"\";this.Source=$ifaceNil;this.Addr=$ifaceNil;this.Err=$ifaceNil;return;}this.Op=Op_;this.Net=Net_;this.Source=Source_;this.Addr=Addr_;this.Err=Err_;});IM=$pkg.timeout=$newType(8,$kindInterface,\"net.timeout\",true,\"net\",false,null);IN=$pkg.temporary=$newType(8,$kindInterface,\"net.temporary\",true,\"net\",false,null);IO=$pkg.ParseError=$newType(0,$kindStruct,\"net.ParseError\",true,\"net\",true,function(Type_,Text_){this.$val=this;if(arguments.length===0){this.Type=\"\";this.Text=\"\";return;}this.Type=Type_;this.Text=Text_;});IP=$pkg.AddrError=$newType(0,$kindStruct,\"net.AddrError\",true,\"net\",true,function(Err_,Addr_){this.$val=this;if(arguments.length===0){this.Err=\"\";this.Addr=\"\";return;}this.Err=Err_;this.Addr=Addr_;});JJ=$pkg.file=$newType(0,$kindStruct,\"net.file\",true,\"net\",false,function(file_,data_,atEOF_){this.$val=this;if(arguments.length===0){this.file=OM.nil;this.data=NM.nil;this.atEOF=false;return;}this.file=file_;this.data=data_;this.atEOF=atEOF_;});LC=$pkg.sockaddr=$newType(8,$kindInterface,\"net.sockaddr\",true,\"net\",false,null);NE=$ptrType(L.Location);NG=$sliceType($String);NM=$sliceType($Uint8);NP=$ptrType(EZ);NX=$ptrType(FU);OE=$ptrType(II);OM=$ptrType(G.File);OQ=$ptrType(JJ);OR=$ptrType(EE);OS=$sliceType(HW);OT=$sliceType(EE);OU=$ptrType(B.IfInfomsg);OV=$ptrType(B.IfAddrmsg);OW=$arrayType($Uint8,4);PM=$ptrType(G.SyscallError);PN=$ptrType(IP);PP=$arrayType($Uint8,20);QL=$ptrType(EM);QM=$mapType($String,$Int);QN=$mapType($Int,$String);QO=$ptrType(EX);QT=$ptrType(IO);AJ=function(){var $s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=D.Sort(D.Reverse(($subslice(new AK(AI.$array),AI.$offset,AI.$offset+AI.$length))));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AJ};}$f.$s=$s;$f.$r=$r;return $f;};AK.prototype.Len=function(){var l;l=this;return l.$length;};$ptrType(AK).prototype.Len=function(){return this.$get().Len();};AK.prototype.Swap=function(l,m){var l,m,n,o,p;n=this;o=$clone(((m<0||m>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+m]),AG);p=$clone(((l<0||l>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+l]),AG);AG.copy(((l<0||l>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+l]),o);AG.copy(((m<0||m>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+m]),p);};$ptrType(AK).prototype.Swap=function(l,m){return this.$get().Swap(l,m);};AK.prototype.Less=function(l,m){var l,m,n,o,p,q,r;n=this;o=((l<0||l>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+l]).Prefix.Mask.Size();p=o[0];q=((m<0||m>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+m]).Prefix.Mask.Size();r=q[0];return p<r;};$ptrType(AK).prototype.Less=function(l,m){return this.$get().Less(l,m);};AL=function(l){var l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:m=FT(l);n=m[0];o=m[1];p=m[2];if(!($interfaceIsEqual(p,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:q=p.Error();$s=3;case 3:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}$panic(new $String(q));case 2:if(!((n.$length===16))){$panic(new $String(\"unexpected IP length\"));}$s=-1;return o;}return;}if($f===undefined){$f={$blk:AL};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};AH.prototype.Classify=function(l){var l,m,n,o,p;m=this;n=m;o=0;while(true){if(!(o<n.$length)){break;}p=$clone(((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]),AG);if(p.Prefix.Contains(l)){return p;}o++;}return new AG.ptr(NP.nil,0,0);};$ptrType(AH).prototype.Classify=function(l){return this.$get().Classify(l);};AP=function(){HU=true;};CY=function(l){var l,m,n,o;m=$assertType(l,B.Errno,true);n=m[0];o=m[1];if(o){return(n===104)||(n===103);}return false;};EF.prototype.String=function(){var l,m,n,o,p,q,r;l=this.$val;m=\"\";n=EG;o=0;while(true){if(!(o<n.$length)){break;}p=o;q=((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]);if(!((((l&(((r=((p>>>0)),r<32?(1<<r):0)>>>0)))>>>0)===0))){if(!(m===\"\")){m=m+(\"|\");}m=m+(q);}o++;}if(m===\"\"){m=\"0\";}return m;};$ptrType(EF).prototype.String=function(){return new EF(this.$get()).String();};EE.ptr.prototype.Addrs=function(){var l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(l===OR.nil){$s=-1;return[OS.nil,new II.ptr(\"route\",\"ip+net\",$ifaceNil,$ifaceNil,DZ)];}n=ER(l);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];if(!($interfaceIsEqual(p,$ifaceNil))){p=new II.ptr(\"route\",\"ip+net\",$ifaceNil,$ifaceNil,p);}$s=-1;return[o,p];}return;}if($f===undefined){$f={$blk:EE.ptr.prototype.Addrs};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};EE.prototype.Addrs=function(){return this.$val.Addrs();};EE.ptr.prototype.MulticastAddrs=function(){var l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(l===OR.nil){$s=-1;return[OS.nil,new II.ptr(\"route\",\"ip+net\",$ifaceNil,$ifaceNil,DZ)];}n=EU(l);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];if(!($interfaceIsEqual(p,$ifaceNil))){p=new II.ptr(\"route\",\"ip+net\",$ifaceNil,$ifaceNil,p);}$s=-1;return[o,p];}return;}if($f===undefined){$f={$blk:EE.ptr.prototype.MulticastAddrs};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};EE.prototype.MulticastAddrs=function(){return this.$val.MulticastAddrs();};EK=function(l,m){var l,m,n,o,p;n=l;o=0;while(true){if(!(o<n.$length)){break;}p=$clone(((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]),EE);if(m===p.Index){return[p,$ifaceNil];}o++;}return[OR.nil,EC];};EO=function(l){var aa,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:m=[m];o=B.NetlinkRIB(18,0);$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;p=n[0];q=n[1];if(!($interfaceIsEqual(q,$ifaceNil))){$s=-1;return[OT.nil,G.NewSyscallError(\"netlinkrib\",q)];}r=B.ParseNetlinkMessage(p);s=r[0];q=r[1];if(!($interfaceIsEqual(q,$ifaceNil))){$s=-1;return[OT.nil,G.NewSyscallError(\"parsenetlinkmessage\",q)];}t=OT.nil;u=s;v=0;loop:while(true){if(!(v<u.$length)){break;}m[0]=$clone(((v<0||v>=u.$length)?($throwRuntimeError(\"index out of range\"),undefined):u.$array[u.$offset+v]),B.NetlinkMessage);w=m[0].Header.Type;if(w===(3)){break loop;}else if(w===(16)){x=($pointerOfStructConversion(($sliceToArray(m[0].Data)),OU));if((l===0)||(l===((x.Index>>0)))){y=B.ParseNetlinkRouteAttr(m[0]);z=y[0];aa=y[1];if(!($interfaceIsEqual(aa,$ifaceNil))){$s=-1;return[OT.nil,G.NewSyscallError(\"parsenetlinkrouteattr\",aa)];}t=$append(t,EP(x,z));if(l===((x.Index>>0))){break loop;}}}v++;}$s=-1;return[t,$ifaceNil];}return;}if($f===undefined){$f={$blk:EO};}$f.aa=aa;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};EP=function(l,m){var aa,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;n=new EE.ptr(((l.Index>>0)),0,\"\",HS.nil,EQ(l.Flags));o=m;p=0;while(true){if(!(p<o.$length)){break;}q=$clone(((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]),B.NetlinkRouteAttr);r=q.Attr.Type;if(r===(1)){s=q.Value.$length;if(s===(4)){t=l.Type;if((t===(768))||(t===(778))||(t===(776))){p++;continue;}}else if(s===(16)){u=l.Type;if((u===(769))||(u===(823))){p++;continue;}}v=false;w=q.Value;x=0;while(true){if(!(x<w.$length)){break;}y=((x<0||x>=w.$length)?($throwRuntimeError(\"index out of range\"),undefined):w.$array[w.$offset+x]);if(!((y===0))){v=true;break;}x++;}if(v){n.HardwareAddr=(z=q.Value,$subslice(new HS(z.$array),z.$offset,z.$offset+z.$length));}}else if(r===(3)){n.Name=($bytesToString($subslice(q.Value,0,(q.Value.$length-1>>0))));}else if(r===(4)){n.MTU=(((aa=$subslice(q.Value,0,4),(0>=aa.$length?($throwRuntimeError(\"index out of range\"),undefined):aa.$array[aa.$offset+0]))>>0));}p++;}return n;};EQ=function(l){var l,m;m=0;if(!((((l&1)>>>0)===0))){m=(m|(1))>>>0;}if(!((((l&2)>>>0)===0))){m=(m|(2))>>>0;}if(!((((l&8)>>>0)===0))){m=(m|(4))>>>0;}if(!((((l&16)>>>0)===0))){m=(m|(8))>>>0;}if(!((((l&4096)>>>0)===0))){m=(m|(16))>>>0;}return m;};ER=function(l){var l,m,n,o,p,q,r,s,t,u,v,w,x,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:n=B.NetlinkRIB(22,0);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];if(!($interfaceIsEqual(p,$ifaceNil))){$s=-1;return[OS.nil,G.NewSyscallError(\"netlinkrib\",p)];}q=B.ParseNetlinkMessage(o);r=q[0];p=q[1];if(!($interfaceIsEqual(p,$ifaceNil))){$s=-1;return[OS.nil,G.NewSyscallError(\"parsenetlinkmessage\",p)];}s=OT.nil;if(l===OR.nil){$s=2;continue;}$s=3;continue;case 2:t=$ifaceNil;v=EO(0);$s=4;case 4:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}u=v;s=u[0];t=u[1];if(!($interfaceIsEqual(t,$ifaceNil))){$s=-1;return[OS.nil,t];}case 3:w=ES(s,l,r);x=w[0];p=w[1];if(!($interfaceIsEqual(p,$ifaceNil))){$s=-1;return[OS.nil,p];}$s=-1;return[x,$ifaceNil];}return;}if($f===undefined){$f={$blk:ER};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.$s=$s;$f.$r=$r;return $f;};ES=function(l,m,n){var l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;o=OS.nil;p=n;q=0;loop:while(true){if(!(q<p.$length)){break;}r=$clone(((q<0||q>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+q]),B.NetlinkMessage);s=r.Header.Type;if(s===(3)){break loop;}else if(s===(20)){t=($pointerOfStructConversion(($sliceToArray(r.Data)),OV));if(!((l.$length===0))||(m.Index===((t.Index>>0)))){if(!((l.$length===0))){u=$ifaceNil;v=EK(l,((t.Index>>0)));m=v[0];u=v[1];if(!($interfaceIsEqual(u,$ifaceNil))){return[OS.nil,u];}}w=B.ParseNetlinkRouteAttr(r);x=w[0];y=w[1];if(!($interfaceIsEqual(y,$ifaceNil))){return[OS.nil,G.NewSyscallError(\"parsenetlinkrouteattr\",y)];}z=ET(t,x);if(!($interfaceIsEqual(z,$ifaceNil))){o=$append(o,z);}}}q++;}return[o,$ifaceNil];};ET=function(l,m){var l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;n=false;o=m;p=0;while(true){if(!(p<o.$length)){break;}q=$clone(((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]),B.NetlinkRouteAttr);if(q.Attr.Type===2){n=true;break;}p++;}r=m;s=0;while(true){if(!(s<r.$length)){break;}t=$clone(((s<0||s>=r.$length)?($throwRuntimeError(\"index out of range\"),undefined):r.$array[r.$offset+s]),B.NetlinkRouteAttr);if(n&&(t.Attr.Type===1)){s++;continue;}u=l.Family;if(u===(2)){return new EZ.ptr(FA((v=t.Value,(0>=v.$length?($throwRuntimeError(\"index out of range\"),undefined):v.$array[v.$offset+0])),(w=t.Value,(1>=w.$length?($throwRuntimeError(\"index out of range\"),undefined):w.$array[w.$offset+1])),(x=t.Value,(2>=x.$length?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+2])),(y=t.Value,(3>=y.$length?($throwRuntimeError(\"index out of range\"),undefined):y.$array[y.$offset+3]))),FD(((l.Prefixlen>>0)),32));}else if(u===(10)){z=new EZ.ptr($makeSlice(EX,16),FD(((l.Prefixlen>>0)),128));$copySlice(z.IP,t.Value);return z;}s++;}return $ifaceNil;};EU=function(l){var l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:m=EV(\"/proc/net/igmp\",l);$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}n=m;o=EW(\"/proc/net/igmp6\",l);$s=2;case 2:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}p=o;$s=-1;return[$appendSlice(n,p),$ifaceNil];}return;}if($f===undefined){$f={$blk:EU};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};EV=function(l,m){var aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);o=JK(l);$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;p=n[0];q=n[1];if(!($interfaceIsEqual(q,$ifaceNil))){$s=-1;return OS.nil;}$deferred.push([$methodVal(p,\"close\"),[]]);r=OS.nil;s=\"\";t=p.readLine();$s=2;case 2:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}t;u=$makeSlice(NM,4);w=p.readLine();$s=3;case 3:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}v=w;x=v[0];y=v[1];case 4:if(!(y)){$s=5;continue;}z=JN(x,\" :\\r\\t\\n\");if(z.$length<4){$s=6;continue;}$s=7;continue;case 6:ab=p.readLine();$s=8;case 8:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}aa=ab;x=aa[0];y=aa[1];$s=4;continue;case 7:if(!((x.charCodeAt(0)===32))&&!((x.charCodeAt(0)===9))){s=(1>=z.$length?($throwRuntimeError(\"index out of range\"),undefined):z.$array[z.$offset+1]);}else if(((0>=z.$length?($throwRuntimeError(\"index out of range\"),undefined):z.$array[z.$offset+0]).length===8)){if(m===OR.nil||s===m.Name){ac=0;while(true){if(!((ac+1>>0)<(0>=z.$length?($throwRuntimeError(\"index out of range\"),undefined):z.$array[z.$offset+0]).length)){break;}ad=JR($substring((0>=z.$length?($throwRuntimeError(\"index out of range\"),undefined):z.$array[z.$offset+0]),ac,(ac+2>>0)),0);(ae=(af=ac/2,(af===af&&af!==1/0&&af!==-1/0)?af>>0:$throwRuntimeError(\"integer divide by zero\")),((ae<0||ae>=u.$length)?($throwRuntimeError(\"index out of range\"),undefined):u.$array[u.$offset+ae]=ad[0]));ac=ac+(2)>>0;}ah=(ag=$subslice(u,0,4),(0>=ag.$length?($throwRuntimeError(\"index out of range\"),undefined):ag.$array[ag.$offset+0]));ai=new FU.ptr(FA((((ah>>>24>>>0)<<24>>>24)),(((ah>>>16>>>0)<<24>>>24)),(((ah>>>8>>>0)<<24>>>24)),((ah<<24>>>24))),\"\");r=$append(r,ai);}}ak=p.readLine();$s=9;case 9:if($c){$c=false;ak=ak.$blk();}if(ak&&ak.$blk!==undefined){break s;}aj=ak;x=aj[0];y=aj[1];$s=4;continue;case 5:$s=-1;return r;}return;}}catch(err){$err=err;$s=-1;return OS.nil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:EV};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};EW=function(l,m){var aa,ab,ac,ad,ae,af,ag,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);o=JK(l);$s=1;case 1:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;p=n[0];q=n[1];if(!($interfaceIsEqual(q,$ifaceNil))){$s=-1;return OS.nil;}$deferred.push([$methodVal(p,\"close\"),[]]);r=OS.nil;s=$makeSlice(NM,16);u=p.readLine();$s=2;case 2:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}t=u;v=t[0];w=t[1];case 3:if(!(w)){$s=4;continue;}x=JN(v,\" \\r\\t\\n\");if(x.$length<6){$s=5;continue;}$s=6;continue;case 5:z=p.readLine();$s=7;case 7:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}y=z;v=y[0];w=y[1];$s=3;continue;case 6:if(m===OR.nil||(1>=x.$length?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+1])===m.Name){aa=0;while(true){if(!((aa+1>>0)<(2>=x.$length?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+2]).length)){break;}ab=JR($substring((2>=x.$length?($throwRuntimeError(\"index out of range\"),undefined):x.$array[x.$offset+2]),aa,(aa+2>>0)),0);(ac=(ad=aa/2,(ad===ad&&ad!==1/0&&ad!==-1/0)?ad>>0:$throwRuntimeError(\"integer divide by zero\")),((ac<0||ac>=s.$length)?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+ac]=ab[0]));aa=aa+(2)>>0;}ae=new FU.ptr(new EX([(0>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+0]),(1>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+1]),(2>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+2]),(3>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+3]),(4>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+4]),(5>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+5]),(6>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+6]),(7>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+7]),(8>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+8]),(9>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+9]),(10>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+10]),(11>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+11]),(12>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+12]),(13>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+13]),(14>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+14]),(15>=s.$length?($throwRuntimeError(\"index out of range\"),undefined):s.$array[s.$offset+15])]),\"\");r=$append(r,ae);}ag=p.readLine();$s=8;case 8:if($c){$c=false;ag=ag.$blk();}if(ag&&ag.$blk!==undefined){break s;}af=ag;v=af[0];w=af[1];$s=3;continue;case 4:$s=-1;return r;}return;}}catch(err){$err=err;$s=-1;return OS.nil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:EW};}$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};FA=function(l,m,n,o){var l,m,n,o,p;p=$makeSlice(EX,16);$copySlice(p,FB);(12>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+12]=l);(13>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+13]=m);(14>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+14]=n);(15>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+15]=o);return p;};$pkg.IPv4=FA;FC=function(l,m,n,o){var l,m,n,o,p;p=$makeSlice(EY,4);(0>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+0]=l);(1>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+1]=m);(2>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+2]=n);(3>=p.$length?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+3]=o);return p;};$pkg.IPv4Mask=FC;FD=function(l,m){var l,m,n,o,p,q,r,s;if(!((m===32))&&!((m===128))){return EY.nil;}if(l<0||l>m){return EY.nil;}o=(n=m/8,(n===n&&n!==1/0&&n!==-1/0)?n>>0:$throwRuntimeError(\"integer divide by zero\"));p=$makeSlice(EY,o);q=((l>>>0));r=0;while(true){if(!(r<o)){break;}if(q>=8){((r<0||r>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+r]=255);q=q-(8)>>>0;r=r+(1)>>0;continue;}((r<0||r>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+r]=(~(((s=q,s<32?(255>>>s):0)<<24>>>24))<<24>>>24));q=0;r=r+(1)>>0;}return p;};$pkg.CIDRMask=FD;EX.prototype.IsUnspecified=function(){var l;l=this;return l.Equal($pkg.IPv4zero)||l.Equal($pkg.IPv6unspecified);};$ptrType(EX).prototype.IsUnspecified=function(){return this.$get().IsUnspecified();};EX.prototype.IsLoopback=function(){var l,m;l=this;m=l.To4();if(!(m===EX.nil)){return(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0])===127;}return l.Equal($pkg.IPv6loopback);};$ptrType(EX).prototype.IsLoopback=function(){return this.$get().IsLoopback();};EX.prototype.IsMulticast=function(){var l,m;l=this;m=l.To4();if(!(m===EX.nil)){return(((0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0])&240)>>>0)===224;}return(l.$length===16)&&((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])===255);};$ptrType(EX).prototype.IsMulticast=function(){return this.$get().IsMulticast();};EX.prototype.IsInterfaceLocalMulticast=function(){var l;l=this;return(l.$length===16)&&((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])===255)&&((((1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1])&15)>>>0)===1);};$ptrType(EX).prototype.IsInterfaceLocalMulticast=function(){return this.$get().IsInterfaceLocalMulticast();};EX.prototype.IsLinkLocalMulticast=function(){var l,m;l=this;m=l.To4();if(!(m===EX.nil)){return((0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0])===224)&&((1>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+1])===0)&&((2>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+2])===0);}return(l.$length===16)&&((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])===255)&&((((1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1])&15)>>>0)===2);};$ptrType(EX).prototype.IsLinkLocalMulticast=function(){return this.$get().IsLinkLocalMulticast();};EX.prototype.IsLinkLocalUnicast=function(){var l,m;l=this;m=l.To4();if(!(m===EX.nil)){return((0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0])===169)&&((1>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+1])===254);}return(l.$length===16)&&((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])===254)&&((((1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1])&192)>>>0)===128);};$ptrType(EX).prototype.IsLinkLocalUnicast=function(){return this.$get().IsLinkLocalUnicast();};EX.prototype.IsGlobalUnicast=function(){var l;l=this;return((l.$length===4)||(l.$length===16))&&!l.Equal($pkg.IPv4bcast)&&!l.IsUnspecified()&&!l.IsLoopback()&&!l.IsMulticast()&&!l.IsLinkLocalUnicast();};$ptrType(EX).prototype.IsGlobalUnicast=function(){return this.$get().IsGlobalUnicast();};FE=function(l){var l,m;m=0;while(true){if(!(m<l.$length)){break;}if(!((((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m])===0))){return false;}m=m+(1)>>0;}return true;};EX.prototype.To4=function(){var l;l=this;if(l.$length===4){return l;}if((l.$length===16)&&FE($subslice(l,0,10))&&((10>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+10])===255)&&((11>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+11])===255)){return $subslice(l,12,16);}return EX.nil;};$ptrType(EX).prototype.To4=function(){return this.$get().To4();};EX.prototype.To16=function(){var l;l=this;if(l.$length===4){return FA((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0]),(1>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+1]),(2>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+2]),(3>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+3]));}if(l.$length===16){return l;}return EX.nil;};$ptrType(EX).prototype.To16=function(){return this.$get().To16();};EX.prototype.DefaultMask=function(){var l;l=this;l=l.To4();if(l===EX.nil){return EY.nil;}if((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])<128){return FF;}else if((0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])<192){return FG;}else{return FH;}};$ptrType(EX).prototype.DefaultMask=function(){return this.$get().DefaultMask();};FI=function(l){var l,m,n,o;m=l;n=0;while(true){if(!(n<m.$length)){break;}o=((n<0||n>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+n]);if(!((o===255))){return false;}n++;}return true;};EX.prototype.Mask=function(l){var l,m,n,o,p,q,r;m=this;if((l.$length===16)&&(m.$length===4)&&FI((n=$subslice(l,0,12),$subslice(new NM(n.$array),n.$offset,n.$offset+n.$length)))){l=$subslice(l,12);}if((l.$length===4)&&(m.$length===16)&&F.Equal((o=$subslice(m,0,12),$subslice(new NM(o.$array),o.$offset,o.$offset+o.$length)),FB)){m=$subslice(m,12);}p=m.$length;if(!((p===l.$length))){return EX.nil;}q=$makeSlice(EX,p);r=0;while(true){if(!(r<p)){break;}((r<0||r>=q.$length)?($throwRuntimeError(\"index out of range\"),undefined):q.$array[q.$offset+r]=((((r<0||r>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+r])&((r<0||r>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+r]))>>>0));r=r+(1)>>0;}return q;};$ptrType(EX).prototype.Mask=function(l){return this.$get().Mask(l);};FJ=function(l,m,n){var l,m,n,o,p,q,r,s,t,u,v,w;if(n<10){((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m]=(n+48<<24>>>24));return 1;}else if(n<100){(p=m+1>>0,((p<0||p>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+p]=((o=n%10,o===o?o:$throwRuntimeError(\"integer divide by zero\"))+48<<24>>>24)));((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m]=((q=n/10,(q===q&&q!==1/0&&q!==-1/0)?q>>>0:$throwRuntimeError(\"integer divide by zero\"))+48<<24>>>24));return 2;}(s=m+2>>0,((s<0||s>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+s]=((r=n%10,r===r?r:$throwRuntimeError(\"integer divide by zero\"))+48<<24>>>24)));(v=m+1>>0,((v<0||v>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+v]=((t=((u=n/10,(u===u&&u!==1/0&&u!==-1/0)?u>>>0:$throwRuntimeError(\"integer divide by zero\")))%10,t===t?t:$throwRuntimeError(\"integer divide by zero\"))+48<<24>>>24)));((m<0||m>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+m]=((w=n/100,(w===w&&w!==1/0&&w!==-1/0)?w>>>0:$throwRuntimeError(\"integer divide by zero\"))+48<<24>>>24));return 3;};EX.prototype.String=function(){var l,m,n,o,p,q,r,s,t,u,v,w,x;l=this;m=l;if(l.$length===0){return\"<nil>\";}n=m.To4();if(n.$length===4){o=$makeSlice(NM,15);p=FJ(o,0,(0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0]));((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]=46);p=p+(1)>>0;p=p+(FJ(o,p,(1>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+1])))>>0;((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]=46);p=p+(1)>>0;p=p+(FJ(o,p,(2>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+2])))>>0;((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]=46);p=p+(1)>>0;p=p+(FJ(o,p,(3>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+3])))>>0;return($bytesToString($subslice(o,0,p)));}if(!((m.$length===16))){return\"?\"+FK($subslice(new NM(l.$array),l.$offset,l.$offset+l.$length));}q=-1;r=-1;s=0;while(true){if(!(s<16)){break;}t=s;while(true){if(!(t<16&&(((t<0||t>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+t])===0)&&((u=t+1>>0,((u<0||u>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+u]))===0))){break;}t=t+(2)>>0;}if(t>s&&(t-s>>0)>(r-q>>0)){q=s;r=t;s=t;}s=s+(2)>>0;}if((r-q>>0)<=2){q=-1;r=-1;}v=$makeSlice(NM,0,39);w=0;while(true){if(!(w<16)){break;}if(w===q){v=$append(v,58,58);w=r;if(w>=16){break;}}else if(w>0){v=$append(v,58);}v=JU(v,(((((((w<0||w>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+w])>>>0))<<8>>>0))|(((x=w+1>>0,((x<0||x>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+x]))>>>0)))>>>0);w=w+(2)>>0;}return($bytesToString(v));};$ptrType(EX).prototype.String=function(){return this.$get().String();};FK=function(l){var l,m,n,o,p,q,r,s,t,u;m=$makeSlice(NM,($imul(l.$length,2)));n=l;o=0;while(true){if(!(o<n.$length)){break;}p=o;q=((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]);r=\"0123456789abcdef\".charCodeAt((q>>>4<<24>>>24));s=\"0123456789abcdef\".charCodeAt(((q&15)>>>0));(t=$imul(p,2),((t<0||t>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+t]=r));(u=($imul(p,2))+1>>0,((u<0||u>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+u]=s));o++;}return($bytesToString(m));};FL=function(l){var l;if(l.$length===0){return\"\";}return l.String();};EX.prototype.MarshalText=function(){var l;l=this;if(l.$length===0){return[(new NM($stringToBytes(\"\"))),$ifaceNil];}if(!((l.$length===4))&&!((l.$length===16))){return[NM.nil,new IP.ptr(\"invalid IP address\",FK($subslice(new NM(l.$array),l.$offset,l.$offset+l.$length)))];}return[(new NM($stringToBytes(l.String()))),$ifaceNil];};$ptrType(EX).prototype.MarshalText=function(){return this.$get().MarshalText();};$ptrType(EX).prototype.UnmarshalText=function(l){var l,m,n,o;m=this;if(l.$length===0){m.$set(EX.nil);return $ifaceNil;}n=($bytesToString(l));o=FR(n);if(o===EX.nil){return new IO.ptr(\"IP address\",n);}m.$set(o);return $ifaceNil;};EX.prototype.Equal=function(l){var l,m,n,o,p,q;m=this;if(m.$length===l.$length){return F.Equal($subslice(new NM(m.$array),m.$offset,m.$offset+m.$length),$subslice(new NM(l.$array),l.$offset,l.$offset+l.$length));}if((m.$length===4)&&(l.$length===16)){return F.Equal((n=$subslice(l,0,12),$subslice(new NM(n.$array),n.$offset,n.$offset+n.$length)),FB)&&F.Equal($subslice(new NM(m.$array),m.$offset,m.$offset+m.$length),(o=$subslice(l,12),$subslice(new NM(o.$array),o.$offset,o.$offset+o.$length)));}if((m.$length===16)&&(l.$length===4)){return F.Equal((p=$subslice(m,0,12),$subslice(new NM(p.$array),p.$offset,p.$offset+p.$length)),FB)&&F.Equal((q=$subslice(m,12),$subslice(new NM(q.$array),q.$offset,q.$offset+q.$length)),$subslice(new NM(l.$array),l.$offset,l.$offset+l.$length));}return false;};$ptrType(EX).prototype.Equal=function(l){return this.$get().Equal(l);};FM=function(l){var l,m,n,o,p,q,r;m=0;n=l;o=0;while(true){if(!(o<n.$length)){break;}p=o;q=((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]);if(q===255){m=m+(8)>>0;o++;continue;}while(true){if(!(!((((q&128)>>>0)===0)))){break;}m=m+(1)>>0;q=(r=(1),r<32?(q<<r):0)<<24>>>24;}if(!((q===0))){return-1;}p=p+(1)>>0;while(true){if(!(p<l.$length)){break;}if(!((((p<0||p>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+p])===0))){return-1;}p=p+(1)>>0;}break;}return m;};EY.prototype.Size=function(){var l,m,n,o,p,q,r;l=0;m=0;n=this;o=FM(n);p=$imul(n.$length,8);l=o;m=p;if(l===-1){q=0;r=0;l=q;m=r;return[l,m];}return[l,m];};$ptrType(EY).prototype.Size=function(){return this.$get().Size();};EY.prototype.String=function(){var l;l=this;if(l.$length===0){return\"<nil>\";}return FK($subslice(new NM(l.$array),l.$offset,l.$offset+l.$length));};$ptrType(EY).prototype.String=function(){return this.$get().String();};FN=function(l){var l,m,n,o,p,q,r,s,t,u;m=EX.nil;n=EY.nil;m=l.IP.To4();if(m===EX.nil){m=l.IP;if(!((m.$length===16))){o=EX.nil;p=EY.nil;m=o;n=p;return[m,n];}}n=l.Mask;q=n.$length;if(q===(4)){if(!((m.$length===4))){r=EX.nil;s=EY.nil;m=r;n=s;return[m,n];}}else if(q===(16)){if(m.$length===4){n=$subslice(n,12);}}else{t=EX.nil;u=EY.nil;m=t;n=u;return[m,n];}return[m,n];};EZ.ptr.prototype.Contains=function(l){var l,m,n,o,p,q,r,s;m=this;n=FN(m);o=n[0];p=n[1];q=l.To4();if(!(q===EX.nil)){l=q;}r=l.$length;if(!((r===o.$length))){return false;}s=0;while(true){if(!(s<r)){break;}if(!((((((s<0||s>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+s])&((s<0||s>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+s]))>>>0)===((((s<0||s>=l.$length)?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+s])&((s<0||s>=p.$length)?($throwRuntimeError(\"index out of range\"),undefined):p.$array[p.$offset+s]))>>>0)))){return false;}s=s+(1)>>0;}return true;};EZ.prototype.Contains=function(l){return this.$val.Contains(l);};EZ.ptr.prototype.Network=function(){var l;l=this;return\"ip+net\";};EZ.prototype.Network=function(){return this.$val.Network();};EZ.ptr.prototype.String=function(){var l,m,n,o,p;l=this;m=FN(l);n=m[0];o=m[1];if(n===EX.nil||o===EY.nil){return\"<nil>\";}p=FM(o);if(p===-1){return n.String()+\"/\"+o.String();}return n.String()+\"/\"+JT(((p>>>0)));};EZ.prototype.String=function(){return this.$val.String();};FO=function(l){var l,m,n,o,p,q,r;m=OW.zero();n=0;while(true){if(!(n<4)){break;}if(l.length===0){return EX.nil;}if(n>0){if(!((l.charCodeAt(0)===46))){return EX.nil;}l=$substring(l,1);}o=JP(l);p=o[0];q=o[1];r=o[2];if(!r||p>255){return EX.nil;}l=$substring(l,q);((n<0||n>=m.length)?($throwRuntimeError(\"index out of range\"),undefined):m[n]=((p<<24>>>24)));n=n+(1)>>0;}if(!((l.length===0))){return EX.nil;}return FA(m[0],m[1],m[2],m[3]);};FQ=function(l){var aa,ab,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;m=EX.nil;m=$makeSlice(EX,16);n=-1;if(l.length>=2&&(l.charCodeAt(0)===58)&&(l.charCodeAt(1)===58)){n=0;l=$substring(l,2);if(l.length===0){m=m;return m;}}o=0;while(true){if(!(o<16)){break;}p=JQ(l);q=p[0];r=p[1];s=p[2];if(!s||q>65535){m=EX.nil;return m;}if(r<l.length&&(l.charCodeAt(r)===46)){if(n<0&&!((o===12))){m=EX.nil;return m;}if((o+4>>0)>16){m=EX.nil;return m;}t=FO(l);if(t===EX.nil){m=EX.nil;return m;}((o<0||o>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+o]=(12>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+12]));(u=o+1>>0,((u<0||u>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+u]=(13>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+13])));(v=o+2>>0,((v<0||v>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+v]=(14>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+14])));(w=o+3>>0,((w<0||w>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+w]=(15>=t.$length?($throwRuntimeError(\"index out of range\"),undefined):t.$array[t.$offset+15])));l=\"\";o=o+(4)>>0;break;}((o<0||o>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+o]=(((q>>8>>0)<<24>>>24)));(x=o+1>>0,((x<0||x>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+x]=((q<<24>>>24))));o=o+(2)>>0;l=$substring(l,r);if(l.length===0){break;}if(!((l.charCodeAt(0)===58))||(l.length===1)){m=EX.nil;return m;}l=$substring(l,1);if(l.charCodeAt(0)===58){if(n>=0){m=EX.nil;return m;}n=o;l=$substring(l,1);if(l.length===0){break;}}}if(!((l.length===0))){m=EX.nil;return m;}if(o<16){if(n<0){m=EX.nil;return m;}y=16-o>>0;z=o-1>>0;while(true){if(!(z>=n)){break;}(aa=z+y>>0,((aa<0||aa>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+aa]=((z<0||z>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+z])));z=z-(1)>>0;}ab=(n+y>>0)-1>>0;while(true){if(!(ab>=n)){break;}((ab<0||ab>=m.$length)?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+ab]=0);ab=ab-(1)>>0;}}else if(n>=0){m=EX.nil;return m;}m=m;return m;};FR=function(l){var l,m,n;m=0;while(true){if(!(m<l.length)){break;}n=l.charCodeAt(m);if(n===(46)){return FO(l);}else if(n===(58)){return FQ(l);}m=m+(1)>>0;}return EX.nil;};$pkg.ParseIP=FR;FT=function(l){var l,m,n,o,p,q,r,s,t,u,v,w;m=F.IndexByteString(l,47);if(m<0){return[EX.nil,NP.nil,new IO.ptr(\"CIDR address\",l)];}n=$substring(l,0,m);o=$substring(l,(m+1>>0));p=n;q=o;r=4;s=FO(p);if(s===EX.nil){r=16;s=FQ(p);}t=JP(q);u=t[0];m=t[1];v=t[2];if(s===EX.nil||!v||!((m===q.length))||u<0||u>($imul(8,r))){return[EX.nil,NP.nil,new IO.ptr(\"CIDR address\",l)];}w=FD(u,$imul(8,r));return[s,new EZ.ptr(s.Mask(w),w),$ifaceNil];};$pkg.ParseCIDR=FT;FU.ptr.prototype.Network=function(){var l;l=this;return\"ip\";};FU.prototype.Network=function(){return this.$val.Network();};FU.ptr.prototype.String=function(){var l,m;l=this;if(l===NX.nil){return\"<nil>\";}m=FL(l.IP);if(!(l.Zone===\"\")){return m+\"%\"+l.Zone;}return m;};FU.prototype.String=function(){return this.$val.String();};HS.prototype.String=function(){var l,m,n,o,p,q;l=this;if(l.$length===0){return\"\";}m=$makeSlice(NM,0,(($imul(l.$length,3))-1>>0));n=l;o=0;while(true){if(!(o<n.$length)){break;}p=o;q=((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]);if(p>0){m=$append(m,58);}m=$append(m,\"0123456789abcdef\".charCodeAt((q>>>4<<24>>>24)));m=$append(m,\"0123456789abcdef\".charCodeAt(((q&15)>>>0)));o++;}return($bytesToString(m));};$ptrType(HS).prototype.String=function(){return this.$get().String();};II.ptr.prototype.Error=function(){var l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(l===OE.nil){$s=-1;return\"<nil>\";}m=l.Op;if(!(l.Net===\"\")){m=m+(\" \"+l.Net);}if(!($interfaceIsEqual(l.Source,$ifaceNil))){$s=1;continue;}$s=2;continue;case 1:n=l.Source.String();$s=3;case 3:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=m+(\" \"+n);case 2:if(!($interfaceIsEqual(l.Addr,$ifaceNil))){$s=4;continue;}$s=5;continue;case 4:if(!($interfaceIsEqual(l.Source,$ifaceNil))){m=m+(\"->\");}else{m=m+(\" \");}o=l.Addr.String();$s=6;case 6:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}m=m+(o);case 5:p=l.Err.Error();$s=7;case 7:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}m=m+(\": \"+p);$s=-1;return m;}return;}if($f===undefined){$f={$blk:II.ptr.prototype.Error};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};II.prototype.Error=function(){return this.$val.Error();};II.ptr.prototype.Timeout=function(){var l,m,n,o,p,q,r,s,t,u,v,w,x,y,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;m=$assertType(l.Err,PM,true);n=m[0];o=m[1];if(o){$s=1;continue;}$s=2;continue;case 1:p=$assertType(n.Err,IM,true);q=p[0];r=p[1];if(!(r)){s=false;$s=3;continue s;}t=q.Timeout();$s=4;case 4:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}s=t;case 3:$s=-1;return s;case 2:u=$assertType(l.Err,IM,true);v=u[0];w=u[1];if(!(w)){x=false;$s=5;continue s;}y=v.Timeout();$s=6;case 6:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;case 5:$s=-1;return x;}return;}if($f===undefined){$f={$blk:II.ptr.prototype.Timeout};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.$s=$s;$f.$r=$r;return $f;};II.prototype.Timeout=function(){return this.$val.Timeout();};II.ptr.prototype.Temporary=function(){var l,m,n,o,p,q,r,s,t,u,v,w,x,y,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;if(l.Op===\"accept\"&&CY(l.Err)){$s=-1;return true;}m=$assertType(l.Err,PM,true);n=m[0];o=m[1];if(o){$s=1;continue;}$s=2;continue;case 1:p=$assertType(n.Err,IN,true);q=p[0];r=p[1];if(!(r)){s=false;$s=3;continue s;}t=q.Temporary();$s=4;case 4:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}s=t;case 3:$s=-1;return s;case 2:u=$assertType(l.Err,IN,true);v=u[0];w=u[1];if(!(w)){x=false;$s=5;continue s;}y=v.Temporary();$s=6;case 6:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;case 5:$s=-1;return x;}return;}if($f===undefined){$f={$blk:II.ptr.prototype.Temporary};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.$s=$s;$f.$r=$r;return $f;};II.prototype.Temporary=function(){return this.$val.Temporary();};IO.ptr.prototype.Error=function(){var l;l=this;return\"invalid \"+l.Type+\": \"+l.Text;};IO.prototype.Error=function(){return this.$val.Error();};IP.ptr.prototype.Error=function(){var l,m;l=this;if(l===PN.nil){return\"<nil>\";}m=l.Err;if(!(l.Addr===\"\")){m=\"address \"+l.Addr+\": \"+m;}return m;};IP.prototype.Error=function(){return this.$val.Error();};IP.ptr.prototype.Timeout=function(){var l;l=this;return false;};IP.prototype.Timeout=function(){return this.$val.Timeout();};IP.ptr.prototype.Temporary=function(){var l;l=this;return false;};IP.prototype.Temporary=function(){return this.$val.Temporary();};JJ.ptr.prototype.close=function(){var l,m,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=this;m=l.file.Close();$s=1;case 1:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}m;$s=-1;return;}return;}if($f===undefined){$f={$blk:JJ.ptr.prototype.close};}$f.l=l;$f.m=m;$f.$s=$s;$f.$r=$r;return $f;};JJ.prototype.close=function(){return this.$val.close();};JJ.ptr.prototype.getLineFromData=function(){var l,m,n,o,p,q;l=\"\";m=false;n=this;o=n.data;p=0;p=0;while(true){if(!(p<o.$length)){break;}if(((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p])===10){l=($bytesToString($subslice(o,0,p)));m=true;p=p+(1)>>0;q=o.$length-p>>0;$copySlice($subslice(o,0),$subslice(o,p));n.data=$subslice(o,0,q);return[l,m];}p=p+(1)>>0;}if(n.atEOF&&n.data.$length>0){l=($bytesToString(o));n.data=$subslice(n.data,0,0);m=true;}return[l,m];};JJ.prototype.getLineFromData=function(){return this.$val.getLineFromData();};JJ.ptr.prototype.readLine=function(){var l,m,n,o,p,q,r,s,t,u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:l=\"\";m=false;n=this;o=n.getLineFromData();l=o[0];m=o[1];if(m){$s=-1;return[l,m];}if(n.data.$length<n.data.$capacity){$s=1;continue;}$s=2;continue;case 1:p=n.data.$length;r=O.ReadFull(n.file,$subslice(n.data,p,n.data.$capacity));$s=3;case 3:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}q=r;s=q[0];t=q[1];if(s>=0){n.data=$subslice(n.data,0,(p+s>>0));}if($interfaceIsEqual(t,O.EOF)||$interfaceIsEqual(t,O.ErrUnexpectedEOF)){n.atEOF=true;}case 2:u=n.getLineFromData();l=u[0];m=u[1];$s=-1;return[l,m];}return;}if($f===undefined){$f={$blk:JJ.ptr.prototype.readLine};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};JJ.prototype.readLine=function(){return this.$val.readLine();};JK=function(l){var l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:n=G.Open(l);$s=1;case 1:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;o=m[0];p=m[1];if(!($interfaceIsEqual(p,$ifaceNil))){$s=-1;return[OQ.nil,p];}$s=-1;return[new JJ.ptr(o,$makeSlice(NM,0,65536),false),$ifaceNil];}return;}if($f===undefined){$f={$blk:JK};}$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};JM=function(l,m){var l,m,n,o;n=0;o=0;while(true){if(!(o<l.length)){break;}if(F.IndexByteString(m,l.charCodeAt(o))>=0){n=n+(1)>>0;}o=o+(1)>>0;}return n;};JN=function(l,m){var l,m,n,o,p,q;n=$makeSlice(NG,(1+JM(l,m)>>0));o=0;p=0;q=0;while(true){if(!(q<l.length)){break;}if(F.IndexByteString(m,l.charCodeAt(q))>=0){if(p<q){((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]=$substring(l,p,q));o=o+(1)>>0;}p=q+1>>0;}q=q+(1)>>0;}if(p<l.length){((o<0||o>=n.$length)?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+o]=$substring(l,p));o=o+(1)>>0;}return $subslice(n,0,o);};JP=function(l){var l,m,n,o,p,q,r,s,t,u,v,w,x;m=0;n=0;o=false;m=0;n=0;while(true){if(!(n<l.length&&48<=l.charCodeAt(n)&&l.charCodeAt(n)<=57)){break;}m=($imul(m,10))+(((l.charCodeAt(n)-48<<24>>>24)>>0))>>0;if(m>=16777215){p=16777215;q=n;r=false;m=p;n=q;o=r;return[m,n,o];}n=n+(1)>>0;}if(n===0){s=0;t=0;u=false;m=s;n=t;o=u;return[m,n,o];}v=m;w=n;x=true;m=v;n=w;o=x;return[m,n,o];};JQ=function(l){var l,m,n,o,p,q,r,s,t,u,v,w,x;m=0;n=0;o=false;m=0;n=0;while(true){if(!(n<l.length)){break;}if(48<=l.charCodeAt(n)&&l.charCodeAt(n)<=57){m=$imul(m,(16));m=m+((((l.charCodeAt(n)-48<<24>>>24)>>0)))>>0;}else if(97<=l.charCodeAt(n)&&l.charCodeAt(n)<=102){m=$imul(m,(16));m=m+(((((l.charCodeAt(n)-97<<24>>>24)>>0))+10>>0))>>0;}else if(65<=l.charCodeAt(n)&&l.charCodeAt(n)<=70){m=$imul(m,(16));m=m+(((((l.charCodeAt(n)-65<<24>>>24)>>0))+10>>0))>>0;}else{break;}if(m>=16777215){p=0;q=n;r=false;m=p;n=q;o=r;return[m,n,o];}n=n+(1)>>0;}if(n===0){s=0;t=n;u=false;m=s;n=t;o=u;return[m,n,o];}v=m;w=n;x=true;m=v;n=w;o=x;return[m,n,o];};JR=function(l,m){var l,m,n,o,p,q;if(l.length>2&&!((l.charCodeAt(2)===m))){return[0,false];}n=JQ($substring(l,0,2));o=n[0];p=n[1];q=n[2];return[((o<<24>>>24)),q&&(p===2)];};JT=function(l){var l,m,n,o,p;if(l===0){return\"0\";}m=PP.zero();n=19;while(true){if(!(l>=10)){break;}p=(o=l/10,(o===o&&o!==1/0&&o!==-1/0)?o>>>0:$throwRuntimeError(\"integer divide by zero\"));((n<0||n>=m.length)?($throwRuntimeError(\"index out of range\"),undefined):m[n]=((((48+l>>>0)-(p*10>>>0)>>>0)<<24>>>24)));n=n-(1)>>0;l=p;}((n<0||n>=m.length)?($throwRuntimeError(\"index out of range\"),undefined):m[n]=(((48+l>>>0)<<24>>>24)));return($bytesToString($subslice(new NM(m),n)));};JU=function(l,m){var l,m,n,o,p;if(m===0){return $append(l,48);}n=7;while(true){if(!(n>=0)){break;}p=(o=((($imul(n,4))>>>0)),o<32?(m>>>o):0)>>>0;if(p>0){l=$append(l,\"0123456789abcdef\".charCodeAt(((p&15)>>>0)));}n=n-(1)>>0;}return l;};AH.methods=[{prop:\"Classify\",name:\"Classify\",pkg:\"\",typ:$funcType([EX],[AG],false)}];AK.methods=[{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)},{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)}];OR.methods=[{prop:\"Addrs\",name:\"Addrs\",pkg:\"\",typ:$funcType([],[OS,$error],false)},{prop:\"MulticastAddrs\",name:\"MulticastAddrs\",pkg:\"\",typ:$funcType([],[OS,$error],false)}];EF.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];QL.methods=[{prop:\"update\",name:\"update\",pkg:\"net\",typ:$funcType([OT,$Bool],[$Bool],false)},{prop:\"name\",name:\"name\",pkg:\"net\",typ:$funcType([$Int],[$String],false)},{prop:\"index\",name:\"index\",pkg:\"net\",typ:$funcType([$String],[$Int],false)}];EX.methods=[{prop:\"IsUnspecified\",name:\"IsUnspecified\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsLoopback\",name:\"IsLoopback\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsMulticast\",name:\"IsMulticast\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsInterfaceLocalMulticast\",name:\"IsInterfaceLocalMulticast\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsLinkLocalMulticast\",name:\"IsLinkLocalMulticast\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsLinkLocalUnicast\",name:\"IsLinkLocalUnicast\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"IsGlobalUnicast\",name:\"IsGlobalUnicast\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"To4\",name:\"To4\",pkg:\"\",typ:$funcType([],[EX],false)},{prop:\"To16\",name:\"To16\",pkg:\"\",typ:$funcType([],[EX],false)},{prop:\"DefaultMask\",name:\"DefaultMask\",pkg:\"\",typ:$funcType([],[EY],false)},{prop:\"Mask\",name:\"Mask\",pkg:\"\",typ:$funcType([EY],[EX],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"MarshalText\",name:\"MarshalText\",pkg:\"\",typ:$funcType([],[NM,$error],false)},{prop:\"Equal\",name:\"Equal\",pkg:\"\",typ:$funcType([EX],[$Bool],false)},{prop:\"matchAddrFamily\",name:\"matchAddrFamily\",pkg:\"net\",typ:$funcType([EX],[$Bool],false)}];QO.methods=[{prop:\"UnmarshalText\",name:\"UnmarshalText\",pkg:\"\",typ:$funcType([NM],[$error],false)}];EY.methods=[{prop:\"Size\",name:\"Size\",pkg:\"\",typ:$funcType([],[$Int,$Int],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];NP.methods=[{prop:\"Contains\",name:\"Contains\",pkg:\"\",typ:$funcType([EX],[$Bool],false)},{prop:\"Network\",name:\"Network\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];NX.methods=[{prop:\"Network\",name:\"Network\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"isWildcard\",name:\"isWildcard\",pkg:\"net\",typ:$funcType([],[$Bool],false)},{prop:\"opAddr\",name:\"opAddr\",pkg:\"net\",typ:$funcType([],[HW],false)},{prop:\"family\",name:\"family\",pkg:\"net\",typ:$funcType([],[$Int],false)},{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"net\",typ:$funcType([$Int],[B.Sockaddr,$error],false)},{prop:\"toLocal\",name:\"toLocal\",pkg:\"net\",typ:$funcType([$String],[LC],false)}];HS.methods=[{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];OE.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}];QT.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];PN.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}];OQ.methods=[{prop:\"close\",name:\"close\",pkg:\"net\",typ:$funcType([],[],false)},{prop:\"getLineFromData\",name:\"getLineFromData\",pkg:\"net\",typ:$funcType([],[$String,$Bool],false)},{prop:\"readLine\",name:\"readLine\",pkg:\"net\",typ:$funcType([],[$String,$Bool],false)}];AG.init(\"\",[{prop:\"Prefix\",name:\"Prefix\",embedded:false,exported:true,typ:NP,tag:\"\"},{prop:\"Precedence\",name:\"Precedence\",embedded:false,exported:true,typ:$Uint8,tag:\"\"},{prop:\"Label\",name:\"Label\",embedded:false,exported:true,typ:$Uint8,tag:\"\"}]);AH.init(AG);AK.init(AG);EE.init(\"\",[{prop:\"Index\",name:\"Index\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"MTU\",name:\"MTU\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"Name\",name:\"Name\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"HardwareAddr\",name:\"HardwareAddr\",embedded:false,exported:true,typ:HS,tag:\"\"},{prop:\"Flags\",name:\"Flags\",embedded:false,exported:true,typ:EF,tag:\"\"}]);EM.init(\"net\",[{prop:\"RWMutex\",name:\"RWMutex\",embedded:true,exported:true,typ:I.RWMutex,tag:\"\"},{prop:\"lastFetched\",name:\"lastFetched\",embedded:false,exported:false,typ:L.Time,tag:\"\"},{prop:\"toIndex\",name:\"toIndex\",embedded:false,exported:false,typ:QM,tag:\"\"},{prop:\"toName\",name:\"toName\",embedded:false,exported:false,typ:QN,tag:\"\"}]);EX.init($Uint8);EY.init($Uint8);EZ.init(\"\",[{prop:\"IP\",name:\"IP\",embedded:false,exported:true,typ:EX,tag:\"\"},{prop:\"Mask\",name:\"Mask\",embedded:false,exported:true,typ:EY,tag:\"\"}]);FU.init(\"\",[{prop:\"IP\",name:\"IP\",embedded:false,exported:true,typ:EX,tag:\"\"},{prop:\"Zone\",name:\"Zone\",embedded:false,exported:true,typ:$String,tag:\"\"}]);HS.init($Uint8);HW.init([{prop:\"Network\",name:\"Network\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}]);II.init(\"\",[{prop:\"Op\",name:\"Op\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Net\",name:\"Net\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Source\",name:\"Source\",embedded:false,exported:true,typ:HW,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:HW,tag:\"\"},{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$error,tag:\"\"}]);IM.init([{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)}]);IN.init([{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}]);IO.init(\"\",[{prop:\"Type\",name:\"Type\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Text\",name:\"Text\",embedded:false,exported:true,typ:$String,tag:\"\"}]);IP.init(\"\",[{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Addr\",name:\"Addr\",embedded:false,exported:true,typ:$String,tag:\"\"}]);JJ.init(\"net\",[{prop:\"file\",name:\"file\",embedded:false,exported:false,typ:OM,tag:\"\"},{prop:\"data\",name:\"data\",embedded:false,exported:false,typ:NM,tag:\"\"},{prop:\"atEOF\",name:\"atEOF\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);LC.init([{prop:\"Network\",name:\"Network\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"family\",name:\"family\",pkg:\"net\",typ:$funcType([],[$Int],false)},{prop:\"isWildcard\",name:\"isWildcard\",pkg:\"net\",typ:$funcType([],[$Bool],false)},{prop:\"sockaddr\",name:\"sockaddr\",pkg:\"net\",typ:$funcType([$Int],[B.Sockaddr,$error],false)},{prop:\"toLocal\",name:\"toLocal\",pkg:\"net\",typ:$funcType([$String],[LC],false)}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=E.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=J.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=K.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=Q.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=N.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=O.$init();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=M.$init();$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=11;case 11:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=13;case 13:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=I.$init();$s=14;case 14:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=P.$init();$s=15;case 15:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=16;case 16:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=L.$init();$s=17;case 17:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}HU=false;BX=A.New(\"lame referral\");BY=A.New(\"cannot unmarshal DNS message\");BZ=A.New(\"cannot marshal DNS message\");CA=A.New(\"server misbehaving\");CB=A.New(\"invalid DNS response\");CC=A.New(\"no answer from DNS server\");CD=A.New(\"server misbehaving\");DM=(function $b(c,d,e,f){var c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:g=d(c,e,f);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}$s=-1;return g;}return;}if($f===undefined){$f={$blk:$b};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;});DZ=A.New(\"invalid network interface\");EA=A.New(\"invalid network interface index\");EB=A.New(\"invalid network interface name\");EC=A.New(\"no such network interface\");ED=A.New(\"no such multicast network interface\");EG=new NG([\"up\",\"broadcast\",\"loopback\",\"pointtopoint\",\"multicast\"]);EN=new EM.ptr(new I.RWMutex.ptr(new I.Mutex.ptr(0,0),0,0,0,0),new L.Time.ptr(new $Uint64(0,0),new $Int64(0,0),NE.nil),{},{});FB=new NM([0,0,0,0,0,0,0,0,0,0,255,255]);$pkg.IPv4bcast=FA(255,255,255,255);$pkg.IPv4allsys=FA(224,0,0,1);$pkg.IPv4allrouter=FA(224,0,0,2);$pkg.IPv4zero=FA(0,0,0,0);$pkg.IPv6unspecified=new EX([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);$pkg.IPv6loopback=new EX([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]);FF=FC(255,0,0,0);FG=FC(255,255,0,0);FH=FC(255,255,255,0);IE=A.New(\"no suitable address found\");IF=A.New(\"missing address\");IG=A.New(\"operation was canceled\");$pkg.ErrWriteToConnected=A.New(\"use of WriteTo with pre-connected connection\");IJ=$clone(L.Unix(new $Int64(0,1),new $Int64(0,0)),L.Time);IT=A.New(\"no such host\");c=AL(\"::1/128\");$s=18;case 18:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=AL(\"::/0\");$s=19;case 19:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=AL(\"::ffff:0:0/96\");$s=20;case 20:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}f=AL(\"2002::/16\");$s=21;case 21:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}g=AL(\"2001::/32\");$s=22;case 22:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=AL(\"fc00::/7\");$s=23;case 23:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}i=AL(\"::/96\");$s=24;case 24:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}j=AL(\"fec0::/10\");$s=25;case 25:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}k=AL(\"3ffe::/16\");$s=26;case 26:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}AI=new AH([new AG.ptr(c,50,0),new AG.ptr(d,40,1),new AG.ptr(e,35,4),new AG.ptr(f,30,2),new AG.ptr(g,5,5),new AG.ptr(h,3,13),new AG.ptr(i,1,3),new AG.ptr(j,1,11),new AG.ptr(k,1,12)]);$r=AJ();$s=27;case 27:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}AP();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"net/url\"]=(function(){var $pkg={},$init,A,B,C,D,E,F,G,H,L,M,U,X,AH,AO,AP,AQ,AR,AS,AT,AU,AV,I,J,N,O,Q,R,T,V,W,Y,Z,AA,AC,AD,AE,AF,AG,AI,AJ,AK,AL,AM,AN;A=$packages[\"errors\"];B=$packages[\"fmt\"];C=$packages[\"sort\"];D=$packages[\"strconv\"];E=$packages[\"strings\"];F=$pkg.Error=$newType(0,$kindStruct,\"url.Error\",true,\"net/url\",true,function(Op_,URL_,Err_){this.$val=this;if(arguments.length===0){this.Op=\"\";this.URL=\"\";this.Err=$ifaceNil;return;}this.Op=Op_;this.URL=URL_;this.Err=Err_;});G=$pkg.timeout=$newType(8,$kindInterface,\"url.timeout\",true,\"net/url\",false,null);H=$pkg.temporary=$newType(8,$kindInterface,\"url.temporary\",true,\"net/url\",false,null);L=$pkg.EscapeError=$newType(8,$kindString,\"url.EscapeError\",true,\"net/url\",true,null);M=$pkg.InvalidHostError=$newType(8,$kindString,\"url.InvalidHostError\",true,\"net/url\",true,null);U=$pkg.URL=$newType(0,$kindStruct,\"url.URL\",true,\"net/url\",true,function(Scheme_,Opaque_,User_,Host_,Path_,RawPath_,ForceQuery_,RawQuery_,Fragment_){this.$val=this;if(arguments.length===0){this.Scheme=\"\";this.Opaque=\"\";this.User=AQ.nil;this.Host=\"\";this.Path=\"\";this.RawPath=\"\";this.ForceQuery=false;this.RawQuery=\"\";this.Fragment=\"\";return;}this.Scheme=Scheme_;this.Opaque=Opaque_;this.User=User_;this.Host=Host_;this.Path=Path_;this.RawPath=RawPath_;this.ForceQuery=ForceQuery_;this.RawQuery=RawQuery_;this.Fragment=Fragment_;});X=$pkg.Userinfo=$newType(0,$kindStruct,\"url.Userinfo\",true,\"net/url\",true,function(username_,password_,passwordSet_){this.$val=this;if(arguments.length===0){this.username=\"\";this.password=\"\";this.passwordSet=false;return;}this.username=username_;this.password=password_;this.passwordSet=passwordSet_;});AH=$pkg.Values=$newType(4,$kindMap,\"url.Values\",true,\"net/url\",true,null);AO=$sliceType($Uint8);AP=$arrayType($Uint8,64);AQ=$ptrType(X);AR=$ptrType(U);AS=$sliceType($emptyInterface);AT=$ptrType(E.Builder);AU=$sliceType($String);AV=$ptrType(F);F.ptr.prototype.Error=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.Err.Error();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return a.Op+\" \"+a.URL+\": \"+b;}return;}if($f===undefined){$f={$blk:F.ptr.prototype.Error};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};F.prototype.Error=function(){return this.$val.Error();};F.ptr.prototype.Timeout=function(){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=$assertType(a.Err,G,true);c=b[0];d=b[1];if(!(d)){e=false;$s=1;continue s;}f=c.Timeout();$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;case 1:$s=-1;return e;}return;}if($f===undefined){$f={$blk:F.ptr.prototype.Timeout};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};F.prototype.Timeout=function(){return this.$val.Timeout();};F.ptr.prototype.Temporary=function(){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=$assertType(a.Err,H,true);c=b[0];d=b[1];if(!(d)){e=false;$s=1;continue s;}f=c.Temporary();$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;case 1:$s=-1;return e;}return;}if($f===undefined){$f={$blk:F.ptr.prototype.Temporary};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};F.prototype.Temporary=function(){return this.$val.Temporary();};I=function(a){var a;if(48<=a&&a<=57){return true;}else if(97<=a&&a<=102){return true;}else if(65<=a&&a<=70){return true;}return false;};J=function(a){var a;if(48<=a&&a<=57){return a-48<<24>>>24;}else if(97<=a&&a<=102){return(a-97<<24>>>24)+10<<24>>>24;}else if(65<=a&&a<=70){return(a-65<<24>>>24)+10<<24>>>24;}return 0;};L.prototype.Error=function(){var a;a=this.$val;return\"invalid URL escape \"+D.Quote((a));};$ptrType(L).prototype.Error=function(){return new L(this.$get()).Error();};M.prototype.Error=function(){var a;a=this.$val;return\"invalid character \"+D.Quote((a))+\" in host name\";};$ptrType(M).prototype.Error=function(){return new M(this.$get()).Error();};N=function(a,b){var a,b,c,d,e,f;if(65<=a&&a<=90||97<=a&&a<=122||48<=a&&a<=57){return false;}if((b===3)||(b===4)){c=a;if((c===(33))||(c===(36))||(c===(38))||(c===(39))||(c===(40))||(c===(41))||(c===(42))||(c===(43))||(c===(44))||(c===(59))||(c===(61))||(c===(58))||(c===(91))||(c===(93))||(c===(60))||(c===(62))||(c===(34))){return false;}}d=a;if((d===(45))||(d===(95))||(d===(46))||(d===(126))){return false;}else if((d===(36))||(d===(38))||(d===(43))||(d===(44))||(d===(47))||(d===(58))||(d===(59))||(d===(61))||(d===(63))||(d===(64))){e=b;if(e===(1)){return a===63;}else if(e===(2)){return(a===47)||(a===59)||(a===44)||(a===63);}else if(e===(5)){return(a===64)||(a===47)||(a===63)||(a===58);}else if(e===(6)){return true;}else if(e===(7)){return false;}}if(b===7){f=a;if((f===(33))||(f===(40))||(f===(41))||(f===(42))){return false;}}return true;};O=function(a){var a;return Q(a,6);};$pkg.QueryUnescape=O;Q=function(a,b){var a,b,c,d,e,f,g,h,i,j,k;c=0;d=false;e=0;while(true){if(!(e<a.length)){break;}f=a.charCodeAt(e);if(f===(37)){c=c+(1)>>0;if((e+2>>0)>=a.length||!I(a.charCodeAt((e+1>>0)))||!I(a.charCodeAt((e+2>>0)))){a=$substring(a,e);if(a.length>3){a=$substring(a,0,3);}return[\"\",new L((a))];}if((b===3)&&J(a.charCodeAt((e+1>>0)))<8&&!($substring(a,e,(e+3>>0))===\"%25\")){return[\"\",new L(($substring(a,e,(e+3>>0))))];}if(b===4){g=((J(a.charCodeAt((e+1>>0)))<<4<<24>>>24)|J(a.charCodeAt((e+2>>0))))>>>0;if(!($substring(a,e,(e+3>>0))===\"%25\")&&!((g===32))&&N(g,3)){return[\"\",new L(($substring(a,e,(e+3>>0))))];}}e=e+(3)>>0;}else if(f===(43)){d=b===6;e=e+(1)>>0;}else{if(((b===3)||(b===4))&&a.charCodeAt(e)<128&&N(a.charCodeAt(e),b)){return[\"\",new M(($substring(a,e,(e+1>>0))))];}e=e+(1)>>0;}}if((c===0)&&!d){return[a,$ifaceNil];}h=$makeSlice(AO,(a.length-($imul(2,c))>>0));i=0;j=0;while(true){if(!(j<a.length)){break;}k=a.charCodeAt(j);if(k===(37)){((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=(((J(a.charCodeAt((j+1>>0)))<<4<<24>>>24)|J(a.charCodeAt((j+2>>0))))>>>0));i=i+(1)>>0;j=j+(3)>>0;}else if(k===(43)){if(b===6){((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=32);}else{((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=43);}i=i+(1)>>0;j=j+(1)>>0;}else{((i<0||i>=h.$length)?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+i]=a.charCodeAt(j));i=i+(1)>>0;j=j+(1)>>0;}}return[($bytesToString(h)),$ifaceNil];};R=function(a){var a;return T(a,6);};$pkg.QueryEscape=R;T=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;c=0;d=0;e=c;f=d;g=0;while(true){if(!(g<a.length)){break;}h=a.charCodeAt(g);if(N(h,b)){if((h===32)&&(b===6)){e=e+(1)>>0;}else{f=f+(1)>>0;}}g=g+(1)>>0;}if((e===0)&&(f===0)){return a;}i=AP.zero();j=AO.nil;k=a.length+($imul(2,f))>>0;if(k<=64){j=$subslice(new AO(i),0,k);}else{j=$makeSlice(AO,k);}if(f===0){$copyString(j,a);l=0;while(true){if(!(l<a.length)){break;}if(a.charCodeAt(l)===32){((l<0||l>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+l]=43);}l=l+(1)>>0;}return($bytesToString(j));}m=0;n=0;while(true){if(!(n<a.length)){break;}o=a.charCodeAt(n);if((o===32)&&(b===6)){((m<0||m>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+m]=43);m=m+(1)>>0;}else if(N(o,b)){((m<0||m>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+m]=37);(p=m+1>>0,((p<0||p>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+p]=\"0123456789ABCDEF\".charCodeAt((o>>>4<<24>>>24))));(q=m+2>>0,((q<0||q>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+q]=\"0123456789ABCDEF\".charCodeAt(((o&15)>>>0))));m=m+(3)>>0;}else{((m<0||m>=j.$length)?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+m]=a.charCodeAt(n));m=m+(1)>>0;}n=n+(1)>>0;}return($bytesToString(j));};V=function(a){var a;return new X.ptr(a,\"\",false);};$pkg.User=V;W=function(a,b){var a,b;return new X.ptr(a,b,true);};$pkg.UserPassword=W;X.ptr.prototype.Username=function(){var a;a=this;if(a===AQ.nil){return\"\";}return a.username;};X.prototype.Username=function(){return this.$val.Username();};X.ptr.prototype.Password=function(){var a;a=this;if(a===AQ.nil){return[\"\",false];}return[a.password,a.passwordSet];};X.prototype.Password=function(){return this.$val.Password();};X.ptr.prototype.String=function(){var a,b;a=this;if(a===AQ.nil){return\"\";}b=T(a.username,5);if(a.passwordSet){b=b+(\":\"+T(a.password,5));}return b;};X.prototype.String=function(){return this.$val.String();};Y=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;b=\"\";c=\"\";d=$ifaceNil;e=0;while(true){if(!(e<a.length)){break;}f=a.charCodeAt(e);if(97<=f&&f<=122||65<=f&&f<=90){}else if(48<=f&&f<=57||(f===43)||(f===45)||(f===46)){if(e===0){g=\"\";h=a;i=$ifaceNil;b=g;c=h;d=i;return[b,c,d];}}else if((f===58)){if(e===0){j=\"\";k=\"\";l=A.New(\"missing protocol scheme\");b=j;c=k;d=l;return[b,c,d];}m=$substring(a,0,e);n=$substring(a,(e+1>>0));o=$ifaceNil;b=m;c=n;d=o;return[b,c,d];}else{p=\"\";q=a;r=$ifaceNil;b=p;c=q;d=r;return[b,c,d];}e=e+(1)>>0;}s=\"\";t=a;u=$ifaceNil;b=s;c=t;d=u;return[b,c,d];};Z=function(a,b,c){var a,b,c,d;d=E.Index(a,b);if(d<0){return[a,\"\"];}if(c){return[$substring(a,0,d),$substring(a,(d+b.length>>0))];}return[$substring(a,0,d),$substring(a,d)];};AA=function(a){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=Z(a,\"#\",true);c=b[0];d=b[1];f=AC(c,false);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;g=e[0];h=e[1];if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[AR.nil,new F.ptr(\"parse\",c,h)];}if(d===\"\"){$s=-1;return[g,$ifaceNil];}i=Q(d,7);g.Fragment=i[0];h=i[1];if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[AR.nil,new F.ptr(\"parse\",a,h)];}$s=-1;return[g,$ifaceNil];}return;}if($f===undefined){$f={$blk:AA};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Parse=AA;AC=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=\"\";d=$ifaceNil;if(AN(a)){$s=-1;return[AR.nil,A.New(\"net/url: invalid control character in URL\")];}if(a===\"\"&&b){$s=-1;return[AR.nil,A.New(\"empty url\")];}e=new U.ptr(\"\",\"\",AQ.nil,\"\",\"\",\"\",false,\"\",\"\");if(a===\"*\"){e.Path=\"*\";$s=-1;return[e,$ifaceNil];}f=Y(a);e.Scheme=f[0];c=f[1];d=f[2];if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return[AR.nil,d];}g=E.ToLower(e.Scheme);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}e.Scheme=g;if(E.HasSuffix(c,\"?\")&&(E.Count(c,\"?\")===1)){e.ForceQuery=true;c=$substring(c,0,(c.length-1>>0));}else{h=Z(c,\"?\",true);c=h[0];e.RawQuery=h[1];}if(!E.HasPrefix(c,\"/\")){if(!(e.Scheme===\"\")){e.Opaque=c;$s=-1;return[e,$ifaceNil];}if(b){$s=-1;return[AR.nil,A.New(\"invalid URI for request\")];}i=E.Index(c,\":\");j=E.Index(c,\"/\");if(i>=0&&(j<0||i<j)){$s=-1;return[AR.nil,A.New(\"first path segment in URL cannot contain colon\")];}}if((!(e.Scheme===\"\")||!b&&!E.HasPrefix(c,\"///\"))&&E.HasPrefix(c,\"//\")){$s=2;continue;}$s=3;continue;case 2:k=\"\";l=Z($substring(c,2),\"/\",false);k=l[0];c=l[1];n=AD(k);$s=4;case 4:if($c){$c=false;n=n.$blk();}if(n&&n.$blk!==undefined){break s;}m=n;e.User=m[0];e.Host=m[1];d=m[2];if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return[AR.nil,d];}case 3:o=e.setPath(c);if(!($interfaceIsEqual(o,$ifaceNil))){$s=-1;return[AR.nil,o];}$s=-1;return[e,$ifaceNil];}return;}if($f===undefined){$f={$blk:AC};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.$s=$s;$f.$r=$r;return $f;};AD=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=AQ.nil;c=\"\";d=$ifaceNil;e=E.LastIndex(a,\"@\");if(e<0){$s=1;continue;}$s=2;continue;case 1:g=AE(a);$s=4;case 4:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;c=f[0];d=f[1];$s=3;continue;case 2:i=AE($substring(a,(e+1>>0)));$s=5;case 5:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;c=h[0];d=h[1];case 3:if(!($interfaceIsEqual(d,$ifaceNil))){j=AQ.nil;k=\"\";l=d;b=j;c=k;d=l;$s=-1;return[b,c,d];}if(e<0){m=AQ.nil;n=c;o=$ifaceNil;b=m;c=n;d=o;$s=-1;return[b,c,d];}p=$substring(a,0,e);if(!AM(p)){q=AQ.nil;r=\"\";s=A.New(\"net/url: invalid userinfo\");b=q;c=r;d=s;$s=-1;return[b,c,d];}if(!E.Contains(p,\":\")){t=Q(p,5);p=t[0];d=t[1];if(!($interfaceIsEqual(d,$ifaceNil))){u=AQ.nil;v=\"\";w=d;b=u;c=v;d=w;$s=-1;return[b,c,d];}b=V(p);}else{x=Z(p,\":\",true);y=x[0];z=x[1];aa=Q(y,5);y=aa[0];d=aa[1];if(!($interfaceIsEqual(d,$ifaceNil))){ab=AQ.nil;ac=\"\";ad=d;b=ab;c=ac;d=ad;$s=-1;return[b,c,d];}ae=Q(z,5);z=ae[0];d=ae[1];if(!($interfaceIsEqual(d,$ifaceNil))){af=AQ.nil;ag=\"\";ah=d;b=af;c=ag;d=ah;$s=-1;return[b,c,d];}b=W(y,z);}ai=b;aj=c;ak=$ifaceNil;b=ai;c=aj;d=ak;$s=-1;return[b,c,d];}return;}if($f===undefined){$f={$blk:AD};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AE=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(E.HasPrefix(a,\"[\")){$s=1;continue;}$s=2;continue;case 1:b=E.LastIndex(a,\"]\");if(b<0){$s=-1;return[\"\",A.New(\"missing ']' in host\")];}c=$substring(a,(b+1>>0));if(!AG(c)){$s=4;continue;}$s=5;continue;case 4:d=B.Errorf(\"invalid port %q after host\",new AS([new $String(c)]));$s=6;case 6:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}$s=-1;return[\"\",d];case 5:e=E.Index($substring(a,0,b),\"%25\");if(e>=0){f=Q($substring(a,0,e),3);g=f[0];h=f[1];if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[\"\",h];}i=Q($substring(a,e,b),4);j=i[0];h=i[1];if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[\"\",h];}k=Q($substring(a,b),3);l=k[0];h=k[1];if(!($interfaceIsEqual(h,$ifaceNil))){$s=-1;return[\"\",h];}$s=-1;return[g+j+l,$ifaceNil];}$s=3;continue;case 2:m=E.LastIndex(a,\":\");if(!((m===-1))){$s=7;continue;}$s=8;continue;case 7:n=$substring(a,m);if(!AG(n)){$s=9;continue;}$s=10;continue;case 9:o=B.Errorf(\"invalid port %q after host\",new AS([new $String(n)]));$s=11;case 11:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}$s=-1;return[\"\",o];case 10:case 8:case 3:p=$ifaceNil;q=Q(a,3);a=q[0];p=q[1];if(!($interfaceIsEqual(p,$ifaceNil))){$s=-1;return[\"\",p];}$s=-1;return[a,$ifaceNil];}return;}if($f===undefined){$f={$blk:AE};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};U.ptr.prototype.setPath=function(a){var a,b,c,d,e,f;b=this;c=Q(a,1);d=c[0];e=c[1];if(!($interfaceIsEqual(e,$ifaceNil))){return e;}b.Path=d;f=T(d,1);if(a===f){b.RawPath=\"\";}else{b.RawPath=a;}return $ifaceNil;};U.prototype.setPath=function(a){return this.$val.setPath(a);};U.ptr.prototype.EscapedPath=function(){var a,b,c,d;a=this;if(!(a.RawPath===\"\")&&AF(a.RawPath)){b=Q(a.RawPath,1);c=b[0];d=b[1];if($interfaceIsEqual(d,$ifaceNil)&&c===a.Path){return a.RawPath;}}if(a.Path===\"*\"){return\"*\";}return T(a.Path,1);};U.prototype.EscapedPath=function(){return this.$val.EscapedPath();};AF=function(a){var a,b,c;b=0;while(true){if(!(b<a.length)){break;}c=a.charCodeAt(b);if((c===(33))||(c===(36))||(c===(38))||(c===(39))||(c===(40))||(c===(41))||(c===(42))||(c===(43))||(c===(44))||(c===(59))||(c===(61))||(c===(58))||(c===(64))){}else if((c===(91))||(c===(93))){}else if(c===(37)){}else if(N(a.charCodeAt(b),1)){return false;}b=b+(1)>>0;}return true;};AG=function(a){var a,b,c,d,e;if(a===\"\"){return true;}if(!((a.charCodeAt(0)===58))){return false;}b=$substring(a,1);c=0;while(true){if(!(c<b.length)){break;}d=$decodeRune(b,c);e=d[0];if(e<48||e>57){return false;}c+=d[1];}return true;};U.ptr.prototype.String=function(){var a,b,c,d,e,f;a=this;b=new E.Builder.ptr(AT.nil,AO.nil);if(!(a.Scheme===\"\")){b.WriteString(a.Scheme);b.WriteByte(58);}if(!(a.Opaque===\"\")){b.WriteString(a.Opaque);}else{if(!(a.Scheme===\"\")||!(a.Host===\"\")||!(a.User===AQ.nil)){if(!(a.Host===\"\")||!(a.Path===\"\")||!(a.User===AQ.nil)){b.WriteString(\"//\");}c=a.User;if(!(c===AQ.nil)){b.WriteString(c.String());b.WriteByte(64);}d=a.Host;if(!(d===\"\")){b.WriteString(T(d,3));}}e=a.EscapedPath();if(!(e===\"\")&&!((e.charCodeAt(0)===47))&&!(a.Host===\"\")){b.WriteByte(47);}if(b.Len()===0){f=E.IndexByte(e,58);if(f>-1&&(E.IndexByte($substring(e,0,f),47)===-1)){b.WriteString(\"./\");}}b.WriteString(e);}if(a.ForceQuery||!(a.RawQuery===\"\")){b.WriteByte(63);b.WriteString(a.RawQuery);}if(!(a.Fragment===\"\")){b.WriteByte(35);b.WriteString(T(a.Fragment,7));}return b.String();};U.prototype.String=function(){return this.$val.String();};AH.prototype.Get=function(a){var a,b,c,d;b=this.$val;if(b===false){return\"\";}d=(c=b[$String.keyFor(a)],c!==undefined?c.v:AU.nil);if(d.$length===0){return\"\";}return(0>=d.$length?($throwRuntimeError(\"index out of range\"),undefined):d.$array[d.$offset+0]);};$ptrType(AH).prototype.Get=function(a){return new AH(this.$get()).Get(a);};AH.prototype.Set=function(a,b){var a,b,c,d;c=this.$val;d=a;(c||$throwRuntimeError(\"assignment to entry in nil map\"))[$String.keyFor(d)]={k:d,v:new AU([b])};};$ptrType(AH).prototype.Set=function(a,b){return new AH(this.$get()).Set(a,b);};AH.prototype.Add=function(a,b){var a,b,c,d,e;c=this.$val;d=a;(c||$throwRuntimeError(\"assignment to entry in nil map\"))[$String.keyFor(d)]={k:d,v:$append((e=c[$String.keyFor(a)],e!==undefined?e.v:AU.nil),b)};};$ptrType(AH).prototype.Add=function(a,b){return new AH(this.$get()).Add(a,b);};AH.prototype.Del=function(a){var a,b;b=this.$val;delete b[$String.keyFor(a)];};$ptrType(AH).prototype.Del=function(a){return new AH(this.$get()).Del(a);};AI=function(a){var a,b,c;b={};c=AJ(b,a);return[b,c];};$pkg.ParseQuery=AI;AJ=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;c=$ifaceNil;while(true){if(!(!(b===\"\"))){break;}d=b;e=E.IndexAny(d,\"&;\");if(e>=0){f=$substring(d,0,e);g=$substring(d,(e+1>>0));d=f;b=g;}else{b=\"\";}if(d===\"\"){continue;}h=\"\";i=E.Index(d,\"=\");if(i>=0){j=$substring(d,0,i);k=$substring(d,(i+1>>0));d=j;h=k;}l=O(d);d=l[0];m=l[1];if(!($interfaceIsEqual(m,$ifaceNil))){if($interfaceIsEqual(c,$ifaceNil)){c=m;}continue;}n=O(h);h=n[0];m=n[1];if(!($interfaceIsEqual(m,$ifaceNil))){if($interfaceIsEqual(c,$ifaceNil)){c=m;}continue;}o=d;(a||$throwRuntimeError(\"assignment to entry in nil map\"))[$String.keyFor(o)]={k:o,v:$append((p=a[$String.keyFor(d)],p!==undefined?p.v:AU.nil),h)};}c=c;return c;};AH.prototype.Encode=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this.$val;if(a===false){$s=-1;return\"\";}b=new E.Builder.ptr(AT.nil,AO.nil);c=$makeSlice(AU,0,$keys(a).length);d=a;e=0;f=$keys(d);while(true){if(!(e<f.length)){break;}g=d[f[e]];if(g===undefined){e++;continue;}h=g.k;c=$append(c,h);e++;}$r=C.Strings(c);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=c;j=0;while(true){if(!(j<i.$length)){break;}k=((j<0||j>=i.$length)?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+j]);m=(l=a[$String.keyFor(k)],l!==undefined?l.v:AU.nil);n=R(k);o=m;p=0;while(true){if(!(p<o.$length)){break;}q=((p<0||p>=o.$length)?($throwRuntimeError(\"index out of range\"),undefined):o.$array[o.$offset+p]);if(b.Len()>0){b.WriteByte(38);}b.WriteString(n);b.WriteByte(61);b.WriteString(R(q));p++;}j++;}$s=-1;return b.String();}return;}if($f===undefined){$f={$blk:AH.prototype.Encode};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(AH).prototype.Encode=function(){return new AH(this.$get()).Encode();};AK=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,l;c=\"\";if(b===\"\"){c=a;}else if(!((b.charCodeAt(0)===47))){d=E.LastIndex(a,\"/\");c=$substring(a,0,(d+1>>0))+b;}else{c=b;}if(c===\"\"){return\"\";}e=AU.nil;f=E.Split(c,\"/\");g=f;h=0;while(true){if(!(h<g.$length)){break;}i=((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h]);j=i;if(j===(\".\")){}else if(j===(\"..\")){if(e.$length>0){e=$subslice(e,0,(e.$length-1>>0));}}else{e=$append(e,i);}h++;}l=(k=f.$length-1>>0,((k<0||k>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+k]));if(l===\".\"||l===\"..\"){e=$append(e,\"\");}return\"/\"+E.TrimPrefix(E.Join(e,\"/\"),\"/\");};U.ptr.prototype.IsAbs=function(){var a;a=this;return!(a.Scheme===\"\");};U.prototype.IsAbs=function(){return this.$val.IsAbs();};U.ptr.prototype.Parse=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;d=AA(a);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}c=d;e=c[0];f=c[1];if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return[AR.nil,f];}$s=-1;return[b.ResolveReference(e),$ifaceNil];}return;}if($f===undefined){$f={$blk:U.ptr.prototype.Parse};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};U.prototype.Parse=function(a){return this.$val.Parse(a);};U.ptr.prototype.ResolveReference=function(a){var a,b,c;b=this;c=$clone(a,U);if(a.Scheme===\"\"){c.Scheme=b.Scheme;}if(!(a.Scheme===\"\")||!(a.Host===\"\")||!(a.User===AQ.nil)){c.setPath(AK(a.EscapedPath(),\"\"));return c;}if(!(a.Opaque===\"\")){c.User=AQ.nil;c.Host=\"\";c.Path=\"\";return c;}if(a.Path===\"\"&&a.RawQuery===\"\"){c.RawQuery=b.RawQuery;if(a.Fragment===\"\"){c.Fragment=b.Fragment;}}c.Host=b.Host;c.User=b.User;c.setPath(AK(b.EscapedPath(),a.EscapedPath()));return c;};U.prototype.ResolveReference=function(a){return this.$val.ResolveReference(a);};U.ptr.prototype.Query=function(){var a,b,c;a=this;b=AI(a.RawQuery);c=b[0];return c;};U.prototype.Query=function(){return this.$val.Query();};U.ptr.prototype.RequestURI=function(){var a,b;a=this;b=a.Opaque;if(b===\"\"){b=a.EscapedPath();if(b===\"\"){b=\"/\";}}else{if(E.HasPrefix(b,\"//\")){b=a.Scheme+\":\"+b;}}if(a.ForceQuery||!(a.RawQuery===\"\")){b=b+(\"?\"+a.RawQuery);}return b;};U.prototype.RequestURI=function(){return this.$val.RequestURI();};U.ptr.prototype.Hostname=function(){var a,b,c;a=this;b=AL(a.Host);c=b[0];return c;};U.prototype.Hostname=function(){return this.$val.Hostname();};U.ptr.prototype.Port=function(){var a,b,c;a=this;b=AL(a.Host);c=b[1];return c;};U.prototype.Port=function(){return this.$val.Port();};AL=function(a){var a,b,c,d,e,f;b=\"\";c=\"\";b=a;d=E.LastIndexByte(b,58);if(!((d===-1))&&AG($substring(b,d))){e=$substring(b,0,d);f=$substring(b,(d+1>>0));b=e;c=f;}if(E.HasPrefix(b,\"[\")&&E.HasSuffix(b,\"]\")){b=$substring(b,1,(b.length-1>>0));}return[b,c];};U.ptr.prototype.MarshalBinary=function(){var a,b,c,d,e;a=AO.nil;b=$ifaceNil;c=this;d=(new AO($stringToBytes(c.String())));e=$ifaceNil;a=d;b=e;return[a,b];};U.prototype.MarshalBinary=function(){return this.$val.MarshalBinary();};U.ptr.prototype.UnmarshalBinary=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;d=AA(($bytesToString(a)));$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}c=d;e=c[0];f=c[1];if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return f;}U.copy(b,e);$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:U.ptr.prototype.UnmarshalBinary};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};U.prototype.UnmarshalBinary=function(a){return this.$val.UnmarshalBinary(a);};AM=function(a){var a,b,c,d,e,f;b=a;c=0;while(true){if(!(c<b.length)){break;}d=$decodeRune(b,c);e=d[0];if(65<=e&&e<=90){c+=d[1];continue;}if(97<=e&&e<=122){c+=d[1];continue;}if(48<=e&&e<=57){c+=d[1];continue;}f=e;if((f===(45))||(f===(46))||(f===(95))||(f===(58))||(f===(126))||(f===(33))||(f===(36))||(f===(38))||(f===(39))||(f===(40))||(f===(41))||(f===(42))||(f===(43))||(f===(44))||(f===(59))||(f===(61))||(f===(37))||(f===(64))){c+=d[1];continue;}else{return false;}c+=d[1];}return true;};AN=function(a){var a,b,c;b=0;while(true){if(!(b<a.length)){break;}c=a.charCodeAt(b);if(c<32||(c===127)){return true;}b=b+(1)>>0;}return false;};AV.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}];L.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];M.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];AR.methods=[{prop:\"setPath\",name:\"setPath\",pkg:\"net/url\",typ:$funcType([$String],[$error],false)},{prop:\"EscapedPath\",name:\"EscapedPath\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"IsAbs\",name:\"IsAbs\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Parse\",name:\"Parse\",pkg:\"\",typ:$funcType([$String],[AR,$error],false)},{prop:\"ResolveReference\",name:\"ResolveReference\",pkg:\"\",typ:$funcType([AR],[AR],false)},{prop:\"Query\",name:\"Query\",pkg:\"\",typ:$funcType([],[AH],false)},{prop:\"RequestURI\",name:\"RequestURI\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Hostname\",name:\"Hostname\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Port\",name:\"Port\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"MarshalBinary\",name:\"MarshalBinary\",pkg:\"\",typ:$funcType([],[AO,$error],false)},{prop:\"UnmarshalBinary\",name:\"UnmarshalBinary\",pkg:\"\",typ:$funcType([AO],[$error],false)}];AQ.methods=[{prop:\"Username\",name:\"Username\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Password\",name:\"Password\",pkg:\"\",typ:$funcType([],[$String,$Bool],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];AH.methods=[{prop:\"Get\",name:\"Get\",pkg:\"\",typ:$funcType([$String],[$String],false)},{prop:\"Set\",name:\"Set\",pkg:\"\",typ:$funcType([$String,$String],[],false)},{prop:\"Add\",name:\"Add\",pkg:\"\",typ:$funcType([$String,$String],[],false)},{prop:\"Del\",name:\"Del\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"Encode\",name:\"Encode\",pkg:\"\",typ:$funcType([],[$String],false)}];F.init(\"\",[{prop:\"Op\",name:\"Op\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"URL\",name:\"URL\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Err\",name:\"Err\",embedded:false,exported:true,typ:$error,tag:\"\"}]);G.init([{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)}]);H.init([{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}]);U.init(\"\",[{prop:\"Scheme\",name:\"Scheme\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Opaque\",name:\"Opaque\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"User\",name:\"User\",embedded:false,exported:true,typ:AQ,tag:\"\"},{prop:\"Host\",name:\"Host\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Path\",name:\"Path\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"RawPath\",name:\"RawPath\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"ForceQuery\",name:\"ForceQuery\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"RawQuery\",name:\"RawQuery\",embedded:false,exported:true,typ:$String,tag:\"\"},{prop:\"Fragment\",name:\"Fragment\",embedded:false,exported:true,typ:$String,tag:\"\"}]);X.init(\"net/url\",[{prop:\"username\",name:\"username\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"password\",name:\"password\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"passwordSet\",name:\"passwordSet\",embedded:false,exported:false,typ:$Bool,tag:\"\"}]);AH.init($String,AU);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\"]=(function(){var $pkg={},$init,B,C,G,H,D,E,A,F,I,K,M,R,S,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,N,J,L,O,P,Q,T;B=$packages[\"bytes\"];C=$packages[\"fmt\"];G=$packages[\"github.com/gopherjs/gopherjs/js\"];H=$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket/websocketjs\"];D=$packages[\"io\"];E=$packages[\"net\"];A=$packages[\"net/url\"];F=$packages[\"time\"];I=$pkg.addr=$newType(0,$kindStruct,\"websocket.addr\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",false,function(URL_){this.$val=this;if(arguments.length===0){this.URL=AA.nil;return;}this.URL=URL_;});K=$pkg.closeError=$newType(0,$kindStruct,\"websocket.closeError\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",false,function(Object_,Code_,Reason_,WasClean_){this.$val=this;if(arguments.length===0){this.Object=null;this.Code=0;this.Reason=\"\";this.WasClean=false;return;}this.Object=Object_;this.Code=Code_;this.Reason=Reason_;this.WasClean=WasClean_;});M=$pkg.deadlineErr=$newType(0,$kindStruct,\"websocket.deadlineErr\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",false,function(){this.$val=this;if(arguments.length===0){return;}});R=$pkg.conn=$newType(0,$kindStruct,\"websocket.conn\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",false,function(WebSocket_,ch_,readBuf_,readDeadline_){this.$val=this;if(arguments.length===0){this.WebSocket=V.nil;this.ch=$chanNil;this.readBuf=W.nil;this.readDeadline=new F.Time.ptr(new $Uint64(0,0),new $Int64(0,0),X.nil);return;}this.WebSocket=WebSocket_;this.ch=ch_;this.readBuf=readBuf_;this.readDeadline=readDeadline_;});S=$pkg.messageEvent=$newType(0,$kindStruct,\"websocket.messageEvent\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",false,function(Object_,Data_){this.$val=this;if(arguments.length===0){this.Object=null;this.Data=null;return;}this.Object=Object_;this.Data=Data_;});U=$sliceType($emptyInterface);V=$ptrType(H.WebSocket);W=$ptrType(B.Reader);X=$ptrType(F.Location);Y=$ptrType(S);Z=$sliceType($Uint8);AA=$ptrType(A.URL);AB=$ptrType(I);AC=$ptrType(K);AD=$ptrType(G.Object);AE=$ptrType(M);AF=$ptrType(R);AG=$chanType(Y,false,false);I.ptr.prototype.Network=function(){var a;a=this;return\"websocket\";};I.prototype.Network=function(){return this.$val.Network();};J=function(a,b){var a,b;return(function $b(c){var c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=b();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$close(a);$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.c=c;$f.$s=$s;$f.$r=$r;return $f;});};K.ptr.prototype.Error=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=\"\";if(!!(a.Object.wasClean)){b=\"clean\";}else{b=\"unclean\";}c=C.Sprintf(\"CloseEvent: (%s) (%d) %s\",new U([new $String(b),new $Int(($parseInt(a.Object.code)>>0)),new $String($internalize(a.Object.reason,$String))]));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}$s=-1;return c;}return;}if($f===undefined){$f={$blk:K.ptr.prototype.Error};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};K.prototype.Error=function(){return this.$val.Error();};L=function(a,b){var a,b;return(function $b(c){var c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=[c];$r=b();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$go((function(c){return function $b(){var $s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=$send(a,new K.ptr(c[0],0,\"\",false));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$close(a);$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.$s=$s;$f.$r=$r;return $f;};})(c),[]);$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.c=c;$f.$s=$s;$f.$r=$r;return $f;});};M.ptr.prototype.Error=function(){var a;a=this;return\"i/o timeout: deadline reached\";};M.prototype.Error=function(){return this.$val.Error();};M.ptr.prototype.Timeout=function(){var a;a=this;return true;};M.prototype.Timeout=function(){return this.$val.Timeout();};M.ptr.prototype.Temporary=function(){var a;a=this;return true;};M.prototype.Temporary=function(){return this.$val.Temporary();};O=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=H.New(a);c=b[0];d=b[1];e=Q(d,c);$s=1;case 1:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:O};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Dial=O;P=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=H.New2(a,b);d=c[0];e=c[1];f=Q(e,d);$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return f;}return;}if($f===undefined){$f={$blk:P};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Dial2=P;Q=function(a,b){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=[b];c=[c];d=[d];if(!($interfaceIsEqual(a,$ifaceNil))){$s=-1;return[$ifaceNil,a];}e=new R.ptr(b[0],new $Chan(Y,1),W.nil,new F.Time.ptr(new $Uint64(0,0),new $Int64(0,0),X.nil));e.initialize();f=new $Chan($error,1);d[0]=$throwNilPointerError;c[0]=$throwNilPointerError;g=(function(b,c,d){return function(){b[0].RemoveEventListener(\"open\",false,d[0]);b[0].RemoveEventListener(\"close\",false,c[0]);};})(b,c,d);d[0]=J(f,g);c[0]=L(f,g);b[0].AddEventListener(\"open\",false,d[0]);b[0].AddEventListener(\"close\",false,c[0]);i=$recv(f);$s=1;case 1:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;a=h[0];j=h[1];if(j&&!($interfaceIsEqual(a,$ifaceNil))){$s=-1;return[$ifaceNil,a];}$s=-1;return[e,$ifaceNil];}return;}if($f===undefined){$f={$blk:Q};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};R.ptr.prototype.onMessage=function(a){var a,b;b=this;$go((function $b(){var $s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=$send(b.ch,new S.ptr(a,null));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.$s=$s;$f.$r=$r;return $f;}),[]);};R.prototype.onMessage=function(a){return this.$val.onMessage(a);};R.ptr.prototype.onClose=function(a){var a,b;b=this;$go((function $b(){var $s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=$send(b.ch,Y.nil);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.$s=$s;$f.$r=$r;return $f;}),[]);};R.prototype.onClose=function(a){return this.$val.onClose(a);};R.ptr.prototype.initialize=function(){var a;a=this;a.WebSocket.Object.binaryType=$externalize(\"arraybuffer\",$String);a.WebSocket.AddEventListener(\"message\",false,$methodVal(a,\"onMessage\"));a.WebSocket.AddEventListener(\"close\",false,$methodVal(a,\"onClose\"));};R.prototype.initialize=function(){return this.$val.initialize();};R.ptr.prototype.handleFrame=function(a,b){var a,b,c;c=this;if(!b){return[Y.nil,D.EOF];}else if(a===Y.nil){$close(c.ch);return[Y.nil,D.EOF];}return[a,$ifaceNil];};R.prototype.handleFrame=function(a,b){return this.$val.handleFrame(a,b);};R.ptr.prototype.receiveFrame=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=this;c=$chanNil;if(a&&!$clone(b.readDeadline,F.Time).IsZero()){$s=1;continue;}$s=2;continue;case 1:d=$clone(F.Now(),F.Time);if($clone(d,F.Time).After($clone(b.readDeadline,F.Time))){e=$select([[b.ch],[]]);if(e[0]===0){f=e[1];g=f[0];h=f[1];$s=-1;return b.handleFrame(g,h);}else if(e[0]===1){$s=-1;return[Y.nil,N];}}i=F.NewTimer($clone(b.readDeadline,F.Time).Sub($clone(d,F.Time)));$deferred.push([$methodVal(i,\"Stop\"),[]]);c=i.C;case 2:k=$select([[b.ch],[c]]);$s=3;case 3:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;if(j[0]===0){l=j[1];m=l[0];n=l[1];$s=-1;return b.handleFrame(m,n);}else if(j[0]===1){$s=-1;return[Y.nil,N];}$s=-1;return[Y.nil,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[Y.nil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:R.ptr.prototype.receiveFrame};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};R.prototype.receiveFrame=function(a){return this.$val.receiveFrame(a);};T=function(a){var a,b,c;b=a.constructor;if(b===$global.ArrayBuffer){c=new($global.Uint8Array)(a);return $assertType($internalize(c,$emptyInterface),Z);}return(new Z($stringToBytes($internalize(a,$String))));};R.ptr.prototype.Read=function(a){var a,b,c,d,e,f,g,h,i,j,k,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;if(!(d.readBuf===W.nil)){e=d.readBuf.Read(a);b=e[0];c=e[1];if($interfaceIsEqual(c,D.EOF)){d.readBuf=W.nil;c=$ifaceNil;}if(b>0){$s=-1;return[b,c];}}g=d.receiveFrame(true);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;h=f[0];c=f[1];if(!($interfaceIsEqual(c,$ifaceNil))){i=0;j=c;b=i;c=j;$s=-1;return[b,c];}k=T(h.Object.data);b=$copySlice(a,k);if(b>=k.$length){$s=-1;return[b,c];}d.readBuf=B.NewReader($subslice(k,b));$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:R.ptr.prototype.Read};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$r=$r;return $f;};R.prototype.Read=function(a){return this.$val.Read(a);};R.ptr.prototype.Write=function(a){var a,b,c,d,e,f,g,h;b=0;c=$ifaceNil;d=this;c=d.WebSocket.Send(a);if(!($interfaceIsEqual(c,$ifaceNil))){e=0;f=c;b=e;c=f;return[b,c];}g=a.$length;h=$ifaceNil;b=g;c=h;return[b,c];};R.prototype.Write=function(a){return this.$val.Write(a);};R.ptr.prototype.LocalAddr=function(){var a;a=this;$panic(new $String(\"we are unable to implement websocket.conn.LocalAddr() due to limitations in the underlying JavaScript API\"));};R.prototype.LocalAddr=function(){return this.$val.LocalAddr();};R.ptr.prototype.RemoteAddr=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;c=A.Parse($internalize(a.WebSocket.Object.url,$String));$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}b=c;d=b[0];e=b[1];if(!($interfaceIsEqual(e,$ifaceNil))){$panic(e);}$s=-1;return new I.ptr(d);}return;}if($f===undefined){$f={$blk:R.ptr.prototype.RemoteAddr};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};R.prototype.RemoteAddr=function(){return this.$val.RemoteAddr();};R.ptr.prototype.SetDeadline=function(a){var a,b;b=this;F.Time.copy(b.readDeadline,a);return $ifaceNil;};R.prototype.SetDeadline=function(a){return this.$val.SetDeadline(a);};R.ptr.prototype.SetReadDeadline=function(a){var a,b;b=this;F.Time.copy(b.readDeadline,a);return $ifaceNil;};R.prototype.SetReadDeadline=function(a){return this.$val.SetReadDeadline(a);};R.ptr.prototype.SetWriteDeadline=function(a){var a,b;b=this;return $ifaceNil;};R.prototype.SetWriteDeadline=function(a){return this.$val.SetWriteDeadline(a);};AB.methods=[{prop:\"Network\",name:\"Network\",pkg:\"\",typ:$funcType([],[$String],false)}];AC.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)}];AE.methods=[{prop:\"Error\",name:\"Error\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"Timeout\",name:\"Timeout\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"Temporary\",name:\"Temporary\",pkg:\"\",typ:$funcType([],[$Bool],false)}];AF.methods=[{prop:\"onMessage\",name:\"onMessage\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",typ:$funcType([AD],[],false)},{prop:\"onClose\",name:\"onClose\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",typ:$funcType([AD],[],false)},{prop:\"initialize\",name:\"initialize\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",typ:$funcType([],[],false)},{prop:\"handleFrame\",name:\"handleFrame\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",typ:$funcType([Y,$Bool],[Y,$error],false)},{prop:\"receiveFrame\",name:\"receiveFrame\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",typ:$funcType([$Bool],[Y,$error],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([Z],[$Int,$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([Z],[$Int,$error],false)},{prop:\"LocalAddr\",name:\"LocalAddr\",pkg:\"\",typ:$funcType([],[E.Addr],false)},{prop:\"RemoteAddr\",name:\"RemoteAddr\",pkg:\"\",typ:$funcType([],[E.Addr],false)},{prop:\"SetDeadline\",name:\"SetDeadline\",pkg:\"\",typ:$funcType([F.Time],[$error],false)},{prop:\"SetReadDeadline\",name:\"SetReadDeadline\",pkg:\"\",typ:$funcType([F.Time],[$error],false)},{prop:\"SetWriteDeadline\",name:\"SetWriteDeadline\",pkg:\"\",typ:$funcType([F.Time],[$error],false)}];I.init(\"\",[{prop:\"URL\",name:\"URL\",embedded:true,exported:true,typ:AA,tag:\"\"}]);K.init(\"\",[{prop:\"Object\",name:\"Object\",embedded:true,exported:true,typ:AD,tag:\"\"},{prop:\"Code\",name:\"Code\",embedded:false,exported:true,typ:$Int,tag:\"js:\\\"code\\\"\"},{prop:\"Reason\",name:\"Reason\",embedded:false,exported:true,typ:$String,tag:\"js:\\\"reason\\\"\"},{prop:\"WasClean\",name:\"WasClean\",embedded:false,exported:true,typ:$Bool,tag:\"js:\\\"wasClean\\\"\"}]);M.init(\"\",[]);R.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\",[{prop:\"WebSocket\",name:\"WebSocket\",embedded:true,exported:true,typ:V,tag:\"\"},{prop:\"ch\",name:\"ch\",embedded:false,exported:false,typ:AG,tag:\"\"},{prop:\"readBuf\",name:\"readBuf\",embedded:false,exported:false,typ:W,tag:\"\"},{prop:\"readDeadline\",name:\"readDeadline\",embedded:false,exported:false,typ:F.Time,tag:\"\"}]);S.init(\"\",[{prop:\"Object\",name:\"Object\",embedded:true,exported:true,typ:AD,tag:\"\"},{prop:\"Data\",name:\"Data\",embedded:false,exported:true,typ:AD,tag:\"js:\\\"data\\\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=B.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=H.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}N=new M.ptr();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"container/heap\"]=(function(){var $pkg={},$init,A,D,E,H,I;A=$packages[\"sort\"];D=function(a,b){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=a.Push(b);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=a;d=a.Len();$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d-1>>0;$r=H(c,e);$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:D};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Push=D;E=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=a.Len();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b-1>>0;$r=a.Swap(0,c);$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=I(a,0,c);$s=3;case 3:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}d;e=a.Pop();$s=4;case 4:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;}return;}if($f===undefined){$f={$blk:E};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Pop=E;H=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:case 1:d=(c=((b-1>>0))/2,(c===c&&c!==1/0&&c!==-1/0)?c>>0:$throwRuntimeError(\"integer divide by zero\"));if(d===b){e=true;$s=5;continue s;}f=a.Less(b,d);$s=6;case 6:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=!f;case 5:if(e){$s=3;continue;}$s=4;continue;case 3:$s=2;continue;case 4:$r=a.Swap(d,b);$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}b=d;$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:H};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};I=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=b;case 1:e=($imul(2,d))+1>>0;if(e>=c||e<0){$s=2;continue;}f=e;g=e+1>>0;if(!(g<c)){h=false;$s=5;continue s;}i=a.Less(g,e);$s=6;case 6:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;case 5:if(h){$s=3;continue;}$s=4;continue;case 3:f=g;case 4:j=a.Less(f,d);$s=9;case 9:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}if(!j){$s=7;continue;}$s=8;continue;case 7:$s=2;continue;case 8:$r=a.Swap(d,f);$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=f;$s=1;continue;case 2:$s=-1;return d>b;}return;}if($f===undefined){$f={$blk:I};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\"]=(function(){var $pkg={},$init,H,C,A,D,E,F,I,B,J,G,N,Q,S,T,U,Z,AA,AB,AC,AE,AF,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,K,L,M,O,P,R,V,W,Y,AD,AG;H=$packages[\"container/heap\"];C=$packages[\"encoding/binary\"];A=$packages[\"errors\"];D=$packages[\"fmt\"];E=$packages[\"io\"];F=$packages[\"math\"];I=$packages[\"net\"];B=$packages[\"sync\"];J=$packages[\"sync/atomic\"];G=$packages[\"time\"];N=$pkg.Allocator=$newType(0,$kindStruct,\"smux.Allocator\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",true,function(buffers_){this.$val=this;if(arguments.length===0){this.buffers=AI.nil;return;}this.buffers=buffers_;});Q=$pkg.Frame=$newType(0,$kindStruct,\"smux.Frame\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",true,function(ver_,cmd_,sid_,data_){this.$val=this;if(arguments.length===0){this.ver=0;this.cmd=0;this.sid=0;this.data=AJ.nil;return;}this.ver=ver_;this.cmd=cmd_;this.sid=sid_;this.data=data_;});S=$pkg.rawHeader=$newType(8,$kindArray,\"smux.rawHeader\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",false,null);T=$pkg.updHeader=$newType(8,$kindArray,\"smux.updHeader\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",false,null);U=$pkg.Config=$newType(0,$kindStruct,\"smux.Config\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",true,function(Version_,KeepAliveDisabled_,KeepAliveInterval_,KeepAliveTimeout_,MaxFrameSize_,MaxReceiveBuffer_,MaxStreamBuffer_){this.$val=this;if(arguments.length===0){this.Version=0;this.KeepAliveDisabled=false;this.KeepAliveInterval=new G.Duration(0,0);this.KeepAliveTimeout=new G.Duration(0,0);this.MaxFrameSize=0;this.MaxReceiveBuffer=0;this.MaxStreamBuffer=0;return;}this.Version=Version_;this.KeepAliveDisabled=KeepAliveDisabled_;this.KeepAliveInterval=KeepAliveInterval_;this.KeepAliveTimeout=KeepAliveTimeout_;this.MaxFrameSize=MaxFrameSize_;this.MaxReceiveBuffer=MaxReceiveBuffer_;this.MaxStreamBuffer=MaxStreamBuffer_;});Z=$pkg.writeRequest=$newType(0,$kindStruct,\"smux.writeRequest\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",false,function(prio_,frame_,result_){this.$val=this;if(arguments.length===0){this.prio=new $Uint64(0,0);this.frame=new Q.ptr(0,0,0,AJ.nil);this.result=$chanNil;return;}this.prio=prio_;this.frame=frame_;this.result=result_;});AA=$pkg.writeResult=$newType(0,$kindStruct,\"smux.writeResult\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",false,function(n_,err_){this.$val=this;if(arguments.length===0){this.n=0;this.err=$ifaceNil;return;}this.n=n_;this.err=err_;});AB=$pkg.buffersWriter=$newType(8,$kindInterface,\"smux.buffersWriter\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",false,null);AC=$pkg.Session=$newType(0,$kindStruct,\"smux.Session\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",true,function(conn_,config_,nextStreamID_,nextStreamIDLock_,bucket_,bucketNotify_,streams_,streamLock_,die_,dieOnce_,socketReadError_,socketWriteError_,chSocketReadError_,chSocketWriteError_,socketReadErrorOnce_,socketWriteErrorOnce_,protoError_,chProtoError_,protoErrorOnce_,chAccepts_,dataReady_,goAway_,deadline_,shaper_,writes_){this.$val=this;if(arguments.length===0){this.conn=$ifaceNil;this.config=AL.nil;this.nextStreamID=0;this.nextStreamIDLock=new B.Mutex.ptr(0,0);this.bucket=0;this.bucketNotify=$chanNil;this.streams=false;this.streamLock=new B.Mutex.ptr(0,0);this.die=$chanNil;this.dieOnce=new B.Once.ptr(new B.Mutex.ptr(0,0),0);this.socketReadError=new J.Value.ptr($ifaceNil);this.socketWriteError=new J.Value.ptr($ifaceNil);this.chSocketReadError=$chanNil;this.chSocketWriteError=$chanNil;this.socketReadErrorOnce=new B.Once.ptr(new B.Mutex.ptr(0,0),0);this.socketWriteErrorOnce=new B.Once.ptr(new B.Mutex.ptr(0,0),0);this.protoError=new J.Value.ptr($ifaceNil);this.chProtoError=$chanNil;this.protoErrorOnce=new B.Once.ptr(new B.Mutex.ptr(0,0),0);this.chAccepts=$chanNil;this.dataReady=0;this.goAway=0;this.deadline=new J.Value.ptr($ifaceNil);this.shaper=$chanNil;this.writes=$chanNil;return;}this.conn=conn_;this.config=config_;this.nextStreamID=nextStreamID_;this.nextStreamIDLock=nextStreamIDLock_;this.bucket=bucket_;this.bucketNotify=bucketNotify_;this.streams=streams_;this.streamLock=streamLock_;this.die=die_;this.dieOnce=dieOnce_;this.socketReadError=socketReadError_;this.socketWriteError=socketWriteError_;this.chSocketReadError=chSocketReadError_;this.chSocketWriteError=chSocketWriteError_;this.socketReadErrorOnce=socketReadErrorOnce_;this.socketWriteErrorOnce=socketWriteErrorOnce_;this.protoError=protoError_;this.chProtoError=chProtoError_;this.protoErrorOnce=protoErrorOnce_;this.chAccepts=chAccepts_;this.dataReady=dataReady_;this.goAway=goAway_;this.deadline=deadline_;this.shaper=shaper_;this.writes=writes_;});AE=$pkg.shaperHeap=$newType(12,$kindSlice,\"smux.shaperHeap\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",false,null);AF=$pkg.Stream=$newType(0,$kindStruct,\"smux.Stream\",true,\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",true,function(id_,sess_,buffers_,heads_,bufferLock_,frameSize_,chReadEvent_,die_,dieOnce_,chFinEvent_,finEventOnce_,readDeadline_,writeDeadline_,numRead_,numWritten_,incr_,peerConsumed_,peerWindow_,chUpdate_){this.$val=this;if(arguments.length===0){this.id=0;this.sess=AM.nil;this.buffers=AU.nil;this.heads=AU.nil;this.bufferLock=new B.Mutex.ptr(0,0);this.frameSize=0;this.chReadEvent=$chanNil;this.die=$chanNil;this.dieOnce=new B.Once.ptr(new B.Mutex.ptr(0,0),0);this.chFinEvent=$chanNil;this.finEventOnce=new B.Once.ptr(new B.Mutex.ptr(0,0),0);this.readDeadline=new J.Value.ptr($ifaceNil);this.writeDeadline=new J.Value.ptr($ifaceNil);this.numRead=0;this.numWritten=0;this.incr=0;this.peerConsumed=0;this.peerWindow=0;this.chUpdate=$chanNil;return;}this.id=id_;this.sess=sess_;this.buffers=buffers_;this.heads=heads_;this.bufferLock=bufferLock_;this.frameSize=frameSize_;this.chReadEvent=chReadEvent_;this.die=die_;this.dieOnce=dieOnce_;this.chFinEvent=chFinEvent_;this.finEventOnce=finEventOnce_;this.readDeadline=readDeadline_;this.writeDeadline=writeDeadline_;this.numRead=numRead_;this.numWritten=numWritten_;this.incr=incr_;this.peerConsumed=peerConsumed_;this.peerWindow=peerWindow_;this.chUpdate=chUpdate_;});AH=$ptrType(N);AI=$sliceType(B.Pool);AJ=$sliceType($Uint8);AK=$sliceType($emptyInterface);AL=$ptrType(U);AM=$ptrType(AC);AN=$structType(\"\",[]);AO=$ptrType(AF);AP=$interfaceType([{prop:\"LocalAddr\",name:\"LocalAddr\",pkg:\"\",typ:$funcType([],[I.Addr],false)}]);AQ=$interfaceType([{prop:\"RemoteAddr\",name:\"RemoteAddr\",pkg:\"\",typ:$funcType([],[I.Addr],false)}]);AR=$ptrType($Int32);AS=$arrayType($Uint8,8);AT=$ptrType(AE);AU=$sliceType(AJ);AV=$ptrType(G.Timer);AW=$ptrType($Uint32);AX=$chanType(AA,false,false);AY=$chanType(G.Time,false,true);AZ=$chanType(AN,false,false);BA=$mapType($Uint32,AO);BB=$chanType(AO,false,false);BC=$chanType(Z,false,false);BD=$chanType(AN,false,true);M=function(){K=O();};O=function(){var a,b,c,d,e,f;a=new N.ptr(AI.nil);a.buffers=$makeSlice(AI,17);b=a.buffers;c=0;while(true){if(!(c<b.$length)){break;}d=[d];e=c;d[0]=e;(f=a.buffers,((e<0||e>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+e])).New=(function(d){return function(){var f;return $makeSlice(AJ,((f=((d[0]>>>0)),f<32?(1<<f):0)>>0));};})(d);c++;}return a;};$pkg.NewAllocator=O;N.ptr.prototype.Get=function(a){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;if(a<=0||a>65536){$s=-1;return AJ.nil;}c=P(a);if(a===((d=c,d<32?(1<<d):0)>>0)){$s=1;continue;}$s=2;continue;case 1:f=(e=b.buffers,((c<0||c>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+c])).Get();$s=4;case 4:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}$s=-1;return $subslice($assertType(f,AJ),0,a);case 2:i=(g=b.buffers,h=c+1<<24>>>24,((h<0||h>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+h])).Get();$s=5;case 5:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}$s=-1;return $subslice($assertType(i,AJ),0,a);case 3:$s=-1;return AJ.nil;}return;}if($f===undefined){$f={$blk:N.ptr.prototype.Get};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};N.prototype.Get=function(a){return this.$val.Get(a);};N.ptr.prototype.Put=function(a){var a,b,c,d,e;b=this;c=P(a.$capacity);if((a.$capacity===0)||a.$capacity>65536||!((a.$capacity===((d=c,d<32?(1<<d):0)>>0)))){return A.New(\"allocator Put() incorrect buffer size\");}(e=b.buffers,((c<0||c>=e.$length)?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+c])).Put(a);return $ifaceNil;};N.prototype.Put=function(a){return this.$val.Put(a);};P=function(a){var a,b,c;b=((a>>>0));b=(b|((b>>>1>>>0)))>>>0;b=(b|((b>>>2>>>0)))>>>0;b=(b|((b>>>4>>>0)))>>>0;b=(b|((b>>>8>>>0)))>>>0;b=(b|((b>>>16>>>0)))>>>0;return(c=(($imul(b,130329821)>>>0))>>>27>>>0,((c<0||c>=L.length)?($throwRuntimeError(\"index out of range\"),undefined):L[c]));};R=function(a,b,c){var a,b,c;return new Q.ptr(a,b,c,AJ.nil);};S.prototype.Version=function(){var a;a=this.$val;return a[0];};$ptrType(S).prototype.Version=function(){return new S(this.$get()).Version();};S.prototype.Cmd=function(){var a;a=this.$val;return a[1];};$ptrType(S).prototype.Cmd=function(){return new S(this.$get()).Cmd();};S.prototype.Length=function(){var a;a=this.$val;return $clone(C.LittleEndian,C.littleEndian).Uint16($subslice(new AJ(a),2));};$ptrType(S).prototype.Length=function(){return new S(this.$get()).Length();};S.prototype.StreamID=function(){var a;a=this.$val;return $clone(C.LittleEndian,C.littleEndian).Uint32($subslice(new AJ(a),4));};$ptrType(S).prototype.StreamID=function(){return new S(this.$get()).StreamID();};S.prototype.String=function(){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this.$val;b=D.Sprintf(\"Version:%d Cmd:%d StreamID:%d Length:%d\",new AK([new $Uint8(new S($clone(a,S)).Version()),new $Uint8(new S($clone(a,S)).Cmd()),new $Uint32(new S($clone(a,S)).StreamID()),new $Uint16(new S($clone(a,S)).Length())]));$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}$s=-1;return b;}return;}if($f===undefined){$f={$blk:S.prototype.String};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};$ptrType(S).prototype.String=function(){return new S(this.$get()).String();};T.prototype.Consumed=function(){var a;a=this.$val;return $clone(C.LittleEndian,C.littleEndian).Uint32(new AJ(a));};$ptrType(T).prototype.Consumed=function(){return new T(this.$get()).Consumed();};T.prototype.Window=function(){var a;a=this.$val;return $clone(C.LittleEndian,C.littleEndian).Uint32($subslice(new AJ(a),4));};$ptrType(T).prototype.Window=function(){return new T(this.$get()).Window();};V=function(){return new U.ptr(1,false,new G.Duration(2,1410065408),new G.Duration(6,4230196224),32768,4194304,65536);};$pkg.DefaultConfig=V;W=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(!((a.Version===1)||(a.Version===2))){$s=-1;return A.New(\"unsupported protocol version\");}if(!a.KeepAliveDisabled){$s=1;continue;}$s=2;continue;case 1:if((b=a.KeepAliveInterval,(b.$high===0&&b.$low===0))){$s=-1;return A.New(\"keep-alive interval must be positive\");}if((c=a.KeepAliveTimeout,d=a.KeepAliveInterval,(c.$high<d.$high||(c.$high===d.$high&&c.$low<d.$low)))){$s=3;continue;}$s=4;continue;case 3:e=D.Errorf(\"keep-alive timeout must be larger than keep-alive interval\",new AK([]));$s=5;case 5:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;case 4:case 2:if(a.MaxFrameSize<=0){$s=-1;return A.New(\"max frame size must be positive\");}if(a.MaxFrameSize>65535){$s=-1;return A.New(\"max frame size must not be larger than 65535\");}if(a.MaxReceiveBuffer<=0){$s=-1;return A.New(\"max receive buffer must be positive\");}if(a.MaxStreamBuffer<=0){$s=-1;return A.New(\"max stream buffer must be positive\");}if(a.MaxStreamBuffer>a.MaxReceiveBuffer){$s=-1;return A.New(\"max stream buffer must not be larger than max receive buffer\");}if(a.MaxStreamBuffer>2147483647){$s=-1;return A.New(\"max stream buffer cannot be larger than 2147483647\");}$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:W};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};$pkg.VerifyConfig=W;Y=function(a,b){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:if(b===AL.nil){b=V();}c=W(b);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;if(!($interfaceIsEqual(d,$ifaceNil))){$s=-1;return[AM.nil,d];}$s=-1;return[AD(b,a,true),$ifaceNil];}return;}if($f===undefined){$f={$blk:Y};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Client=Y;AD=function(a,b,c){var a,b,c,d;d=new AC.ptr($ifaceNil,AL.nil,0,new B.Mutex.ptr(0,0),0,$chanNil,false,new B.Mutex.ptr(0,0),$chanNil,new B.Once.ptr(new B.Mutex.ptr(0,0),0),new J.Value.ptr($ifaceNil),new J.Value.ptr($ifaceNil),$chanNil,$chanNil,new B.Once.ptr(new B.Mutex.ptr(0,0),0),new B.Once.ptr(new B.Mutex.ptr(0,0),0),new J.Value.ptr($ifaceNil),$chanNil,new B.Once.ptr(new B.Mutex.ptr(0,0),0),$chanNil,0,0,new J.Value.ptr($ifaceNil),$chanNil,$chanNil);d.die=new $Chan(AN,0);d.conn=b;d.config=a;d.streams={};d.chAccepts=new $Chan(AO,1024);d.bucket=((a.MaxReceiveBuffer>>0));d.bucketNotify=new $Chan(AN,1);d.shaper=new $Chan(Z,0);d.writes=new $Chan(Z,0);d.chSocketReadError=new $Chan(AN,0);d.chSocketWriteError=new $Chan(AN,0);d.chProtoError=new $Chan(AN,0);if(c){d.nextStreamID=1;}else{d.nextStreamID=0;}$go($methodVal(d,\"shaperLoop\"),[]);$go($methodVal(d,\"recvLoop\"),[]);$go($methodVal(d,\"sendLoop\"),[]);if(!a.KeepAliveDisabled){$go($methodVal(d,\"keepalive\"),[]);}return d;};AC.ptr.prototype.OpenStream=function(){var a,b,c,d,e,f,g,h,i,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;if(a.IsClosed()){$s=-1;return[AO.nil,E.ErrClosedPipe];}$r=a.nextStreamIDLock.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(a.goAway>0){$s=2;continue;}$s=3;continue;case 2:$r=a.nextStreamIDLock.Unlock();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return[AO.nil,$pkg.ErrGoAway];case 3:a.nextStreamID=a.nextStreamID+(2)>>>0;b=a.nextStreamID;if(b===(c=b%2,c===c?c:$throwRuntimeError(\"integer divide by zero\"))){$s=5;continue;}$s=6;continue;case 5:a.goAway=1;$r=a.nextStreamIDLock.Unlock();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return[AO.nil,$pkg.ErrGoAway];case 6:$r=a.nextStreamIDLock.Unlock();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=AG(b,a.config.MaxFrameSize,a);f=a.writeFrame($clone(R(((a.config.Version<<24>>>24)),0,b),Q));$s=9;case 9:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;g=e[1];if(!($interfaceIsEqual(g,$ifaceNil))){$s=-1;return[AO.nil,g];}$r=a.streamLock.Lock();$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(a.streamLock,\"Unlock\"),[]]);h=$select([[a.chSocketReadError],[a.chSocketWriteError],[a.die],[]]);if(h[0]===0){$s=-1;return[AO.nil,$assertType(a.socketReadError.Load(),$error)];}else if(h[0]===1){$s=-1;return[AO.nil,$assertType(a.socketWriteError.Load(),$error)];}else if(h[0]===2){$s=-1;return[AO.nil,E.ErrClosedPipe];}else if(h[0]===3){i=b;(a.streams||$throwRuntimeError(\"assignment to entry in nil map\"))[$Uint32.keyFor(i)]={k:i,v:d};$s=-1;return[d,$ifaceNil];}$s=-1;return[AO.nil,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[AO.nil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AC.ptr.prototype.OpenStream};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AC.prototype.OpenStream=function(){return this.$val.OpenStream();};AC.ptr.prototype.Open=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.OpenStream();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;$s=-1;return[c[0],c[1]];}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.Open};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.Open=function(){return this.$val.Open();};AC.ptr.prototype.AcceptStream=function(){var a,b,c,d,e,f,g,h,i,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;b=$chanNil;c=$assertType(a.deadline.Load(),G.Time,true);d=$clone(c[0],G.Time);e=c[1];if(e&&!$clone(d,G.Time).IsZero()){f=G.NewTimer(G.Until($clone(d,G.Time)));$deferred.push([$methodVal(f,\"Stop\"),[]]);b=f.C;}h=$select([[a.chAccepts],[b],[a.chSocketReadError],[a.chProtoError],[a.die]]);$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;if(g[0]===0){i=g[1][0];$s=-1;return[i,$ifaceNil];}else if(g[0]===1){$s=-1;return[AO.nil,$pkg.ErrTimeout];}else if(g[0]===2){$s=-1;return[AO.nil,$assertType(a.socketReadError.Load(),$error)];}else if(g[0]===3){$s=-1;return[AO.nil,$assertType(a.protoError.Load(),$error)];}else if(g[0]===4){$s=-1;return[AO.nil,E.ErrClosedPipe];}$s=-1;return[AO.nil,$ifaceNil];}return;}}catch(err){$err=err;$s=-1;return[AO.nil,$ifaceNil];}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AC.ptr.prototype.AcceptStream};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AC.prototype.AcceptStream=function(){return this.$val.AcceptStream();};AC.ptr.prototype.Accept=function(){var a,b,c,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=a.AcceptStream();$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;$s=-1;return[c[0],c[1]];}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.Accept};}$f.a=a;$f.b=b;$f.c=c;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.Accept=function(){return this.$val.Accept();};AC.ptr.prototype.Close=function(){var a,b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];b[0]=this;a[0]=false;$r=b[0].dieOnce.Do((function(a,b){return function(){$close(b[0].die);a[0]=true;};})(a,b));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(a[0]){$s=2;continue;}$s=3;continue;case 2:$r=b[0].streamLock.Lock();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=b[0].streams;d=0;e=$keys(c);case 6:if(!(d<e.length)){$s=7;continue;}f=c[e[d]];if(f===undefined){d++;$s=6;continue;}g=f.k;$r=(h=b[0].streams[$Uint32.keyFor(g)],h!==undefined?h.v:AO.nil).sessionClose();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d++;$s=6;continue;case 7:$r=b[0].streamLock.Unlock();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=b[0].conn.Close();$s=10;case 10:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}$s=-1;return i;case 3:$s=-1;return E.ErrClosedPipe;case 4:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.Close};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.Close=function(){return this.$val.Close();};AC.ptr.prototype.notifyBucket=function(){var a,b,$r;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$r=$f.$r;}a=this;b=$select([[a.bucketNotify,new AN.ptr()],[]]);if(b[0]===0){}else if(b[0]===1){}if($f===undefined){$f={$blk:AC.ptr.prototype.notifyBucket};}$f.a=a;$f.b=b;$f.$r=$r;return $f;};AC.prototype.notifyBucket=function(){return this.$val.notifyBucket();};AC.ptr.prototype.notifyReadError=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];b[0]=this;$r=b[0].socketReadErrorOnce.Do((function(a,b){return function(){b[0].socketReadError.Store(a[0]);$close(b[0].chSocketReadError);};})(a,b));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.notifyReadError};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.notifyReadError=function(a){return this.$val.notifyReadError(a);};AC.ptr.prototype.notifyWriteError=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];b[0]=this;$r=b[0].socketWriteErrorOnce.Do((function(a,b){return function(){b[0].socketWriteError.Store(a[0]);$close(b[0].chSocketWriteError);};})(a,b));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.notifyWriteError};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.notifyWriteError=function(a){return this.$val.notifyWriteError(a);};AC.ptr.prototype.notifyProtoError=function(a){var a,b,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];b[0]=this;$r=b[0].protoErrorOnce.Do((function(a,b){return function(){b[0].protoError.Store(a[0]);$close(b[0].chProtoError);};})(a,b));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.notifyProtoError};}$f.a=a;$f.b=b;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.notifyProtoError=function(a){return this.$val.notifyProtoError(a);};AC.ptr.prototype.IsClosed=function(){var a,b,$r;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$r=$f.$r;}a=this;b=$select([[a.die],[]]);if(b[0]===0){return true;}else if(b[0]===1){return false;}if($f===undefined){$f={$blk:AC.ptr.prototype.IsClosed};}$f.a=a;$f.b=b;$f.$r=$r;return $f;};AC.prototype.IsClosed=function(){return this.$val.IsClosed();};AC.ptr.prototype.NumStreams=function(){var a,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;if(a.IsClosed()){$s=-1;return 0;}$r=a.streamLock.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(a.streamLock,\"Unlock\"),[]]);$s=-1;return $keys(a.streams).length;}return;}}catch(err){$err=err;$s=-1;return 0;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AC.ptr.prototype.NumStreams};}$f.a=a;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AC.prototype.NumStreams=function(){return this.$val.NumStreams();};AC.ptr.prototype.SetDeadline=function(a){var a,b;b=this;b.deadline.Store(new a.constructor.elem(a));return $ifaceNil;};AC.prototype.SetDeadline=function(a){return this.$val.SetDeadline(a);};AC.ptr.prototype.LocalAddr=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=$assertType(a.conn,AP,true);c=b[0];d=b[1];if(d){$s=1;continue;}$s=2;continue;case 1:e=c.LocalAddr();$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.LocalAddr};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.LocalAddr=function(){return this.$val.LocalAddr();};AC.ptr.prototype.RemoteAddr=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=$assertType(a.conn,AQ,true);c=b[0];d=b[1];if(d){$s=1;continue;}$s=2;continue;case 1:e=c.RemoteAddr();$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.RemoteAddr};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.RemoteAddr=function(){return this.$val.RemoteAddr();};AC.ptr.prototype.streamClosed=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;$r=b.streamLock.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=(c=b.streams[$Uint32.keyFor(a)],c!==undefined?c.v:AO.nil).recycleTokens();$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;if(e>0){if(J.AddInt32((b.$ptr_bucket||(b.$ptr_bucket=new AR(function(){return this.$target.bucket;},function($v){this.$target.bucket=$v;},b))),((e>>0)))>0){b.notifyBucket();}}delete b.streams[$Uint32.keyFor(a)];$r=b.streamLock.Unlock();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.streamClosed};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.streamClosed=function(a){return this.$val.streamClosed(a);};AC.ptr.prototype.returnTokens=function(a){var a,b;b=this;if(J.AddInt32((b.$ptr_bucket||(b.$ptr_bucket=new AR(function(){return this.$target.bucket;},function($v){this.$target.bucket=$v;},b))),((a>>0)))>0){b.notifyBucket();}};AC.prototype.returnTokens=function(a){return this.$val.returnTokens(a);};AC.ptr.prototype.recvLoop=function(){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=AS.zero();c=AS.zero();case 1:case 3:if(!(J.LoadInt32((a.$ptr_bucket||(a.$ptr_bucket=new AR(function(){return this.$target.bucket;},function($v){this.$target.bucket=$v;},a))))<=0&&!a.IsClosed())){$s=4;continue;}e=$select([[a.bucketNotify],[a.die]]);$s=5;case 5:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;if(d[0]===0){}else if(d[0]===1){$s=-1;return;}$s=3;continue;case 4:g=E.ReadFull(a.conn,new AJ(b));$s=6;case 6:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;h=f[1];if($interfaceIsEqual(h,$ifaceNil)){$s=7;continue;}$s=8;continue;case 7:J.StoreInt32((a.$ptr_dataReady||(a.$ptr_dataReady=new AR(function(){return this.$target.dataReady;},function($v){this.$target.dataReady=$v;},a))),1);if(!((new S($clone(b,S)).Version()===((a.config.Version<<24>>>24))))){$s=10;continue;}$s=11;continue;case 10:$r=a.notifyProtoError($pkg.ErrInvalidProtocol);$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 11:i=new S($clone(b,S)).StreamID();j=new S($clone(b,S)).Cmd();if(j===(3)){$s=14;continue;}if(j===(0)){$s=15;continue;}if(j===(1)){$s=16;continue;}if(j===(2)){$s=17;continue;}if(j===(4)){$s=18;continue;}$s=19;continue;case 14:$s=20;continue;case 15:$r=a.streamLock.Lock();$s=21;case 21:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}k=(l=a.streams[$Uint32.keyFor(i)],l!==undefined?[l.v,true]:[AO.nil,false]);m=k[1];if(!m){$s=22;continue;}$s=23;continue;case 22:n=AG(i,a.config.MaxFrameSize,a);o=i;(a.streams||$throwRuntimeError(\"assignment to entry in nil map\"))[$Uint32.keyFor(o)]={k:o,v:n};q=$select([[a.chAccepts,n],[a.die]]);$s=24;case 24:if($c){$c=false;q=q.$blk();}if(q&&q.$blk!==undefined){break s;}p=q;if(p[0]===0){}else if(p[0]===1){}case 23:$r=a.streamLock.Unlock();$s=25;case 25:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=20;continue;case 16:$r=a.streamLock.Lock();$s=26;case 26:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}r=(s=a.streams[$Uint32.keyFor(i)],s!==undefined?[s.v,true]:[AO.nil,false]);t=r[0];u=r[1];if(u){$s=27;continue;}$s=28;continue;case 27:$r=t.fin();$s=29;case 29:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}t.notifyReadEvent();case 28:$r=a.streamLock.Unlock();$s=30;case 30:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=20;continue;case 17:if(new S($clone(b,S)).Length()>0){$s=31;continue;}$s=32;continue;case 31:v=K.Get(((new S($clone(b,S)).Length()>>0)));$s=33;case 33:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}w=v;y=E.ReadFull(a.conn,w);$s=34;case 34:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}x=y;z=x[0];aa=x[1];if($interfaceIsEqual(aa,$ifaceNil)){$s=35;continue;}$s=36;continue;case 35:$r=a.streamLock.Lock();$s=38;case 38:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}ab=(ac=a.streams[$Uint32.keyFor(i)],ac!==undefined?[ac.v,true]:[AO.nil,false]);ad=ab[0];ae=ab[1];if(ae){$s=39;continue;}$s=40;continue;case 39:af=ad.pushBytes(w);$s=41;case 41:if($c){$c=false;af=af.$blk();}if(af&&af.$blk!==undefined){break s;}af;J.AddInt32((a.$ptr_bucket||(a.$ptr_bucket=new AR(function(){return this.$target.bucket;},function($v){this.$target.bucket=$v;},a))),-((z>>0)));ad.notifyReadEvent();case 40:$r=a.streamLock.Unlock();$s=42;case 42:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=37;continue;case 36:$r=a.notifyReadError(aa);$s=43;case 43:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 37:case 32:$s=20;continue;case 18:ah=E.ReadFull(a.conn,new AJ(c));$s=44;case 44:if($c){$c=false;ah=ah.$blk();}if(ah&&ah.$blk!==undefined){break s;}ag=ah;ai=ag[1];if($interfaceIsEqual(ai,$ifaceNil)){$s=45;continue;}$s=46;continue;case 45:$r=a.streamLock.Lock();$s=48;case 48:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}aj=(ak=a.streams[$Uint32.keyFor(i)],ak!==undefined?[ak.v,true]:[AO.nil,false]);al=aj[0];am=aj[1];if(am){al.update(new T($clone(c,T)).Consumed(),new T($clone(c,T)).Window());}$r=a.streamLock.Unlock();$s=49;case 49:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=47;continue;case 46:$r=a.notifyReadError(ai);$s=50;case 50:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 47:$s=20;continue;case 19:$r=a.notifyProtoError($pkg.ErrInvalidProtocol);$s=51;case 51:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 20:case 13:$s=9;continue;case 8:$r=a.notifyReadError(h);$s=52;case 52:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 9:$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.recvLoop};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.recvLoop=function(){return this.$val.recvLoop();};AC.ptr.prototype.keepalive=function(){var a,b,c,d,e,f,g,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;b=G.NewTicker(a.config.KeepAliveInterval);c=G.NewTicker(a.config.KeepAliveTimeout);$deferred.push([$methodVal(b,\"Stop\"),[]]);$deferred.push([$methodVal(c,\"Stop\"),[]]);case 1:e=$select([[b.C],[c.C],[a.die]]);$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;if(d[0]===0){$s=4;continue;}if(d[0]===1){$s=5;continue;}if(d[0]===2){$s=6;continue;}$s=7;continue;case 4:f=a.writeFrameInternal($clone(R(((a.config.Version<<24>>>24)),3,0),Q),b.C,new $Uint64(0,0));$s=8;case 8:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}f;a.notifyBucket();$s=7;continue;case 5:if(!J.CompareAndSwapInt32((a.$ptr_dataReady||(a.$ptr_dataReady=new AR(function(){return this.$target.dataReady;},function($v){this.$target.dataReady=$v;},a))),1,0)){$s=9;continue;}$s=10;continue;case 9:if(J.LoadInt32((a.$ptr_bucket||(a.$ptr_bucket=new AR(function(){return this.$target.bucket;},function($v){this.$target.bucket=$v;},a))))>0){$s=11;continue;}$s=12;continue;case 11:g=a.Close();$s=13;case 13:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}g;$s=-1;return;case 12:case 10:$s=7;continue;case 6:$s=-1;return;case 7:$s=1;continue;case 2:$s=-1;return;}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AC.ptr.prototype.keepalive};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AC.prototype.keepalive=function(){return this.$val.keepalive();};AC.ptr.prototype.shaperLoop=function(){var a,b,c,d,e,f,g,h,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=this;a[0]=AE.nil;c=new Z.ptr(new $Uint64(0,0),new Q.ptr(0,0,0,AJ.nil),$chanNil);d=$chanNil;case 1:if(a[0].$length>0){$s=3;continue;}$s=4;continue;case 3:d=b.writes;e=H.Pop((a.$ptr||(a.$ptr=new AT(function(){return this.$target[0];},function($v){this.$target[0]=$v;},a))));$s=6;case 6:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}Z.copy(c,$assertType(e,Z));$s=5;continue;case 4:d=$chanNil;case 5:g=$select([[b.die],[b.shaper],[d,$clone(c,Z)]]);$s=7;case 7:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;if(f[0]===0){$s=8;continue;}if(f[0]===1){$s=9;continue;}if(f[0]===2){$s=10;continue;}$s=11;continue;case 8:$s=-1;return;case 9:h=$clone(f[1][0],Z);if(!(d===$chanNil)){$s=12;continue;}$s=13;continue;case 12:$r=H.Push((a.$ptr||(a.$ptr=new AT(function(){return this.$target[0];},function($v){this.$target[0]=$v;},a))),new c.constructor.elem(c));$s=14;case 14:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 13:$r=H.Push((a.$ptr||(a.$ptr=new AT(function(){return this.$target[0];},function($v){this.$target[0]=$v;},a))),new h.constructor.elem(h));$s=15;case 15:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=11;continue;case 10:case 11:$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.shaperLoop};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.shaperLoop=function(){return this.$val.shaperLoop();};AC.ptr.prototype.sendLoop=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=AJ.nil;c=0;d=$ifaceNil;e=AU.nil;f=$assertType(a.conn,AB,true);g=f[0];h=f[1];if(h){b=$makeSlice(AJ,8);e=$makeSlice(AU,2);}else{b=$makeSlice(AJ,65544);}case 1:j=$select([[a.die],[a.writes]]);$s=3;case 3:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;if(i[0]===0){$s=4;continue;}if(i[0]===1){$s=5;continue;}$s=6;continue;case 4:$s=-1;return;case 5:k=$clone(i[1][0],Z);(0>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+0]=k.frame.ver);(1>=b.$length?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+1]=k.frame.cmd);$clone(C.LittleEndian,C.littleEndian).PutUint16($subslice(b,2),((k.frame.data.$length<<16>>>16)));$clone(C.LittleEndian,C.littleEndian).PutUint32($subslice(b,4),k.frame.sid);if(e.$length>0){$s=7;continue;}$s=8;continue;case 7:(0>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+0]=$subslice(b,0,8));(1>=e.$length?($throwRuntimeError(\"index out of range\"),undefined):e.$array[e.$offset+1]=k.frame.data);m=g.WriteBuffers(e);$s=10;case 10:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;c=l[0];d=l[1];$s=9;continue;case 8:$copySlice($subslice(b,8),k.frame.data);o=a.conn.Write($subslice(b,0,(8+k.frame.data.$length>>0)));$s=11;case 11:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}n=o;c=n[0];d=n[1];case 9:c=c-(8)>>0;if(c<0){c=0;}p=new AA.ptr(c,d);$r=$send(k.result,$clone($clone(p,AA),AA));$s=12;case 12:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$close(k.result);if(!($interfaceIsEqual(d,$ifaceNil))){$s=13;continue;}$s=14;continue;case 13:$r=a.notifyWriteError(d);$s=15;case 15:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;case 14:case 6:$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.sendLoop};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.sendLoop=function(){return this.$val.sendLoop();};AC.ptr.prototype.writeFrame=function(a){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;f=d.writeFrameInternal($clone(a,Q),$chanNil,new $Uint64(0,0));$s=1;case 1:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;b=e[0];c=e[1];$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.writeFrame};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.writeFrame=function(a){return this.$val.writeFrame(a);};AC.ptr.prototype.writeFrameInternal=function(a,b,c){var a,b,c,d,e,f,g,h,i,j,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=this;e=new Z.ptr(c,$clone(a,Q),new $Chan(AA,1));g=$select([[d.shaper,$clone(e,Z)],[d.die],[d.chSocketWriteError],[b]]);$s=1;case 1:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;if(f[0]===0){$s=2;continue;}if(f[0]===1){$s=3;continue;}if(f[0]===2){$s=4;continue;}if(f[0]===3){$s=5;continue;}$s=6;continue;case 2:$s=6;continue;case 3:$s=-1;return[0,E.ErrClosedPipe];case 4:$s=-1;return[0,$assertType(d.socketWriteError.Load(),$error)];case 5:$s=-1;return[0,$pkg.ErrTimeout];case 6:i=$select([[e.result],[d.die],[d.chSocketWriteError],[b]]);$s=7;case 7:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;if(h[0]===0){j=$clone(h[1][0],AA);$s=-1;return[j.n,j.err];}else if(h[0]===1){$s=-1;return[0,E.ErrClosedPipe];}else if(h[0]===2){$s=-1;return[0,$assertType(d.socketWriteError.Load(),$error)];}else if(h[0]===3){$s=-1;return[0,$pkg.ErrTimeout];}$s=-1;return[0,$ifaceNil];}return;}if($f===undefined){$f={$blk:AC.ptr.prototype.writeFrameInternal};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.$s=$s;$f.$r=$r;return $f;};AC.prototype.writeFrameInternal=function(a,b,c){return this.$val.writeFrameInternal(a,b,c);};AE.prototype.Len=function(){var a;a=this;return a.$length;};$ptrType(AE).prototype.Len=function(){return this.$get().Len();};AE.prototype.Less=function(a,b){var a,b,c,d,e;c=this;return(d=((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]).prio,e=((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]).prio,(d.$high<e.$high||(d.$high===e.$high&&d.$low<e.$low)));};$ptrType(AE).prototype.Less=function(a,b){return this.$get().Less(a,b);};AE.prototype.Swap=function(a,b){var a,b,c,d,e;c=this;d=$clone(((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]),Z);e=$clone(((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]),Z);Z.copy(((a<0||a>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+a]),d);Z.copy(((b<0||b>=c.$length)?($throwRuntimeError(\"index out of range\"),undefined):c.$array[c.$offset+b]),e);};$ptrType(AE).prototype.Swap=function(a,b){return this.$get().Swap(a,b);};$ptrType(AE).prototype.Push=function(a){var a,b;b=this;b.$set($append(b.$get(),$assertType(a,Z)));};$ptrType(AE).prototype.Pop=function(){var a,b,c,d,e;a=this;b=a.$get();c=b.$length;e=$clone((d=c-1>>0,((d<0||d>=b.$length)?($throwRuntimeError(\"index out of range\"),undefined):b.$array[b.$offset+d])),Z);a.$set($subslice(b,0,(c-1>>0)));return new e.constructor.elem(e);};AG=function(a,b,c){var a,b,c,d;d=new AF.ptr(0,AM.nil,AU.nil,AU.nil,new B.Mutex.ptr(0,0),0,$chanNil,$chanNil,new B.Once.ptr(new B.Mutex.ptr(0,0),0),$chanNil,new B.Once.ptr(new B.Mutex.ptr(0,0),0),new J.Value.ptr($ifaceNil),new J.Value.ptr($ifaceNil),0,0,0,0,0,$chanNil);d.id=a;d.chReadEvent=new $Chan(AN,1);d.chUpdate=new $Chan(AN,1);d.frameSize=b;d.sess=c;d.die=new $Chan(AN,0);d.chFinEvent=new $Chan(AN,0);d.peerWindow=262144;return d;};AF.ptr.prototype.ID=function(){var a;a=this;return a.id;};AF.prototype.ID=function(){return this.$val.ID();};AF.ptr.prototype.Read=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;case 1:f=d.tryRead(a);$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;b=e[0];c=e[1];if($interfaceIsEqual(c,$pkg.ErrWouldBlock)){$s=4;continue;}$s=5;continue;case 4:g=d.waitRead();$s=7;case 7:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}h=g;if(!($interfaceIsEqual(h,$ifaceNil))){i=0;j=h;b=i;c=j;$s=-1;return[b,c];}$s=6;continue;case 5:k=b;l=c;b=k;c=l;$s=-1;return[b,c];case 6:$s=1;continue;case 2:$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.Read};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.Read=function(a){return this.$val.Read(a);};AF.ptr.prototype.tryRead=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;if(d.sess.config.Version===2){$s=1;continue;}$s=2;continue;case 1:f=d.tryReadv2(a);$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;b=e[0];c=e[1];$s=-1;return[b,c];case 2:if(a.$length===0){g=0;h=$ifaceNil;b=g;c=h;$s=-1;return[b,c];}$r=d.bufferLock.Lock();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(d.buffers.$length>0){b=$copySlice(a,(i=d.buffers,(0>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+0])));(k=d.buffers,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0]=$subslice((j=d.buffers,(0>=j.$length?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+0])),b)));if((l=d.buffers,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0])).$length===0){(m=d.buffers,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0]=AJ.nil));d.buffers=$subslice(d.buffers,1);K.Put((n=d.heads,(0>=n.$length?($throwRuntimeError(\"index out of range\"),undefined):n.$array[n.$offset+0])));d.heads=$subslice(d.heads,1);}}$r=d.bufferLock.Unlock();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(b>0){d.sess.returnTokens(b);o=b;p=$ifaceNil;b=o;c=p;$s=-1;return[b,c];}q=$select([[d.die],[]]);if(q[0]===0){r=0;s=E.EOF;b=r;c=s;$s=-1;return[b,c];}else if(q[0]===1){t=0;u=$pkg.ErrWouldBlock;b=t;c=u;$s=-1;return[b,c];}$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.tryRead};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.tryRead=function(a){return this.$val.tryRead(a);};AF.ptr.prototype.tryReadv2=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;if(a.$length===0){e=0;f=$ifaceNil;b=e;c=f;$s=-1;return[b,c];}g=0;$r=d.bufferLock.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(d.buffers.$length>0){b=$copySlice(a,(h=d.buffers,(0>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+0])));(j=d.buffers,(0>=j.$length?($throwRuntimeError(\"index out of range\"),undefined):j.$array[j.$offset+0]=$subslice((i=d.buffers,(0>=i.$length?($throwRuntimeError(\"index out of range\"),undefined):i.$array[i.$offset+0])),b)));if((k=d.buffers,(0>=k.$length?($throwRuntimeError(\"index out of range\"),undefined):k.$array[k.$offset+0])).$length===0){(l=d.buffers,(0>=l.$length?($throwRuntimeError(\"index out of range\"),undefined):l.$array[l.$offset+0]=AJ.nil));d.buffers=$subslice(d.buffers,1);K.Put((m=d.heads,(0>=m.$length?($throwRuntimeError(\"index out of range\"),undefined):m.$array[m.$offset+0])));d.heads=$subslice(d.heads,1);}}d.numRead=d.numRead+(((b>>>0)))>>>0;d.incr=d.incr+(((b>>>0)))>>>0;if(d.incr>=(((n=d.sess.config.MaxStreamBuffer/2,(n===n&&n!==1/0&&n!==-1/0)?n>>0:$throwRuntimeError(\"integer divide by zero\"))>>>0))||(d.numRead===((b>>>0)))){g=d.numRead;d.incr=0;}$r=d.bufferLock.Unlock();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(b>0){$s=3;continue;}$s=4;continue;case 3:d.sess.returnTokens(b);if(g>0){$s=5;continue;}$s=6;continue;case 5:o=d.sendWindowUpdate(g);$s=8;case 8:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}p=o;q=b;r=p;b=q;c=r;$s=-1;return[b,c];case 6:s=b;t=$ifaceNil;b=s;c=t;$s=-1;return[b,c];case 7:case 4:u=$select([[d.die],[]]);if(u[0]===0){v=0;w=E.EOF;b=v;c=w;$s=-1;return[b,c];}else if(u[0]===1){x=0;y=$pkg.ErrWouldBlock;b=x;c=y;$s=-1;return[b,c];}$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.tryReadv2};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.tryReadv2=function(a){return this.$val.tryReadv2(a);};AF.ptr.prototype.WriteTo=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=new $Int64(0,0);c=$ifaceNil;d=this;if(d.sess.config.Version===2){$s=1;continue;}$s=2;continue;case 1:f=d.writeTov2(a);$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;b=e[0];c=e[1];$s=-1;return[b,c];case 2:case 4:g=AJ.nil;$r=d.bufferLock.Lock();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(d.buffers.$length>0){g=(h=d.buffers,(0>=h.$length?($throwRuntimeError(\"index out of range\"),undefined):h.$array[h.$offset+0]));d.buffers=$subslice(d.buffers,1);d.heads=$subslice(d.heads,1);}$r=d.bufferLock.Unlock();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(!(g===AJ.nil)){$s=8;continue;}$s=9;continue;case 8:j=a.Write(g);$s=11;case 11:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;k=i[0];l=i[1];d.sess.returnTokens(g.$length);K.Put(g);if(k>0){b=(m=(new $Int64(0,k)),new $Int64(b.$high+m.$high,b.$low+m.$low));}if(!($interfaceIsEqual(l,$ifaceNil))){n=b;o=l;b=n;c=o;$s=-1;return[b,c];}$s=10;continue;case 9:p=d.waitRead();$s=12;case 12:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p;if(!($interfaceIsEqual(q,$ifaceNil))){r=b;s=q;b=r;c=s;$s=-1;return[b,c];}case 10:$s=4;continue;case 5:$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.WriteTo};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.WriteTo=function(a){return this.$val.WriteTo(a);};AF.ptr.prototype.writeTov2=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=new $Int64(0,0);c=$ifaceNil;d=this;case 1:e=0;f=AJ.nil;$r=d.bufferLock.Lock();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(d.buffers.$length>0){f=(g=d.buffers,(0>=g.$length?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+0]));d.buffers=$subslice(d.buffers,1);d.heads=$subslice(d.heads,1);}d.numRead=d.numRead+(((f.$length>>>0)))>>>0;d.incr=d.incr+(((f.$length>>>0)))>>>0;if(d.incr>=(((h=d.sess.config.MaxStreamBuffer/2,(h===h&&h!==1/0&&h!==-1/0)?h>>0:$throwRuntimeError(\"integer divide by zero\"))>>>0))||(d.numRead===((f.$length>>>0)))){e=d.numRead;d.incr=0;}$r=d.bufferLock.Unlock();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(!(f===AJ.nil)){$s=5;continue;}$s=6;continue;case 5:j=a.Write(f);$s=8;case 8:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;k=i[0];l=i[1];d.sess.returnTokens(f.$length);K.Put(f);if(k>0){b=(m=(new $Int64(0,k)),new $Int64(b.$high+m.$high,b.$low+m.$low));}if(!($interfaceIsEqual(l,$ifaceNil))){n=b;o=l;b=n;c=o;$s=-1;return[b,c];}if(e>0){$s=9;continue;}$s=10;continue;case 9:p=d.sendWindowUpdate(e);$s=11;case 11:if($c){$c=false;p=p.$blk();}if(p&&p.$blk!==undefined){break s;}q=p;if(!($interfaceIsEqual(q,$ifaceNil))){r=b;s=q;b=r;c=s;$s=-1;return[b,c];}case 10:$s=7;continue;case 6:t=d.waitRead();$s=12;case 12:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}u=t;if(!($interfaceIsEqual(u,$ifaceNil))){v=b;w=u;b=v;c=w;$s=-1;return[b,c];}case 7:$s=1;continue;case 2:$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.writeTov2};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.writeTov2=function(a){return this.$val.writeTov2(a);};AF.ptr.prototype.sendWindowUpdate=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=this;c=AV.nil;d=$chanNil;e=$assertType(b.readDeadline.Load(),G.Time,true);f=$clone(e[0],G.Time);g=e[1];if(g&&!$clone(f,G.Time).IsZero()){c=G.NewTimer(G.Until($clone(f,G.Time)));$deferred.push([$methodVal(c,\"Stop\"),[]]);d=c.C;}h=$clone(R(((b.sess.config.Version<<24>>>24)),4,b.id),Q);i=AS.zero();$clone(C.LittleEndian,C.littleEndian).PutUint32(new AJ(i),a);$clone(C.LittleEndian,C.littleEndian).PutUint32($subslice(new AJ(i),4),((b.sess.config.MaxStreamBuffer>>>0)));h.data=new AJ(i);k=b.sess.writeFrameInternal($clone(h,Q),d,new $Uint64(0,0));$s=1;case 1:if($c){$c=false;k=k.$blk();}if(k&&k.$blk!==undefined){break s;}j=k;l=j[1];$s=-1;return l;}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AF.ptr.prototype.sendWindowUpdate};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AF.prototype.sendWindowUpdate=function(a){return this.$val.sendWindowUpdate(a);};AF.ptr.prototype.waitRead=function(){var a,b,c,d,e,f,g,h,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;b=AV.nil;c=$chanNil;d=$assertType(a.readDeadline.Load(),G.Time,true);e=$clone(d[0],G.Time);f=d[1];if(f&&!$clone(e,G.Time).IsZero()){b=G.NewTimer(G.Until($clone(e,G.Time)));$deferred.push([$methodVal(b,\"Stop\"),[]]);c=b.C;}h=$select([[a.chReadEvent],[a.chFinEvent],[a.sess.chSocketReadError],[a.sess.chProtoError],[c],[a.die]]);$s=1;case 1:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}g=h;if(g[0]===0){$s=2;continue;}if(g[0]===1){$s=3;continue;}if(g[0]===2){$s=4;continue;}if(g[0]===3){$s=5;continue;}if(g[0]===4){$s=6;continue;}if(g[0]===5){$s=7;continue;}$s=8;continue;case 2:$s=-1;return $ifaceNil;case 3:$r=a.bufferLock.Lock();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$deferred.push([$methodVal(a.bufferLock,\"Unlock\"),[]]);if(a.buffers.$length>0){$s=-1;return $ifaceNil;}$s=-1;return E.EOF;case 4:$s=-1;return $assertType(a.sess.socketReadError.Load(),$error);case 5:$s=-1;return $assertType(a.sess.protoError.Load(),$error);case 6:$s=-1;return $pkg.ErrTimeout;case 7:$s=-1;return E.ErrClosedPipe;case 8:$s=-1;return $ifaceNil;}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:AF.ptr.prototype.waitRead};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AF.prototype.waitRead=function(){return this.$val.waitRead();};AF.ptr.prototype.Write=function(a){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=0;c=$ifaceNil;d=this;if(d.sess.config.Version===2){$s=1;continue;}$s=2;continue;case 1:f=d.writeV2(a);$s=3;case 3:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}e=f;b=e[0];c=e[1];$s=-1;return[b,c];case 2:g=$chanNil;h=$assertType(d.writeDeadline.Load(),G.Time,true);i=$clone(h[0],G.Time);j=h[1];if(j&&!$clone(i,G.Time).IsZero()){k=G.NewTimer(G.Until($clone(i,G.Time)));$deferred.push([$methodVal(k,\"Stop\"),[]]);g=k.C;}l=$select([[d.die],[]]);if(l[0]===0){m=0;n=E.ErrClosedPipe;b=m;c=n;$s=-1;return[b,c];}else if(l[0]===1){}o=0;p=$clone(R(((d.sess.config.Version<<24>>>24)),2,d.id),Q);q=a;case 4:if(!(q.$length>0)){$s=5;continue;}r=q.$length;if(r>d.frameSize){r=d.frameSize;}p.data=$subslice(q,0,r);q=$subslice(q,r);t=d.sess.writeFrameInternal($clone(p,Q),g,(new $Uint64(0,d.numWritten)));$s=6;case 6:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}s=t;u=s[0];v=s[1];d.numWritten=d.numWritten+(1)>>>0;o=o+(u)>>0;if(!($interfaceIsEqual(v,$ifaceNil))){w=o;x=v;b=w;c=x;$s=-1;return[b,c];}$s=4;continue;case 5:y=o;z=$ifaceNil;b=y;c=z;$s=-1;return[b,c];}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return[b,c];}if($curGoroutine.asleep){if($f===undefined){$f={$blk:AF.ptr.prototype.Write};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AF.prototype.Write=function(a){return this.$val.Write(a);};AF.ptr.prototype.writeV2=function(a){var a,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;aa=$f.aa;ab=$f.ab;ac=$f.ac;ad=$f.ad;ae=$f.ae;af=$f.af;ag=$f.ag;ah=$f.ah;ai=$f.ai;aj=$f.aj;ak=$f.ak;al=$f.al;am=$f.am;an=$f.an;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=0;c=$ifaceNil;d=this;if(a.$length===0){e=0;f=$ifaceNil;b=e;c=f;$s=-1;return[b,c];}g=$select([[d.die],[]]);if(g[0]===0){h=0;i=E.ErrClosedPipe;b=h;c=i;$s=-1;return[b,c];}else if(g[0]===1){}j=$chanNil;k=$assertType(d.writeDeadline.Load(),G.Time,true);l=$clone(k[0],G.Time);m=k[1];if(m&&!$clone(l,G.Time).IsZero()){n=G.NewTimer(G.Until($clone(l,G.Time)));$deferred.push([$methodVal(n,\"Stop\"),[]]);j=n.C;}o=0;p=$clone(R(((d.sess.config.Version<<24>>>24)),2,d.id),Q);case 1:q=AJ.nil;r=(((J.LoadUint32((d.$ptr_numWritten||(d.$ptr_numWritten=new AW(function(){return this.$target.numWritten;},function($v){this.$target.numWritten=$v;},d))))-J.LoadUint32((d.$ptr_peerConsumed||(d.$ptr_peerConsumed=new AW(function(){return this.$target.peerConsumed;},function($v){this.$target.peerConsumed=$v;},d))))>>>0)>>0));if(r<0){s=0;t=$pkg.ErrConsumed;b=s;c=t;$s=-1;return[b,c];}u=((J.LoadUint32((d.$ptr_peerWindow||(d.$ptr_peerWindow=new AW(function(){return this.$target.peerWindow;},function($v){this.$target.peerWindow=$v;},d))))>>0))-r>>0;if(u>0){$s=3;continue;}$s=4;continue;case 3:if(u>((a.$length>>0))){q=a;a=AJ.nil;}else{q=$subslice(a,0,u);a=$subslice(a,u);}case 5:if(!(q.$length>0)){$s=6;continue;}v=q.$length;if(v>d.frameSize){v=d.frameSize;}p.data=$subslice(q,0,v);q=$subslice(q,v);x=d.sess.writeFrameInternal($clone(p,Q),j,(new $Uint64(0,J.LoadUint32((d.$ptr_numWritten||(d.$ptr_numWritten=new AW(function(){return this.$target.numWritten;},function($v){this.$target.numWritten=$v;},d)))))));$s=7;case 7:if($c){$c=false;x=x.$blk();}if(x&&x.$blk!==undefined){break s;}w=x;y=w[0];z=w[1];J.AddUint32((d.$ptr_numWritten||(d.$ptr_numWritten=new AW(function(){return this.$target.numWritten;},function($v){this.$target.numWritten=$v;},d))),((v>>>0)));o=o+(y)>>0;if(!($interfaceIsEqual(z,$ifaceNil))){aa=o;ab=z;b=aa;c=ab;$s=-1;return[b,c];}$s=5;continue;case 6:case 4:if(a.$length>0){$s=8;continue;}$s=9;continue;case 8:ad=$select([[d.chFinEvent],[d.die],[j],[d.sess.chSocketWriteError],[d.chUpdate]]);$s=11;case 11:if($c){$c=false;ad=ad.$blk();}if(ad&&ad.$blk!==undefined){break s;}ac=ad;if(ac[0]===0){ae=0;af=E.EOF;b=ae;c=af;$s=-1;return[b,c];}else if(ac[0]===1){ag=o;ah=E.ErrClosedPipe;b=ag;c=ah;$s=-1;return[b,c];}else if(ac[0]===2){ai=o;aj=$pkg.ErrTimeout;b=ai;c=aj;$s=-1;return[b,c];}else if(ac[0]===3){ak=o;al=$assertType(d.sess.socketWriteError.Load(),$error);b=ak;c=al;$s=-1;return[b,c];}else if(ac[0]===4){$s=1;continue;}$s=10;continue;case 9:am=o;an=$ifaceNil;b=am;c=an;$s=-1;return[b,c];case 10:$s=1;continue;case 2:$s=-1;return[b,c];}return;}}catch(err){$err=err;$s=-1;}finally{$callDeferred($deferred,$err);if(!$curGoroutine.asleep){return[b,c];}if($curGoroutine.asleep){if($f===undefined){$f={$blk:AF.ptr.prototype.writeV2};}$f.a=a;$f.aa=aa;$f.ab=ab;$f.ac=ac;$f.ad=ad;$f.ae=ae;$f.af=af;$f.ag=ag;$f.ah=ah;$f.ai=ai;$f.aj=aj;$f.ak=ak;$f.al=al;$f.am=am;$f.an=an;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};AF.prototype.writeV2=function(a){return this.$val.writeV2(a);};AF.ptr.prototype.Close=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];b=[b];b[0]=this;a[0]=false;c=$ifaceNil;$r=b[0].dieOnce.Do((function(a,b){return function(){$close(b[0].die);a[0]=true;};})(a,b));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if(a[0]){$s=2;continue;}$s=3;continue;case 2:e=b[0].sess.writeFrame($clone(R(((b[0].sess.config.Version<<24>>>24)),1,b[0].id),Q));$s=5;case 5:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}d=e;c=d[1];$r=b[0].sess.streamClosed(b[0].id);$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return c;case 3:$s=-1;return E.ErrClosedPipe;case 4:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.Close};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.Close=function(){return this.$val.Close();};AF.ptr.prototype.GetDieCh=function(){var a;a=this;return a.die;};AF.prototype.GetDieCh=function(){return this.$val.GetDieCh();};AF.ptr.prototype.SetReadDeadline=function(a){var a,b;b=this;b.readDeadline.Store(new a.constructor.elem(a));b.notifyReadEvent();return $ifaceNil;};AF.prototype.SetReadDeadline=function(a){return this.$val.SetReadDeadline(a);};AF.ptr.prototype.SetWriteDeadline=function(a){var a,b;b=this;b.writeDeadline.Store(new a.constructor.elem(a));return $ifaceNil;};AF.prototype.SetWriteDeadline=function(a){return this.$val.SetWriteDeadline(a);};AF.ptr.prototype.SetDeadline=function(a){var a,b,c,d;b=this;c=b.SetReadDeadline($clone(a,G.Time));if(!($interfaceIsEqual(c,$ifaceNil))){return c;}d=b.SetWriteDeadline($clone(a,G.Time));if(!($interfaceIsEqual(d,$ifaceNil))){return d;}return $ifaceNil;};AF.prototype.SetDeadline=function(a){return this.$val.SetDeadline(a);};AF.ptr.prototype.sessionClose=function(){var a,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];a[0]=this;$r=a[0].dieOnce.Do((function(a){return function(){$close(a[0].die);};})(a));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.sessionClose};}$f.a=a;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.sessionClose=function(){return this.$val.sessionClose();};AF.ptr.prototype.LocalAddr=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=$assertType(a.sess.conn,AP,true);c=b[0];d=b[1];if(d){$s=1;continue;}$s=2;continue;case 1:e=c.LocalAddr();$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.LocalAddr};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.LocalAddr=function(){return this.$val.LocalAddr();};AF.ptr.prototype.RemoteAddr=function(){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=this;b=$assertType(a.sess.conn,AQ,true);c=b[0];d=b[1];if(d){$s=1;continue;}$s=2;continue;case 1:e=c.RemoteAddr();$s=3;case 3:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}$s=-1;return e;case 2:$s=-1;return $ifaceNil;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.RemoteAddr};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.RemoteAddr=function(){return this.$val.RemoteAddr();};AF.ptr.prototype.pushBytes=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=0;c=$ifaceNil;d=this;$r=d.bufferLock.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d.buffers=$append(d.buffers,a);d.heads=$append(d.heads,a);$r=d.bufferLock.Unlock();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return[b,c];}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.pushBytes};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.pushBytes=function(a){return this.$val.pushBytes(a);};AF.ptr.prototype.recycleTokens=function(){var a,b,c,d,e,f,g,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=0;b=this;$r=b.bufferLock.Lock();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c=b.buffers;d=0;while(true){if(!(d<c.$length)){break;}e=d;a=a+((f=b.buffers,((e<0||e>=f.$length)?($throwRuntimeError(\"index out of range\"),undefined):f.$array[f.$offset+e])).$length)>>0;K.Put((g=b.heads,((e<0||e>=g.$length)?($throwRuntimeError(\"index out of range\"),undefined):g.$array[g.$offset+e])));d++;}b.buffers=AU.nil;b.heads=AU.nil;$r=b.bufferLock.Unlock();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return a;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.recycleTokens};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.recycleTokens=function(){return this.$val.recycleTokens();};AF.ptr.prototype.notifyReadEvent=function(){var a,b,$r;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;$r=$f.$r;}a=this;b=$select([[a.chReadEvent,new AN.ptr()],[]]);if(b[0]===0){}else if(b[0]===1){}if($f===undefined){$f={$blk:AF.ptr.prototype.notifyReadEvent};}$f.a=a;$f.b=b;$f.$r=$r;return $f;};AF.prototype.notifyReadEvent=function(){return this.$val.notifyReadEvent();};AF.ptr.prototype.update=function(a,b){var a,b,c,d,$r;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$r=$f.$r;}c=this;J.StoreUint32((c.$ptr_peerConsumed||(c.$ptr_peerConsumed=new AW(function(){return this.$target.peerConsumed;},function($v){this.$target.peerConsumed=$v;},c))),a);J.StoreUint32((c.$ptr_peerWindow||(c.$ptr_peerWindow=new AW(function(){return this.$target.peerWindow;},function($v){this.$target.peerWindow=$v;},c))),b);d=$select([[c.chUpdate,new AN.ptr()],[]]);if(d[0]===0){}else if(d[0]===1){}if($f===undefined){$f={$blk:AF.ptr.prototype.update};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$r=$r;return $f;};AF.prototype.update=function(a,b){return this.$val.update(a,b);};AF.ptr.prototype.fin=function(){var a,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];a[0]=this;$r=a[0].finEventOnce.Do((function(a){return function(){$close(a[0].chFinEvent);};})(a));$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$s=-1;return;}return;}if($f===undefined){$f={$blk:AF.ptr.prototype.fin};}$f.a=a;$f.$s=$s;$f.$r=$r;return $f;};AF.prototype.fin=function(){return this.$val.fin();};AH.methods=[{prop:\"Get\",name:\"Get\",pkg:\"\",typ:$funcType([$Int],[AJ],false)},{prop:\"Put\",name:\"Put\",pkg:\"\",typ:$funcType([AJ],[$error],false)}];S.methods=[{prop:\"Version\",name:\"Version\",pkg:\"\",typ:$funcType([],[$Uint8],false)},{prop:\"Cmd\",name:\"Cmd\",pkg:\"\",typ:$funcType([],[$Uint8],false)},{prop:\"Length\",name:\"Length\",pkg:\"\",typ:$funcType([],[$Uint16],false)},{prop:\"StreamID\",name:\"StreamID\",pkg:\"\",typ:$funcType([],[$Uint32],false)},{prop:\"String\",name:\"String\",pkg:\"\",typ:$funcType([],[$String],false)}];T.methods=[{prop:\"Consumed\",name:\"Consumed\",pkg:\"\",typ:$funcType([],[$Uint32],false)},{prop:\"Window\",name:\"Window\",pkg:\"\",typ:$funcType([],[$Uint32],false)}];AM.methods=[{prop:\"OpenStream\",name:\"OpenStream\",pkg:\"\",typ:$funcType([],[AO,$error],false)},{prop:\"Open\",name:\"Open\",pkg:\"\",typ:$funcType([],[E.ReadWriteCloser,$error],false)},{prop:\"AcceptStream\",name:\"AcceptStream\",pkg:\"\",typ:$funcType([],[AO,$error],false)},{prop:\"Accept\",name:\"Accept\",pkg:\"\",typ:$funcType([],[E.ReadWriteCloser,$error],false)},{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"notifyBucket\",name:\"notifyBucket\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"notifyReadError\",name:\"notifyReadError\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$error],[],false)},{prop:\"notifyWriteError\",name:\"notifyWriteError\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$error],[],false)},{prop:\"notifyProtoError\",name:\"notifyProtoError\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$error],[],false)},{prop:\"IsClosed\",name:\"IsClosed\",pkg:\"\",typ:$funcType([],[$Bool],false)},{prop:\"NumStreams\",name:\"NumStreams\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"SetDeadline\",name:\"SetDeadline\",pkg:\"\",typ:$funcType([G.Time],[$error],false)},{prop:\"LocalAddr\",name:\"LocalAddr\",pkg:\"\",typ:$funcType([],[I.Addr],false)},{prop:\"RemoteAddr\",name:\"RemoteAddr\",pkg:\"\",typ:$funcType([],[I.Addr],false)},{prop:\"streamClosed\",name:\"streamClosed\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$Uint32],[],false)},{prop:\"returnTokens\",name:\"returnTokens\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$Int],[],false)},{prop:\"recvLoop\",name:\"recvLoop\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"keepalive\",name:\"keepalive\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"shaperLoop\",name:\"shaperLoop\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"sendLoop\",name:\"sendLoop\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"writeFrame\",name:\"writeFrame\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([Q],[$Int,$error],false)},{prop:\"writeFrameInternal\",name:\"writeFrameInternal\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([Q,AY,$Uint64],[$Int,$error],false)}];AE.methods=[{prop:\"Len\",name:\"Len\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"Less\",name:\"Less\",pkg:\"\",typ:$funcType([$Int,$Int],[$Bool],false)},{prop:\"Swap\",name:\"Swap\",pkg:\"\",typ:$funcType([$Int,$Int],[],false)}];AT.methods=[{prop:\"Push\",name:\"Push\",pkg:\"\",typ:$funcType([$emptyInterface],[],false)},{prop:\"Pop\",name:\"Pop\",pkg:\"\",typ:$funcType([],[$emptyInterface],false)}];AO.methods=[{prop:\"ID\",name:\"ID\",pkg:\"\",typ:$funcType([],[$Uint32],false)},{prop:\"Read\",name:\"Read\",pkg:\"\",typ:$funcType([AJ],[$Int,$error],false)},{prop:\"tryRead\",name:\"tryRead\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([AJ],[$Int,$error],false)},{prop:\"tryReadv2\",name:\"tryReadv2\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([AJ],[$Int,$error],false)},{prop:\"WriteTo\",name:\"WriteTo\",pkg:\"\",typ:$funcType([E.Writer],[$Int64,$error],false)},{prop:\"writeTov2\",name:\"writeTov2\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([E.Writer],[$Int64,$error],false)},{prop:\"sendWindowUpdate\",name:\"sendWindowUpdate\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$Uint32],[$error],false)},{prop:\"waitRead\",name:\"waitRead\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[$error],false)},{prop:\"Write\",name:\"Write\",pkg:\"\",typ:$funcType([AJ],[$Int,$error],false)},{prop:\"writeV2\",name:\"writeV2\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([AJ],[$Int,$error],false)},{prop:\"Close\",name:\"Close\",pkg:\"\",typ:$funcType([],[$error],false)},{prop:\"GetDieCh\",name:\"GetDieCh\",pkg:\"\",typ:$funcType([],[BD],false)},{prop:\"SetReadDeadline\",name:\"SetReadDeadline\",pkg:\"\",typ:$funcType([G.Time],[$error],false)},{prop:\"SetWriteDeadline\",name:\"SetWriteDeadline\",pkg:\"\",typ:$funcType([G.Time],[$error],false)},{prop:\"SetDeadline\",name:\"SetDeadline\",pkg:\"\",typ:$funcType([G.Time],[$error],false)},{prop:\"sessionClose\",name:\"sessionClose\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"LocalAddr\",name:\"LocalAddr\",pkg:\"\",typ:$funcType([],[I.Addr],false)},{prop:\"RemoteAddr\",name:\"RemoteAddr\",pkg:\"\",typ:$funcType([],[I.Addr],false)},{prop:\"pushBytes\",name:\"pushBytes\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([AJ],[$Int,$error],false)},{prop:\"recycleTokens\",name:\"recycleTokens\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[$Int],false)},{prop:\"notifyReadEvent\",name:\"notifyReadEvent\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)},{prop:\"update\",name:\"update\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([$Uint32,$Uint32],[],false)},{prop:\"fin\",name:\"fin\",pkg:\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",typ:$funcType([],[],false)}];N.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",[{prop:\"buffers\",name:\"buffers\",embedded:false,exported:false,typ:AI,tag:\"\"}]);Q.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",[{prop:\"ver\",name:\"ver\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"cmd\",name:\"cmd\",embedded:false,exported:false,typ:$Uint8,tag:\"\"},{prop:\"sid\",name:\"sid\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"data\",name:\"data\",embedded:false,exported:false,typ:AJ,tag:\"\"}]);S.init($Uint8,8);T.init($Uint8,8);U.init(\"\",[{prop:\"Version\",name:\"Version\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"KeepAliveDisabled\",name:\"KeepAliveDisabled\",embedded:false,exported:true,typ:$Bool,tag:\"\"},{prop:\"KeepAliveInterval\",name:\"KeepAliveInterval\",embedded:false,exported:true,typ:G.Duration,tag:\"\"},{prop:\"KeepAliveTimeout\",name:\"KeepAliveTimeout\",embedded:false,exported:true,typ:G.Duration,tag:\"\"},{prop:\"MaxFrameSize\",name:\"MaxFrameSize\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"MaxReceiveBuffer\",name:\"MaxReceiveBuffer\",embedded:false,exported:true,typ:$Int,tag:\"\"},{prop:\"MaxStreamBuffer\",name:\"MaxStreamBuffer\",embedded:false,exported:true,typ:$Int,tag:\"\"}]);Z.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",[{prop:\"prio\",name:\"prio\",embedded:false,exported:false,typ:$Uint64,tag:\"\"},{prop:\"frame\",name:\"frame\",embedded:false,exported:false,typ:Q,tag:\"\"},{prop:\"result\",name:\"result\",embedded:false,exported:false,typ:AX,tag:\"\"}]);AA.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",[{prop:\"n\",name:\"n\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"err\",name:\"err\",embedded:false,exported:false,typ:$error,tag:\"\"}]);AB.init([{prop:\"WriteBuffers\",name:\"WriteBuffers\",pkg:\"\",typ:$funcType([AU],[$Int,$error],false)}]);AC.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",[{prop:\"conn\",name:\"conn\",embedded:false,exported:false,typ:E.ReadWriteCloser,tag:\"\"},{prop:\"config\",name:\"config\",embedded:false,exported:false,typ:AL,tag:\"\"},{prop:\"nextStreamID\",name:\"nextStreamID\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"nextStreamIDLock\",name:\"nextStreamIDLock\",embedded:false,exported:false,typ:B.Mutex,tag:\"\"},{prop:\"bucket\",name:\"bucket\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"bucketNotify\",name:\"bucketNotify\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"streams\",name:\"streams\",embedded:false,exported:false,typ:BA,tag:\"\"},{prop:\"streamLock\",name:\"streamLock\",embedded:false,exported:false,typ:B.Mutex,tag:\"\"},{prop:\"die\",name:\"die\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"dieOnce\",name:\"dieOnce\",embedded:false,exported:false,typ:B.Once,tag:\"\"},{prop:\"socketReadError\",name:\"socketReadError\",embedded:false,exported:false,typ:J.Value,tag:\"\"},{prop:\"socketWriteError\",name:\"socketWriteError\",embedded:false,exported:false,typ:J.Value,tag:\"\"},{prop:\"chSocketReadError\",name:\"chSocketReadError\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"chSocketWriteError\",name:\"chSocketWriteError\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"socketReadErrorOnce\",name:\"socketReadErrorOnce\",embedded:false,exported:false,typ:B.Once,tag:\"\"},{prop:\"socketWriteErrorOnce\",name:\"socketWriteErrorOnce\",embedded:false,exported:false,typ:B.Once,tag:\"\"},{prop:\"protoError\",name:\"protoError\",embedded:false,exported:false,typ:J.Value,tag:\"\"},{prop:\"chProtoError\",name:\"chProtoError\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"protoErrorOnce\",name:\"protoErrorOnce\",embedded:false,exported:false,typ:B.Once,tag:\"\"},{prop:\"chAccepts\",name:\"chAccepts\",embedded:false,exported:false,typ:BB,tag:\"\"},{prop:\"dataReady\",name:\"dataReady\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"goAway\",name:\"goAway\",embedded:false,exported:false,typ:$Int32,tag:\"\"},{prop:\"deadline\",name:\"deadline\",embedded:false,exported:false,typ:J.Value,tag:\"\"},{prop:\"shaper\",name:\"shaper\",embedded:false,exported:false,typ:BC,tag:\"\"},{prop:\"writes\",name:\"writes\",embedded:false,exported:false,typ:BC,tag:\"\"}]);AE.init(Z);AF.init(\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\",[{prop:\"id\",name:\"id\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"sess\",name:\"sess\",embedded:false,exported:false,typ:AM,tag:\"\"},{prop:\"buffers\",name:\"buffers\",embedded:false,exported:false,typ:AU,tag:\"\"},{prop:\"heads\",name:\"heads\",embedded:false,exported:false,typ:AU,tag:\"\"},{prop:\"bufferLock\",name:\"bufferLock\",embedded:false,exported:false,typ:B.Mutex,tag:\"\"},{prop:\"frameSize\",name:\"frameSize\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"chReadEvent\",name:\"chReadEvent\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"die\",name:\"die\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"dieOnce\",name:\"dieOnce\",embedded:false,exported:false,typ:B.Once,tag:\"\"},{prop:\"chFinEvent\",name:\"chFinEvent\",embedded:false,exported:false,typ:AZ,tag:\"\"},{prop:\"finEventOnce\",name:\"finEventOnce\",embedded:false,exported:false,typ:B.Once,tag:\"\"},{prop:\"readDeadline\",name:\"readDeadline\",embedded:false,exported:false,typ:J.Value,tag:\"\"},{prop:\"writeDeadline\",name:\"writeDeadline\",embedded:false,exported:false,typ:J.Value,tag:\"\"},{prop:\"numRead\",name:\"numRead\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"numWritten\",name:\"numWritten\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"incr\",name:\"incr\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"peerConsumed\",name:\"peerConsumed\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"peerWindow\",name:\"peerWindow\",embedded:false,exported:false,typ:$Uint32,tag:\"\"},{prop:\"chUpdate\",name:\"chUpdate\",embedded:false,exported:false,typ:AZ,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=H.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=A.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=I.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=J.$init();$s=9;case 9:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=10;case 10:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}K=AH.nil;L=$toNativeArray($kindUint8,[0,9,1,10,13,21,2,29,11,14,16,18,22,25,3,30,8,12,20,28,15,17,24,7,19,27,23,6,26,5,4,31]);$pkg.ErrInvalidProtocol=A.New(\"invalid protocol\");$pkg.ErrConsumed=A.New(\"peer consumed more than sent\");$pkg.ErrGoAway=A.New(\"stream id overflows, should start a new connection\");$pkg.ErrTimeout=A.New(\"timeout\");$pkg.ErrWouldBlock=A.New(\"operation would block on IO\");M();}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/bridge\"]=(function(){var $pkg={},$init,A,C,B,D,E,F,G,H,J,K,I;A=$packages[\"fmt\"];C=$packages[\"github.com/v2fly/BrowserBridge/proto\"];B=$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/gopherjs/websocket\"];D=$packages[\"github.com/v2fly/BrowserBridge/vendor/github.com/xtaci/smux\"];E=$packages[\"io\"];F=$packages[\"net\"];G=$packages[\"time\"];H=$pkg.Settings=$newType(0,$kindStruct,\"bridge.Settings\",true,\"github.com/v2fly/BrowserBridge/bridge\",true,function(DialAddr_){this.$val=this;if(arguments.length===0){this.DialAddr=\"\";return;}this.DialAddr=DialAddr_;});J=$sliceType($emptyInterface);K=$ptrType(D.Config);I=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=[a];case 1:b=G.NewTimer(new G.Duration(0,1000000000));c=(function(a){return function $b(){var c,d,e,f,g,h,i,j,k,l,m,n,o,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:d=B.Dial(a[0].DialAddr);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}c=d;e=c[0];f=c[1];if(!($interfaceIsEqual(f,$ifaceNil))){$s=2;continue;}$s=3;continue;case 2:g=A.Println(new J([f,new $String(a[0].DialAddr)]));$s=4;case 4:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}g;$s=-1;return;case 3:i=D.Client(e,K.nil);$s=5;case 5:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}h=i;j=h[0];f=h[1];if(!($interfaceIsEqual(f,$ifaceNil))){$s=-1;return;}case 6:k=[k];m=j.Accept();$s=8;case 8:if($c){$c=false;m=m.$blk();}if(m&&m.$blk!==undefined){break s;}l=m;k[0]=l[0];n=l[1];if(!($interfaceIsEqual(n,$ifaceNil))){$s=9;continue;}$s=10;continue;case 9:o=A.Println(new J([n]));$s=11;case 11:if($c){$c=false;o=o.$blk();}if(o&&o.$blk!==undefined){break s;}o;$s=-1;return;case 10:$go((function(a,k){return function $b(){var aa,ab,p,q,r,s,t,u,v,w,x,y,z,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;aa=$f.aa;ab=$f.ab;p=$f.p;q=$f.q;r=$f.r;s=$f.s;t=$f.t;u=$f.u;v=$f.v;w=$f.w;x=$f.x;y=$f.y;z=$f.z;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:p=[p];r=C.ReadRequest(k[0]);$s=1;case 1:if($c){$c=false;r=r.$blk();}if(r&&r.$blk!==undefined){break s;}q=r;s=q[0];p[0]=q[1];if(!($interfaceIsEqual(s,$ifaceNil))){$s=2;continue;}$s=3;continue;case 2:t=A.Println(new J([s]));$s=4;case 4:if($c){$c=false;t=t.$blk();}if(t&&t.$blk!==undefined){break s;}t;$s=-1;return;case 3:u=(function(a,k,p){return function $b(){var u,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;u=$f.u;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:u=B.Dial(p[0].Destination);$s=1;case 1:if($c){$c=false;u=u.$blk();}if(u&&u.$blk!==undefined){break s;}$s=-1;return u;}return;}if($f===undefined){$f={$blk:$b};}$f.u=u;$f.$s=$s;$f.$r=$r;return $f;};})(a,k,p);if(!((p[0].ProtocolStringSize===0))){$s=5;continue;}$s=6;continue;case 5:u=(function(a,k,p){return function $b(){var v,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;v=$f.v;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:v=B.Dial2(p[0].Destination,p[0].ProtocolString);$s=1;case 1:if($c){$c=false;v=v.$blk();}if(v&&v.$blk!==undefined){break s;}$s=-1;return v;}return;}if($f===undefined){$f={$blk:$b};}$f.v=v;$f.$s=$s;$f.$r=$r;return $f;};})(a,k,p);case 6:w=u();$s=7;case 7:if($c){$c=false;w=w.$blk();}if(w&&w.$blk!==undefined){break s;}v=w;x=v[0];s=v[1];if(!($interfaceIsEqual(s,$ifaceNil))){$s=8;continue;}$s=9;continue;case 8:y=A.Println(new J([s]));$s=10;case 10:if($c){$c=false;y=y.$blk();}if(y&&y.$blk!==undefined){break s;}y;z=k[0].Close();$s=11;case 11:if($c){$c=false;z=z.$blk();}if(z&&z.$blk!==undefined){break s;}z;$s=-1;return;case 9:$go(E.Copy,[k[0],x]);aa=E.Copy(x,k[0]);$s=12;case 12:if($c){$c=false;aa=aa.$blk();}if(aa&&aa.$blk!==undefined){break s;}aa;ab=k[0].Close();$s=13;case 13:if($c){$c=false;ab=ab.$blk();}if(ab&&ab.$blk!==undefined){break s;}ab;$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.aa=aa;$f.ab=ab;$f.p=p;$f.q=q;$f.r=r;$f.s=s;$f.t=t;$f.u=u;$f.v=v;$f.w=w;$f.x=x;$f.y=y;$f.z=z;$f.$s=$s;$f.$r=$r;return $f;};})(a,k),[]);$s=6;continue;case 7:$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.$s=$s;$f.$r=$r;return $f;};})(a);$r=c();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}d=$recv(b.C);$s=4;case 4:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}d[0];$s=1;continue;case 2:$s=-1;return;}return;}if($f===undefined){$f={$blk:I};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Bridge=I;H.init(\"\",[{prop:\"DialAddr\",name:\"DialAddr\",embedded:false,exported:true,typ:$String,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=G.$init();$s=7;case 7:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"log\"]=(function(){var $pkg={},$init,A,E,B,C,D,F,G,Z,AA,AB,AC,AD,I,H,J,R;A=$packages[\"fmt\"];E=$packages[\"github.com/gopherjs/gopherjs/nosync\"];B=$packages[\"io\"];C=$packages[\"os\"];D=$packages[\"runtime\"];F=$packages[\"time\"];G=$pkg.Logger=$newType(0,$kindStruct,\"log.Logger\",true,\"log\",true,function(mu_,prefix_,flag_,out_,buf_){this.$val=this;if(arguments.length===0){this.mu=new E.Mutex.ptr(false);this.prefix=\"\";this.flag=0;this.out=$ifaceNil;this.buf=Z.nil;return;}this.mu=mu_;this.prefix=prefix_;this.flag=flag_;this.out=out_;this.buf=buf_;});Z=$sliceType($Uint8);AA=$arrayType($Uint8,20);AB=$ptrType(Z);AC=$sliceType($emptyInterface);AD=$ptrType(G);H=function(a,b,c){var a,b,c;return new G.ptr(new E.Mutex.ptr(false),b,c,a,Z.nil);};$pkg.New=H;G.ptr.prototype.SetOutput=function(a){var a,b,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=this;b.mu.Lock();$deferred.push([$methodVal(b.mu,\"Unlock\"),[]]);b.out=a;}catch(err){$err=err;}finally{$callDeferred($deferred,$err);}};G.prototype.SetOutput=function(a){return this.$val.SetOutput(a);};J=function(a,b,c){var a,b,c,d,e,f,g;d=AA.zero();e=19;while(true){if(!(b>=10||c>1)){break;}c=c-(1)>>0;g=(f=b/10,(f===f&&f!==1/0&&f!==-1/0)?f>>0:$throwRuntimeError(\"integer divide by zero\"));((e<0||e>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[e]=((((48+b>>0)-($imul(g,10))>>0)<<24>>>24)));e=e-(1)>>0;b=g;}((e<0||e>=d.length)?($throwRuntimeError(\"index out of range\"),undefined):d[e]=(((48+b>>0)<<24>>>24)));a.$set($appendSlice(a.$get(),$subslice(new Z(d),e)));};G.ptr.prototype.formatHeader=function(a,b,c,d){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;l=$f.l;m=$f.m;n=$f.n;o=$f.o;p=$f.p;q=$f.q;r=$f.r;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:e=this;a.$set($appendSlice(a.$get(),e.prefix));if(!(((e.flag&7)===0))){$s=1;continue;}$s=2;continue;case 1:if(!(((e.flag&32)===0))){F.Time.copy(b,$clone(b,F.Time).UTC());}if(!(((e.flag&1)===0))){$s=3;continue;}$s=4;continue;case 3:g=$clone(b,F.Time).Date();$s=5;case 5:if($c){$c=false;g=g.$blk();}if(g&&g.$blk!==undefined){break s;}f=g;h=f[0];i=f[1];j=f[2];J(a,h,4);a.$set($append(a.$get(),47));J(a,((i>>0)),2);a.$set($append(a.$get(),47));J(a,j,2);a.$set($append(a.$get(),32));case 4:if(!(((e.flag&6)===0))){$s=6;continue;}$s=7;continue;case 6:l=$clone(b,F.Time).Clock();$s=8;case 8:if($c){$c=false;l=l.$blk();}if(l&&l.$blk!==undefined){break s;}k=l;m=k[0];n=k[1];o=k[2];J(a,m,2);a.$set($append(a.$get(),58));J(a,n,2);a.$set($append(a.$get(),58));J(a,o,2);if(!(((e.flag&4)===0))){a.$set($append(a.$get(),46));J(a,(p=$clone(b,F.Time).Nanosecond()/1000,(p===p&&p!==1/0&&p!==-1/0)?p>>0:$throwRuntimeError(\"integer divide by zero\")),6);}a.$set($append(a.$get(),32));case 7:case 2:if(!(((e.flag&24)===0))){if(!(((e.flag&16)===0))){q=c;r=c.length-1>>0;while(true){if(!(r>0)){break;}if(c.charCodeAt(r)===47){q=$substring(c,(r+1>>0));break;}r=r-(1)>>0;}c=q;}a.$set($appendSlice(a.$get(),c));a.$set($append(a.$get(),58));J(a,d,-1);a.$set($appendSlice(a.$get(),\": \"));}$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.formatHeader};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.l=l;$f.m=m;$f.n=n;$f.o=o;$f.p=p;$f.q=q;$f.r=r;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.formatHeader=function(a,b,c,d){return this.$val.formatHeader(a,b,c,d);};G.ptr.prototype.Output=function(a,b){var a,b,c,d,e,f,g,h,i,j,k,$s,$deferred,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;j=$f.j;k=$f.k;$s=$f.$s;$deferred=$f.$deferred;$r=$f.$r;}var $err=null;try{s:while(true){switch($s){case 0:$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);c=this;d=$clone(F.Now(),F.Time);e=\"\";f=0;c.mu.Lock();$deferred.push([$methodVal(c.mu,\"Unlock\"),[]]);if(!(((c.flag&24)===0))){c.mu.Unlock();g=false;h=D.Caller(a);e=h[1];f=h[2];g=h[3];if(!g){e=\"???\";f=0;}c.mu.Lock();}c.buf=$subslice(c.buf,0,0);$r=c.formatHeader((c.$ptr_buf||(c.$ptr_buf=new AB(function(){return this.$target.buf;},function($v){this.$target.buf=$v;},c))),$clone(d,F.Time),e,f);$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}c.buf=$appendSlice(c.buf,b);if((b.length===0)||!((b.charCodeAt((b.length-1>>0))===10))){c.buf=$append(c.buf,10);}j=c.out.Write(c.buf);$s=2;case 2:if($c){$c=false;j=j.$blk();}if(j&&j.$blk!==undefined){break s;}i=j;k=i[1];$s=-1;return k;}return;}}catch(err){$err=err;$s=-1;return $ifaceNil;}finally{$callDeferred($deferred,$err);if($curGoroutine.asleep){if($f===undefined){$f={$blk:G.ptr.prototype.Output};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.j=j;$f.k=k;$f.$s=$s;$f.$deferred=$deferred;$f.$r=$r;return $f;}}};G.prototype.Output=function(a,b){return this.$val.Output(a,b);};G.ptr.prototype.Printf=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=A.Sprintf(a,b);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;f=c.Output(2,e);$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}f;$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Printf};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Printf=function(a,b){return this.$val.Printf(a,b);};G.ptr.prototype.Print=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=A.Sprint(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=b.Output(2,d);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Print};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Print=function(a){return this.$val.Print(a);};G.ptr.prototype.Println=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=A.Sprintln(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=b.Output(2,d);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Println};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Println=function(a){return this.$val.Println(a);};G.ptr.prototype.Fatal=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=A.Sprint(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=b.Output(2,d);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;C.Exit(1);$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Fatal};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Fatal=function(a){return this.$val.Fatal(a);};G.ptr.prototype.Fatalf=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=A.Sprintf(a,b);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;f=c.Output(2,e);$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}f;C.Exit(1);$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Fatalf};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Fatalf=function(a,b){return this.$val.Fatalf(a,b);};G.ptr.prototype.Fatalln=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=A.Sprintln(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=b.Output(2,d);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;C.Exit(1);$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Fatalln};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Fatalln=function(a){return this.$val.Fatalln(a);};G.ptr.prototype.Panic=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=A.Sprint(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=b.Output(2,d);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;$panic(new $String(d));$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Panic};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Panic=function(a){return this.$val.Panic(a);};G.ptr.prototype.Panicf=function(a,b){var a,b,c,d,e,f,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:c=this;d=A.Sprintf(a,b);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}e=d;f=c.Output(2,e);$s=2;case 2:if($c){$c=false;f=f.$blk();}if(f&&f.$blk!==undefined){break s;}f;$panic(new $String(e));$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Panicf};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Panicf=function(a,b){return this.$val.Panicf(a,b);};G.ptr.prototype.Panicln=function(a){var a,b,c,d,e,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;e=$f.e;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=this;c=A.Sprintln(a);$s=1;case 1:if($c){$c=false;c=c.$blk();}if(c&&c.$blk!==undefined){break s;}d=c;e=b.Output(2,d);$s=2;case 2:if($c){$c=false;e=e.$blk();}if(e&&e.$blk!==undefined){break s;}e;$panic(new $String(d));$s=-1;return;}return;}if($f===undefined){$f={$blk:G.ptr.prototype.Panicln};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.$s=$s;$f.$r=$r;return $f;};G.prototype.Panicln=function(a){return this.$val.Panicln(a);};G.ptr.prototype.Flags=function(){var a,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;a.mu.Lock();$deferred.push([$methodVal(a.mu,\"Unlock\"),[]]);return a.flag;}catch(err){$err=err;return 0;}finally{$callDeferred($deferred,$err);}};G.prototype.Flags=function(){return this.$val.Flags();};G.ptr.prototype.SetFlags=function(a){var a,b,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=this;b.mu.Lock();$deferred.push([$methodVal(b.mu,\"Unlock\"),[]]);b.flag=a;}catch(err){$err=err;}finally{$callDeferred($deferred,$err);}};G.prototype.SetFlags=function(a){return this.$val.SetFlags(a);};G.ptr.prototype.Prefix=function(){var a,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;a.mu.Lock();$deferred.push([$methodVal(a.mu,\"Unlock\"),[]]);return a.prefix;}catch(err){$err=err;return\"\";}finally{$callDeferred($deferred,$err);}};G.prototype.Prefix=function(){return this.$val.Prefix();};G.ptr.prototype.SetPrefix=function(a){var a,b,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);b=this;b.mu.Lock();$deferred.push([$methodVal(b.mu,\"Unlock\"),[]]);b.prefix=a;}catch(err){$err=err;}finally{$callDeferred($deferred,$err);}};G.prototype.SetPrefix=function(a){return this.$val.SetPrefix(a);};G.ptr.prototype.Writer=function(){var a,$deferred;var $err=null;try{$deferred=[];$deferred.index=$curGoroutine.deferStack.length;$curGoroutine.deferStack.push($deferred);a=this;a.mu.Lock();$deferred.push([$methodVal(a.mu,\"Unlock\"),[]]);return a.out;}catch(err){$err=err;return $ifaceNil;}finally{$callDeferred($deferred,$err);}};G.prototype.Writer=function(){return this.$val.Writer();};R=function(a){var a,b,c,d,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;b=$f.b;c=$f.c;d=$f.d;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=A.Sprintln(a);$s=1;case 1:if($c){$c=false;b=b.$blk();}if(b&&b.$blk!==undefined){break s;}c=b;d=I.Output(2,c);$s=2;case 2:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}d;$s=-1;return;}return;}if($f===undefined){$f={$blk:R};}$f.a=a;$f.b=b;$f.c=c;$f.d=d;$f.$s=$s;$f.$r=$r;return $f;};$pkg.Println=R;AD.methods=[{prop:\"SetOutput\",name:\"SetOutput\",pkg:\"\",typ:$funcType([B.Writer],[],false)},{prop:\"formatHeader\",name:\"formatHeader\",pkg:\"log\",typ:$funcType([AB,F.Time,$String,$Int],[],false)},{prop:\"Output\",name:\"Output\",pkg:\"\",typ:$funcType([$Int,$String],[$error],false)},{prop:\"Printf\",name:\"Printf\",pkg:\"\",typ:$funcType([$String,AC],[],true)},{prop:\"Print\",name:\"Print\",pkg:\"\",typ:$funcType([AC],[],true)},{prop:\"Println\",name:\"Println\",pkg:\"\",typ:$funcType([AC],[],true)},{prop:\"Fatal\",name:\"Fatal\",pkg:\"\",typ:$funcType([AC],[],true)},{prop:\"Fatalf\",name:\"Fatalf\",pkg:\"\",typ:$funcType([$String,AC],[],true)},{prop:\"Fatalln\",name:\"Fatalln\",pkg:\"\",typ:$funcType([AC],[],true)},{prop:\"Panic\",name:\"Panic\",pkg:\"\",typ:$funcType([AC],[],true)},{prop:\"Panicf\",name:\"Panicf\",pkg:\"\",typ:$funcType([$String,AC],[],true)},{prop:\"Panicln\",name:\"Panicln\",pkg:\"\",typ:$funcType([AC],[],true)},{prop:\"Flags\",name:\"Flags\",pkg:\"\",typ:$funcType([],[$Int],false)},{prop:\"SetFlags\",name:\"SetFlags\",pkg:\"\",typ:$funcType([$Int],[],false)},{prop:\"Prefix\",name:\"Prefix\",pkg:\"\",typ:$funcType([],[$String],false)},{prop:\"SetPrefix\",name:\"SetPrefix\",pkg:\"\",typ:$funcType([$String],[],false)},{prop:\"Writer\",name:\"Writer\",pkg:\"\",typ:$funcType([],[B.Writer],false)}];G.init(\"log\",[{prop:\"mu\",name:\"mu\",embedded:false,exported:false,typ:E.Mutex,tag:\"\"},{prop:\"prefix\",name:\"prefix\",embedded:false,exported:false,typ:$String,tag:\"\"},{prop:\"flag\",name:\"flag\",embedded:false,exported:false,typ:$Int,tag:\"\"},{prop:\"out\",name:\"out\",embedded:false,exported:false,typ:B.Writer,tag:\"\"},{prop:\"buf\",name:\"buf\",embedded:false,exported:false,typ:Z,tag:\"\"}]);$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=F.$init();$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}I=H(C.Stderr,\"\",3);}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$packages[\"github.com/v2fly/BrowserBridge/bridge/bridgejs\"]=(function(){var $pkg={},$init,A,B,C,D,E,G,F;A=$packages[\"fmt\"];B=$packages[\"github.com/gopherjs/gopherjs/js\"];C=$packages[\"github.com/v2fly/BrowserBridge/bridge\"];D=$packages[\"log\"];E=$packages[\"net/url\"];G=$sliceType($emptyInterface);F=function(){var a,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;a=$f.a;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:a=A.Println(new G([new $String(\"V3\")]));$s=1;case 1:if($c){$c=false;a=a.$blk();}if(a&&a.$blk!==undefined){break s;}a;$go((function $b(){var b,c,d,e,f,g,h,i,$s,$r;$s=0;var $f,$c=false;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;b=$f.b;c=$f.c;d=$f.d;e=$f.e;f=$f.f;g=$f.g;h=$f.h;i=$f.i;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:b=$internalize($global.window.location.href,$String);d=E.Parse(b);$s=1;case 1:if($c){$c=false;d=d.$blk();}if(d&&d.$blk!==undefined){break s;}c=d;e=c[0];f=c[1];if(!($interfaceIsEqual(f,$ifaceNil))){$s=2;continue;}$s=3;continue;case 2:$r=D.Println(new G([f]));$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}case 3:g=e.Host;h=A.Sprintf(\"ws://%v/link\",new G([new $String(g)]));$s=5;case 5:if($c){$c=false;h=h.$blk();}if(h&&h.$blk!==undefined){break s;}$r=D.Println(new G([new $String(h)]));$s=6;case 6:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}i=A.Sprintf(\"ws://%v/link\",new G([new $String(g)]));$s=7;case 7:if($c){$c=false;i=i.$blk();}if(i&&i.$blk!==undefined){break s;}$r=C.Bridge(new C.Settings.ptr(i));$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$global.location.reload();$s=-1;return;}return;}if($f===undefined){$f={$blk:$b};}$f.b=b;$f.c=c;$f.d=d;$f.e=e;$f.f=f;$f.g=g;$f.h=h;$f.i=i;$f.$s=$s;$f.$r=$r;return $f;}),[]);$s=-1;return;}return;}if($f===undefined){$f={$blk:F};}$f.a=a;$f.$s=$s;$f.$r=$r;return $f;};$init=function(){$pkg.$init=function(){};var $f,$c=false,$s=0,$r;if(this!==undefined&&this.$blk!==undefined){$f=this;$c=true;$s=$f.$s;$r=$f.$r;}s:while(true){switch($s){case 0:$r=A.$init();$s=1;case 1:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=B.$init();$s=2;case 2:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=C.$init();$s=3;case 3:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=D.$init();$s=4;case 4:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$r=E.$init();$s=5;case 5:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}if($pkg===$mainPkg){$s=6;continue;}$s=7;continue;case 6:$r=F();$s=8;case 8:if($c){$c=false;$r=$r.$blk();}if($r&&$r.$blk!==undefined){break s;}$mainFinished=true;case 7:}return;}if($f===undefined){$f={$blk:$init};}$f.$s=$s;$f.$r=$r;return $f;};$pkg.$init=$init;return $pkg;})();\n$synthesizeMethods();\nvar $mainPkg = $packages[\"github.com/v2fly/BrowserBridge/bridge/bridgejs\"];\n$packages[\"runtime\"].$init();\n$go($mainPkg.$init, []);\n$flushConsole();\n\n}).call(this);\n//# sourceMappingURL=bridgejs.js.map\n"
  },
  {
    "path": "release/friendly-filenames.json",
    "content": "{\n  \"darwin-amd64\": { \"friendlyName\": \"macos-64\" },\n  \"darwin-arm64\": { \"friendlyName\": \"macos-arm64-v8a\" },\n  \"dragonfly-amd64\": { \"friendlyName\": \"dragonfly-64\" },\n  \"freebsd-386\": { \"friendlyName\": \"freebsd-32\" },\n  \"freebsd-amd64\": { \"friendlyName\": \"freebsd-64\" },\n  \"freebsd-arm6\": { \"friendlyName\": \"freebsd-arm32-v6\" },\n  \"freebsd-arm7\": { \"friendlyName\": \"freebsd-arm32-v7a\" },\n  \"freebsd-arm64\": { \"friendlyName\": \"freebsd-arm64-v8a\" },\n  \"linux-386\": { \"friendlyName\": \"linux-32\" },\n  \"linux-amd64\": { \"friendlyName\": \"linux-64\" },\n  \"linux-amd64pie\": { \"friendlyName\": \"linux-64-pie\" },\n  \"linux-arm5\": { \"friendlyName\": \"linux-arm32-v5\" },\n  \"linux-arm64\": { \"friendlyName\": \"linux-arm64-v8a\" },\n  \"linux-arm64pie\": { \"friendlyName\": \"linux-arm64-v8a-pie\" },\n  \"linux-arm6\": { \"friendlyName\": \"linux-arm32-v6\" },\n  \"linux-arm7\": { \"friendlyName\": \"linux-arm32-v7a\" },\n  \"linux-mips64le\": { \"friendlyName\": \"linux-mips64le\" },\n  \"linux-mips64\": { \"friendlyName\": \"linux-mips64\" },\n  \"linux-mipsle\": { \"friendlyName\": \"linux-mips32le\" },\n  \"linux-mips\": { \"friendlyName\": \"linux-mips32\" },\n  \"linux-riscv64\": { \"friendlyName\": \"linux-riscv64\" },\n  \"linux-loong64\": { \"friendlyName\": \"linux-loong64\" },\n  \"openbsd-386\": { \"friendlyName\": \"openbsd-32\" },\n  \"openbsd-amd64\": { \"friendlyName\": \"openbsd-64\" },\n  \"openbsd-arm6\": { \"friendlyName\": \"openbsd-arm32-v6\" },\n  \"openbsd-arm7\": { \"friendlyName\": \"openbsd-arm32-v7a\" },\n  \"openbsd-arm64\": { \"friendlyName\": \"openbsd-arm64-v8a\" },\n  \"windows-amd64\": { \"friendlyName\": \"windows-64\" },\n  \"windows-386\": { \"friendlyName\": \"windows-32\" },\n  \"windows-arm64\": { \"friendlyName\": \"windows-arm64-v8a\" },\n  \"windows-arm7\": { \"friendlyName\": \"windows-arm32-v7a\" },\n  \"android-arm64\": { \"friendlyName\": \"android-arm64-v8a\" }\n}\n"
  },
  {
    "path": "release/install-release.sh",
    "content": "#!/usr/bin/env bash\n\n# This file is accessible as https://install.direct/go.sh\n# Original source is located at github.com/v2fly/v2ray-core/release/install-release.sh\n\n# If not specify, default meaning of return value:\n# 0: Success\n# 1: System error\n# 2: Application error\n# 3: Network error\n\n#######color code########\nRED=\"31m\"      # Error message\nYELLOW=\"33m\"   # Warning message\ncolorEcho(){\n    echo -e \"\\033[${1}${@:2}\\033[0m\" 1>& 2\n}\n\ncolorEcho ${RED} \"ERROR: This script has been DISCARDED, please switch to fhs-install-v2ray project.\"\ncolorEcho ${YELLOW} \"HOW TO USE: https://github.com/v2fly/fhs-install-v2ray\"\ncolorEcho ${YELLOW} \"TO MIGRATE: https://github.com/v2fly/fhs-install-v2ray/wiki/Migrate-from-the-old-script-to-this\"\nexit 255\n"
  },
  {
    "path": "release/requestsign.sh",
    "content": "#!/usr/bin/env bash\n\nRELEASE_DATA=$(curl --data \"version=${SIGN_VERSION}\" --data \"password=${SIGN_SERVICE_PASSWORD}\" -X POST \"${SIGN_SERIVCE_URL}\" )\necho $RELEASE_DATA\nRELEASE_ID=$(echo $RELEASE_DATA| jq -r \".id\")\n\nfunction uploadfile() {\n  FILE=$1\n  CTYPE=$(file -b --mime-type $FILE)\n\n  sleep 1\n  curl -H \"Authorization: token ${GITHUB_TOKEN}\" -H \"Content-Type: ${CTYPE}\" --data-binary @$FILE \"https://uploads.github.com/repos/v2fly/v2ray-core/releases/${RELEASE_ID}/assets?name=$(basename $FILE)\"\n  sleep 1\n}\n\nfunction upload() {\n  FILE=$1\n  DGST=$1.dgst\n  openssl dgst -md5 $FILE | sed 's/([^)]*)//g' >> $DGST\n  openssl dgst -sha1 $FILE | sed 's/([^)]*)//g' >> $DGST\n  openssl dgst -sha256 $FILE | sed 's/([^)]*)//g' >> $DGST\n  openssl dgst -sha512 $FILE | sed 's/([^)]*)//g' >> $DGST\n  uploadfile $FILE\n  uploadfile $DGST\n}\n\ncurl \"https://raw.githubusercontent.com/v2fly/Release/master/v2fly/${SIGN_VERSION}.Release\" > Release\nupload Release\n"
  },
  {
    "path": "release/user-package.sh",
    "content": "#!/usr/bin/env bash\n\nset -o errexit\nset -o pipefail\nset -o nounset\n# set -o xtrace\n\ntrap 'echo -e \"Aborted, error $? in command: $BASH_COMMAND\"; trap ERR; exit 1' ERR\n\nNOW=$(date '+%Y%m%d-%H%M%S')\nTMP=$(mktemp -d)\nSRCDIR=$(pwd)\n\nCODENAME=\"user\"\nBUILDNAME=$NOW\n\ncleanup() { rm -rf \"$TMP\"; }\ntrap cleanup INT TERM ERR\n\nget_source() {\n\techo \">>> Clone v2fly/v2ray-core repo...\"\n\tgit clone https://github.com/v2fly/v2ray-core.git\n\tcd v2ray-core\n\tgo mod download\n}\n\nbuild_v2() {\n\tif [[ $nosource != 1 ]]; then\n\t\tcd ${SRCDIR}/v2ray-core\n\t\tlocal VERSIONTAG=$(git describe --abbrev=0 --tags)\n\telse\n\t\techo \">>> Use current directory as WORKDIR\"\n\t\tlocal VERSIONTAG=$(git describe --abbrev=0 --tags)\n\tfi\n\n\tLDFLAGS=\"-s -w -buildid= -X github.com/v2fly/v2ray-core/v5.codename=${CODENAME} -X github.com/v2fly/v2ray-core/v5.build=${BUILDNAME} -X github.com/v2fly/v2ray-core/v5.version=${VERSIONTAG}\"\n\n\techo \">>> Compile v2ray ...\"\n\tenv CGO_ENABLED=0 go build -o \"$TMP\"/v2ray\"${EXESUFFIX}\" -ldflags \"$LDFLAGS\" ./main\n}\n\nbuild_dat() {\n\techo \">>> Download latest geoip.dat\"\n\tcurl -s -L -o \"$TMP\"/geoip.dat \"https://github.com/v2fly/geoip/raw/release/geoip.dat\"\n\n\techo \">>> Download latest geoip-only-cn-private.dat\"\n\tcurl -s -L -o \"$TMP\"/geoip-only-cn-private.dat \"https://github.com/v2fly/geoip/raw/release/geoip-only-cn-private.dat\"\n\n\techo \">>> Download latest geosite.dat\"\n\tcurl -s -L -o \"$TMP\"/geosite.dat \"https://github.com/v2fly/domain-list-community/raw/release/dlc.dat\"\n}\n\ncopyconf() {\n\techo \">>> Copying config...\"\n\tcd ./release/config\n\tif [[ $GOOS == \"linux\" ]]; then\n\t\ttar c --exclude \"*.dat\" . | tar x -C \"$TMP\"\n\telse\n\t\ttar c --exclude \"*.dat\" --exclude \"systemd/**\" . | tar x -C \"$TMP\"\n\tfi\n}\n\npackzip() {\n\techo \">>> Generating zip package\"\n\tcd \"$TMP\"\n\tlocal PKG=${SRCDIR}/v2ray-custom-${GOARCH}-${GOOS}-${PKGSUFFIX}${NOW}.zip\n\tzip -r \"$PKG\" .\n\techo \">>> Generated: $(basename \"$PKG\") at $(dirname \"$PKG\")\"\n}\n\npacktgz() {\n\techo \">>> Generating tgz package\"\n\tcd \"$TMP\"\n\tlocal PKG=${SRCDIR}/v2ray-custom-${GOARCH}-${GOOS}-${PKGSUFFIX}${NOW}.tar.gz\n\ttar cvfz \"$PKG\" .\n\techo \">>> Generated: $(basename \"$PKG\") at $(dirname \"$PKG\")\"\n}\n\npacktgzAbPath() {\n\tlocal ABPATH=\"$1\"\n\techo \">>> Generating tgz package at $ABPATH\"\n\tcd \"$TMP\"\n\ttar cvfz \"$ABPATH\" .\n\techo \">>> Generated: $ABPATH\"\n}\n\npkg=zip\nnosource=0\nnodat=0\nnoconf=0\nGOOS=linux\nGOARCH=amd64\nEXESUFFIX=\nPKGSUFFIX=\n\nfor arg in \"$@\"; do\n\tcase $arg in\n\t386 | arm* | mips* | ppc64* | riscv64 | loong64 | s390x)\n\t\tGOARCH=$arg\n\t\t;;\n\twindows)\n\t\tGOOS=$arg\n\t\tEXESUFFIX=.exe\n\t\t;;\n\tdarwin | dragonfly | freebsd | openbsd)\n\t\tGOOS=$arg\n\t\t;;\n\tnodat)\n\t\tnodat=1\n\t\tPKGSUFFIX=${PKGSUFFIX}nodat-\n\t\t;;\n\tnoconf)\n\t\tnoconf=1\n\t\t;;\n\tnosource)\n\t\tnosource=1\n\t\t;;\n\ttgz)\n\t\tpkg=tgz\n\t\t;;\n\tabpathtgz=*)\n\t\tpkg=${arg##abpathtgz=}\n\t\t;;\n\tcodename=*)\n\t\tCODENAME=${arg##codename=}\n\t\t;;\n\tbuildname=*)\n\t\tBUILDNAME=${arg##buildname=}\n\t\t;;\n\tesac\ndone\n\nif [[ $nosource != 1 ]]; then\n\tget_source\nfi\n\nexport GOOS GOARCH\necho \"Build ARGS: GOOS=${GOOS} GOARCH=${GOARCH} CODENAME=${CODENAME} BUILDNAME=${BUILDNAME}\"\necho \"PKG ARGS: pkg=${pkg}\"\nbuild_v2\n\nif [[ $nodat != 1 ]]; then\n\tbuild_dat\nfi\n\nif [[ $noconf != 1 ]]; then\n\tcopyconf\nfi\n\nif [[ $pkg == \"zip\" ]]; then\n\tpackzip\nelif [[ $pkg == \"tgz\" ]]; then\n\tpacktgz\nelse\n\tpacktgzAbPath \"$pkg\"\nfi\n\ncleanup\n"
  },
  {
    "path": "testing/mocks/dns.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/v2fly/v2ray-core/v5/features/dns (interfaces: Client)\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\tnet \"net\"\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// DNSClient is a mock of Client interface.\ntype DNSClient struct {\n\tctrl     *gomock.Controller\n\trecorder *DNSClientMockRecorder\n}\n\n// DNSClientMockRecorder is the mock recorder for DNSClient.\ntype DNSClientMockRecorder struct {\n\tmock *DNSClient\n}\n\n// NewDNSClient creates a new mock instance.\nfunc NewDNSClient(ctrl *gomock.Controller) *DNSClient {\n\tmock := &DNSClient{ctrl: ctrl}\n\tmock.recorder = &DNSClientMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *DNSClient) EXPECT() *DNSClientMockRecorder {\n\treturn m.recorder\n}\n\n// Close mocks base method.\nfunc (m *DNSClient) Close() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Close\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Close indicates an expected call of Close.\nfunc (mr *DNSClientMockRecorder) Close() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Close\", reflect.TypeOf((*DNSClient)(nil).Close))\n}\n\n// LookupIP mocks base method.\nfunc (m *DNSClient) LookupIP(arg0 string) ([]net.IP, error) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"LookupIP\", arg0)\n\tret0, _ := ret[0].([]net.IP)\n\tret1, _ := ret[1].(error)\n\treturn ret0, ret1\n}\n\n// LookupIP indicates an expected call of LookupIP.\nfunc (mr *DNSClientMockRecorder) LookupIP(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"LookupIP\", reflect.TypeOf((*DNSClient)(nil).LookupIP), arg0)\n}\n\n// Start mocks base method.\nfunc (m *DNSClient) Start() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Start\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Start indicates an expected call of Start.\nfunc (mr *DNSClientMockRecorder) Start() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Start\", reflect.TypeOf((*DNSClient)(nil).Start))\n}\n\n// Type mocks base method.\nfunc (m *DNSClient) Type() interface{} {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Type\")\n\tret0, _ := ret[0].(interface{})\n\treturn ret0\n}\n\n// Type indicates an expected call of Type.\nfunc (mr *DNSClientMockRecorder) Type() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Type\", reflect.TypeOf((*DNSClient)(nil).Type))\n}\n"
  },
  {
    "path": "testing/mocks/io.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: io (interfaces: Reader,Writer)\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n)\n\n// Reader is a mock of Reader interface.\ntype Reader struct {\n\tctrl     *gomock.Controller\n\trecorder *ReaderMockRecorder\n}\n\n// ReaderMockRecorder is the mock recorder for Reader.\ntype ReaderMockRecorder struct {\n\tmock *Reader\n}\n\n// NewReader creates a new mock instance.\nfunc NewReader(ctrl *gomock.Controller) *Reader {\n\tmock := &Reader{ctrl: ctrl}\n\tmock.recorder = &ReaderMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *Reader) EXPECT() *ReaderMockRecorder {\n\treturn m.recorder\n}\n\n// Read mocks base method.\nfunc (m *Reader) Read(arg0 []byte) (int, error) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Read\", arg0)\n\tret0, _ := ret[0].(int)\n\tret1, _ := ret[1].(error)\n\treturn ret0, ret1\n}\n\n// Read indicates an expected call of Read.\nfunc (mr *ReaderMockRecorder) Read(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Read\", reflect.TypeOf((*Reader)(nil).Read), arg0)\n}\n\n// Writer is a mock of Writer interface.\ntype Writer struct {\n\tctrl     *gomock.Controller\n\trecorder *WriterMockRecorder\n}\n\n// WriterMockRecorder is the mock recorder for Writer.\ntype WriterMockRecorder struct {\n\tmock *Writer\n}\n\n// NewWriter creates a new mock instance.\nfunc NewWriter(ctrl *gomock.Controller) *Writer {\n\tmock := &Writer{ctrl: ctrl}\n\tmock.recorder = &WriterMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *Writer) EXPECT() *WriterMockRecorder {\n\treturn m.recorder\n}\n\n// Write mocks base method.\nfunc (m *Writer) Write(arg0 []byte) (int, error) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Write\", arg0)\n\tret0, _ := ret[0].(int)\n\tret1, _ := ret[1].(error)\n\treturn ret0, ret1\n}\n\n// Write indicates an expected call of Write.\nfunc (mr *WriterMockRecorder) Write(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Write\", reflect.TypeOf((*Writer)(nil).Write), arg0)\n}\n"
  },
  {
    "path": "testing/mocks/log.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/v2fly/v2ray-core/v5/common/log (interfaces: Handler)\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\tlog \"github.com/v2fly/v2ray-core/v5/common/log\"\n)\n\n// LogHandler is a mock of Handler interface.\ntype LogHandler struct {\n\tctrl     *gomock.Controller\n\trecorder *LogHandlerMockRecorder\n}\n\n// LogHandlerMockRecorder is the mock recorder for LogHandler.\ntype LogHandlerMockRecorder struct {\n\tmock *LogHandler\n}\n\n// NewLogHandler creates a new mock instance.\nfunc NewLogHandler(ctrl *gomock.Controller) *LogHandler {\n\tmock := &LogHandler{ctrl: ctrl}\n\tmock.recorder = &LogHandlerMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *LogHandler) EXPECT() *LogHandlerMockRecorder {\n\treturn m.recorder\n}\n\n// Handle mocks base method.\nfunc (m *LogHandler) Handle(arg0 log.Message) {\n\tm.ctrl.T.Helper()\n\tm.ctrl.Call(m, \"Handle\", arg0)\n}\n\n// Handle indicates an expected call of Handle.\nfunc (mr *LogHandlerMockRecorder) Handle(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Handle\", reflect.TypeOf((*LogHandler)(nil).Handle), arg0)\n}\n"
  },
  {
    "path": "testing/mocks/mux.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/v2fly/v2ray-core/v5/common/mux (interfaces: ClientWorkerFactory)\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\tmux \"github.com/v2fly/v2ray-core/v5/common/mux\"\n)\n\n// MuxClientWorkerFactory is a mock of ClientWorkerFactory interface.\ntype MuxClientWorkerFactory struct {\n\tctrl     *gomock.Controller\n\trecorder *MuxClientWorkerFactoryMockRecorder\n}\n\n// MuxClientWorkerFactoryMockRecorder is the mock recorder for MuxClientWorkerFactory.\ntype MuxClientWorkerFactoryMockRecorder struct {\n\tmock *MuxClientWorkerFactory\n}\n\n// NewMuxClientWorkerFactory creates a new mock instance.\nfunc NewMuxClientWorkerFactory(ctrl *gomock.Controller) *MuxClientWorkerFactory {\n\tmock := &MuxClientWorkerFactory{ctrl: ctrl}\n\tmock.recorder = &MuxClientWorkerFactoryMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *MuxClientWorkerFactory) EXPECT() *MuxClientWorkerFactoryMockRecorder {\n\treturn m.recorder\n}\n\n// Create mocks base method.\nfunc (m *MuxClientWorkerFactory) Create() (*mux.ClientWorker, error) {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Create\")\n\tret0, _ := ret[0].(*mux.ClientWorker)\n\tret1, _ := ret[1].(error)\n\treturn ret0, ret1\n}\n\n// Create indicates an expected call of Create.\nfunc (mr *MuxClientWorkerFactoryMockRecorder) Create() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Create\", reflect.TypeOf((*MuxClientWorkerFactory)(nil).Create))\n}\n"
  },
  {
    "path": "testing/mocks/outbound.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/v2fly/v2ray-core/v5/features/outbound (interfaces: Manager,HandlerSelector)\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\tcontext \"context\"\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\toutbound \"github.com/v2fly/v2ray-core/v5/features/outbound\"\n)\n\n// OutboundManager is a mock of Manager interface.\ntype OutboundManager struct {\n\tctrl     *gomock.Controller\n\trecorder *OutboundManagerMockRecorder\n}\n\n// OutboundManagerMockRecorder is the mock recorder for OutboundManager.\ntype OutboundManagerMockRecorder struct {\n\tmock *OutboundManager\n}\n\n// NewOutboundManager creates a new mock instance.\nfunc NewOutboundManager(ctrl *gomock.Controller) *OutboundManager {\n\tmock := &OutboundManager{ctrl: ctrl}\n\tmock.recorder = &OutboundManagerMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *OutboundManager) EXPECT() *OutboundManagerMockRecorder {\n\treturn m.recorder\n}\n\n// AddHandler mocks base method.\nfunc (m *OutboundManager) AddHandler(arg0 context.Context, arg1 outbound.Handler) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"AddHandler\", arg0, arg1)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// AddHandler indicates an expected call of AddHandler.\nfunc (mr *OutboundManagerMockRecorder) AddHandler(arg0, arg1 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"AddHandler\", reflect.TypeOf((*OutboundManager)(nil).AddHandler), arg0, arg1)\n}\n\n// Close mocks base method.\nfunc (m *OutboundManager) Close() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Close\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Close indicates an expected call of Close.\nfunc (mr *OutboundManagerMockRecorder) Close() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Close\", reflect.TypeOf((*OutboundManager)(nil).Close))\n}\n\n// GetDefaultHandler mocks base method.\nfunc (m *OutboundManager) GetDefaultHandler() outbound.Handler {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"GetDefaultHandler\")\n\tret0, _ := ret[0].(outbound.Handler)\n\treturn ret0\n}\n\n// GetDefaultHandler indicates an expected call of GetDefaultHandler.\nfunc (mr *OutboundManagerMockRecorder) GetDefaultHandler() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"GetDefaultHandler\", reflect.TypeOf((*OutboundManager)(nil).GetDefaultHandler))\n}\n\n// GetHandler mocks base method.\nfunc (m *OutboundManager) GetHandler(arg0 string) outbound.Handler {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"GetHandler\", arg0)\n\tret0, _ := ret[0].(outbound.Handler)\n\treturn ret0\n}\n\n// GetHandler indicates an expected call of GetHandler.\nfunc (mr *OutboundManagerMockRecorder) GetHandler(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"GetHandler\", reflect.TypeOf((*OutboundManager)(nil).GetHandler), arg0)\n}\n\n// RemoveHandler mocks base method.\nfunc (m *OutboundManager) RemoveHandler(arg0 context.Context, arg1 string) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"RemoveHandler\", arg0, arg1)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// RemoveHandler indicates an expected call of RemoveHandler.\nfunc (mr *OutboundManagerMockRecorder) RemoveHandler(arg0, arg1 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"RemoveHandler\", reflect.TypeOf((*OutboundManager)(nil).RemoveHandler), arg0, arg1)\n}\n\n// Start mocks base method.\nfunc (m *OutboundManager) Start() error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Start\")\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Start indicates an expected call of Start.\nfunc (mr *OutboundManagerMockRecorder) Start() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Start\", reflect.TypeOf((*OutboundManager)(nil).Start))\n}\n\n// Type mocks base method.\nfunc (m *OutboundManager) Type() interface{} {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Type\")\n\tret0, _ := ret[0].(interface{})\n\treturn ret0\n}\n\n// Type indicates an expected call of Type.\nfunc (mr *OutboundManagerMockRecorder) Type() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Type\", reflect.TypeOf((*OutboundManager)(nil).Type))\n}\n\n// OutboundHandlerSelector is a mock of HandlerSelector interface.\ntype OutboundHandlerSelector struct {\n\tctrl     *gomock.Controller\n\trecorder *OutboundHandlerSelectorMockRecorder\n}\n\n// OutboundHandlerSelectorMockRecorder is the mock recorder for OutboundHandlerSelector.\ntype OutboundHandlerSelectorMockRecorder struct {\n\tmock *OutboundHandlerSelector\n}\n\n// NewOutboundHandlerSelector creates a new mock instance.\nfunc NewOutboundHandlerSelector(ctrl *gomock.Controller) *OutboundHandlerSelector {\n\tmock := &OutboundHandlerSelector{ctrl: ctrl}\n\tmock.recorder = &OutboundHandlerSelectorMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *OutboundHandlerSelector) EXPECT() *OutboundHandlerSelectorMockRecorder {\n\treturn m.recorder\n}\n\n// Select mocks base method.\nfunc (m *OutboundHandlerSelector) Select(arg0 []string) []string {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Select\", arg0)\n\tret0, _ := ret[0].([]string)\n\treturn ret0\n}\n\n// Select indicates an expected call of Select.\nfunc (mr *OutboundHandlerSelectorMockRecorder) Select(arg0 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Select\", reflect.TypeOf((*OutboundHandlerSelector)(nil).Select), arg0)\n}\n"
  },
  {
    "path": "testing/mocks/proxy.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: github.com/v2fly/v2ray-core/v5/proxy (interfaces: Inbound,Outbound)\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\tcontext \"context\"\n\treflect \"reflect\"\n\n\tgomock \"github.com/golang/mock/gomock\"\n\tnet \"github.com/v2fly/v2ray-core/v5/common/net\"\n\trouting \"github.com/v2fly/v2ray-core/v5/features/routing\"\n\ttransport \"github.com/v2fly/v2ray-core/v5/transport\"\n\tinternet \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// ProxyInbound is a mock of Inbound interface.\ntype ProxyInbound struct {\n\tctrl     *gomock.Controller\n\trecorder *ProxyInboundMockRecorder\n}\n\n// ProxyInboundMockRecorder is the mock recorder for ProxyInbound.\ntype ProxyInboundMockRecorder struct {\n\tmock *ProxyInbound\n}\n\n// NewProxyInbound creates a new mock instance.\nfunc NewProxyInbound(ctrl *gomock.Controller) *ProxyInbound {\n\tmock := &ProxyInbound{ctrl: ctrl}\n\tmock.recorder = &ProxyInboundMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *ProxyInbound) EXPECT() *ProxyInboundMockRecorder {\n\treturn m.recorder\n}\n\n// Network mocks base method.\nfunc (m *ProxyInbound) Network() []net.Network {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Network\")\n\tret0, _ := ret[0].([]net.Network)\n\treturn ret0\n}\n\n// Network indicates an expected call of Network.\nfunc (mr *ProxyInboundMockRecorder) Network() *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Network\", reflect.TypeOf((*ProxyInbound)(nil).Network))\n}\n\n// Process mocks base method.\nfunc (m *ProxyInbound) Process(arg0 context.Context, arg1 net.Network, arg2 internet.Connection, arg3 routing.Dispatcher) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Process\", arg0, arg1, arg2, arg3)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Process indicates an expected call of Process.\nfunc (mr *ProxyInboundMockRecorder) Process(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Process\", reflect.TypeOf((*ProxyInbound)(nil).Process), arg0, arg1, arg2, arg3)\n}\n\n// ProxyOutbound is a mock of Outbound interface.\ntype ProxyOutbound struct {\n\tctrl     *gomock.Controller\n\trecorder *ProxyOutboundMockRecorder\n}\n\n// ProxyOutboundMockRecorder is the mock recorder for ProxyOutbound.\ntype ProxyOutboundMockRecorder struct {\n\tmock *ProxyOutbound\n}\n\n// NewProxyOutbound creates a new mock instance.\nfunc NewProxyOutbound(ctrl *gomock.Controller) *ProxyOutbound {\n\tmock := &ProxyOutbound{ctrl: ctrl}\n\tmock.recorder = &ProxyOutboundMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *ProxyOutbound) EXPECT() *ProxyOutboundMockRecorder {\n\treturn m.recorder\n}\n\n// Process mocks base method.\nfunc (m *ProxyOutbound) Process(arg0 context.Context, arg1 *transport.Link, arg2 internet.Dialer) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Process\", arg0, arg1, arg2)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Process indicates an expected call of Process.\nfunc (mr *ProxyOutboundMockRecorder) Process(arg0, arg1, arg2 interface{}) *gomock.Call {\n\tmr.mock.ctrl.T.Helper()\n\treturn mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Process\", reflect.TypeOf((*ProxyOutbound)(nil).Process), arg0, arg1, arg2)\n}\n"
  },
  {
    "path": "testing/scenarios/cert/self-signed_cert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIBhDCCASmgAwIBAgIQOGW77bhKIQBVcKBkruQEjDAKBggqhkjOPQQDAjAoMRIw\nEAYDVQQKEwlWMlJheSBJbmMxEjAQBgNVBAMTCVYyUmF5IEluYzAeFw0yNDA5MTUx\nNjIyMjRaFw0yNDEyMTQxNzIyMjRaMCgxEjAQBgNVBAoTCVYyUmF5IEluYzESMBAG\nA1UEAxMJVjJSYXkgSW5jMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmKTCe3pJ\n6qYR8JSt4LHurI9ukGQISTBBLrFw8fDsWTeJielnHZdqgKL9swcC+IF/ikjzbT5W\niP0EGUBGk6wbPKM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUF\nBwMBMAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0EAwIDSQAwRgIhAKIZM1xlaHwSHsZP\nV6aN+AbWnoRgwVVJuY4I5q17FY0cAiEAiLr9NkHd9glFz0BzALygvo7gnNpgF69l\nDdiZ4828MXY=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "testing/scenarios/cert/self-signed_key.pem",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgmkOATgwafiG4sDs/\nJ1xVZfimvgREFJy0mtZHeGM2O6ehRANCAASYpMJ7eknqphHwlK3gse6sj26QZAhJ\nMEEusXDx8OxZN4mJ6Wcdl2qAov2zBwL4gX+KSPNtPlaI/QQZQEaTrBs8\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "testing/scenarios/command_test.go",
    "content": "package scenarios\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/commander\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman/command\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/stats\"\n\tstatscmd \"github.com/v2fly/v2ray-core/v5/app/stats/command\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestCommanderRemoveHandler(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tclientPort := tcp.PickPort()\n\tcmdPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&commander.Config{\n\t\t\t\tTag: \"api\",\n\t\t\t\tService: []*anypb.Any{\n\t\t\t\t\tserial.ToTypedMessage(&command.Config{}),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tInboundTag: []string{\"api\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"api\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"d\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"api\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(cmdPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag:           \"default-outbound\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tcmdConn, err := grpc.Dial(fmt.Sprintf(\"127.0.0.1:%d\", cmdPort), grpc.WithInsecure(), grpc.WithBlock())\n\tcommon.Must(err)\n\tdefer cmdConn.Close()\n\n\thsClient := command.NewHandlerServiceClient(cmdConn)\n\tresp, err := hsClient.RemoveInbound(context.Background(), &command.RemoveInboundRequest{\n\t\tTag: \"d\",\n\t})\n\tcommon.Must(err)\n\tif resp == nil {\n\t\tt.Error(\"unexpected nil response\")\n\t}\n\n\t{\n\t\t_, err := net.DialTCP(\"tcp\", nil, &net.TCPAddr{\n\t\t\tIP:   []byte{127, 0, 0, 1},\n\t\t\tPort: int(clientPort),\n\t\t})\n\t\tif err == nil {\n\t\t\tt.Error(\"unexpected nil error\")\n\t\t}\n\t}\n}\n\nfunc TestCommanderAddRemoveUser(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tu1 := protocol.NewID(uuid.New())\n\tu2 := protocol.NewID(uuid.New())\n\n\tcmdPort := tcp.PickPort()\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&commander.Config{\n\t\t\t\tTag: \"api\",\n\t\t\t\tService: []*anypb.Any{\n\t\t\t\t\tserial.ToTypedMessage(&command.Config{}),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tInboundTag: []string{\"api\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"api\",\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\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"v\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      u1.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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{\n\t\t\t\tTag: \"api\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(cmdPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"d\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      u2.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*5)(); err != io.EOF &&\n\t\t/*We might wish to drain the connection*/\n\t\t(err != nil && !strings.HasSuffix(err.Error(), \"i/o timeout\")) {\n\t\tt.Fatal(\"expected error: \", err)\n\t}\n\n\tcmdConn, err := grpc.Dial(fmt.Sprintf(\"127.0.0.1:%d\", cmdPort), grpc.WithInsecure(), grpc.WithBlock())\n\tcommon.Must(err)\n\tdefer cmdConn.Close()\n\n\thsClient := command.NewHandlerServiceClient(cmdConn)\n\tresp, err := hsClient.AlterInbound(context.Background(), &command.AlterInboundRequest{\n\t\tTag: \"v\",\n\t\tOperation: serial.ToTypedMessage(\n\t\t\t&command.AddUserOperation{\n\t\t\t\tUser: &protocol.User{\n\t\t\t\t\tEmail: \"test@v2fly.org\",\n\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\tId:      u2.String(),\n\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t})\n\tcommon.Must(err)\n\tif resp == nil {\n\t\tt.Fatal(\"nil response\")\n\t}\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tresp, err = hsClient.AlterInbound(context.Background(), &command.AlterInboundRequest{\n\t\tTag:       \"v\",\n\t\tOperation: serial.ToTypedMessage(&command.RemoveUserOperation{Email: \"test@v2fly.org\"}),\n\t})\n\tcommon.Must(err)\n\tif resp == nil {\n\t\tt.Fatal(\"nil response\")\n\t}\n}\n\nfunc TestCommanderStats(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tcmdPort := tcp.PickPort()\n\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&stats.Config{}),\n\t\t\tserial.ToTypedMessage(&commander.Config{\n\t\t\t\tTag: \"api\",\n\t\t\t\tService: []*anypb.Any{\n\t\t\t\t\tserial.ToTypedMessage(&statscmd.Config{}),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tInboundTag: []string{\"api\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"api\",\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\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t1: {\n\t\t\t\t\t\tStats: &policy.Policy_Stats{\n\t\t\t\t\t\t\tUserUplink:   true,\n\t\t\t\t\t\t\tUserDownlink: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSystem: &policy.SystemPolicy{\n\t\t\t\t\tStats: &policy.SystemPolicy_Stats{\n\t\t\t\t\t\tInboundUplink: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"vmess\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLevel: 1,\n\t\t\t\t\t\t\tEmail: \"test\",\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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{\n\t\t\t\tTag: \"api\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(cmdPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to create all servers\", err)\n\t}\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 10240*1024, time.Second*20)(); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tcmdConn, err := grpc.Dial(fmt.Sprintf(\"127.0.0.1:%d\", cmdPort), grpc.WithInsecure(), grpc.WithBlock())\n\tcommon.Must(err)\n\tdefer cmdConn.Close()\n\n\tconst name = \"user>>>test>>>traffic>>>uplink\"\n\tsClient := statscmd.NewStatsServiceClient(cmdConn)\n\n\tsresp, err := sClient.GetStats(context.Background(), &statscmd.GetStatsRequest{\n\t\tName:   name,\n\t\tReset_: true,\n\t})\n\tcommon.Must(err)\n\tif r := cmp.Diff(sresp.Stat, &statscmd.Stat{\n\t\tName:  name,\n\t\tValue: 10240 * 1024,\n\t}, cmpopts.IgnoreUnexported(statscmd.Stat{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tsresp, err = sClient.GetStats(context.Background(), &statscmd.GetStatsRequest{\n\t\tName: name,\n\t})\n\tcommon.Must(err)\n\tif r := cmp.Diff(sresp.Stat, &statscmd.Stat{\n\t\tName:  name,\n\t\tValue: 0,\n\t}, cmpopts.IgnoreUnexported(statscmd.Stat{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tsresp, err = sClient.GetStats(context.Background(), &statscmd.GetStatsRequest{\n\t\tName:   \"inbound>>>vmess>>>traffic>>>uplink\",\n\t\tReset_: true,\n\t})\n\tcommon.Must(err)\n\tif sresp.Stat.Value <= 10240*1024 {\n\t\tt.Error(\"value < 10240*1024: \", sresp.Stat.Value)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/common.go",
    "content": "package scenarios\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"golang.org/x/net/proxy\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/units\"\n)\n\nfunc xor(b []byte) []byte {\n\tr := make([]byte, len(b))\n\tfor i, v := range b {\n\t\tr[i] = v ^ 'c'\n\t}\n\treturn r\n}\n\nfunc readFrom(conn net.Conn, timeout time.Duration, length int) []byte {\n\tb := make([]byte, length)\n\tdeadline := time.Now().Add(timeout)\n\tconn.SetReadDeadline(deadline)\n\tn, err := io.ReadFull(conn, b[:length])\n\tif err != nil {\n\t\tfmt.Println(\"Unexpected error from readFrom:\", err)\n\t}\n\treturn b[:n]\n}\n\nfunc readFrom2(conn net.Conn, timeout time.Duration, length int) ([]byte, error) {\n\tb := make([]byte, length)\n\tdeadline := time.Now().Add(timeout)\n\tconn.SetReadDeadline(deadline)\n\tn, err := io.ReadFull(conn, b[:length])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn b[:n], nil\n}\n\nfunc InitializeServerConfigs(configs ...*core.Config) ([]*exec.Cmd, error) {\n\tservers := make([]*exec.Cmd, 0, 10)\n\n\tfor _, config := range configs {\n\t\tserver, err := InitializeServerConfig(config)\n\t\tif err != nil {\n\t\t\tCloseAllServers(servers)\n\t\t\treturn nil, err\n\t\t}\n\t\tservers = append(servers, server)\n\t}\n\n\ttime.Sleep(time.Second * 2)\n\n\treturn servers, nil\n}\n\nfunc InitializeServerConfig(config *core.Config) (*exec.Cmd, error) {\n\terr := BuildV2Ray()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfig = withDefaultApps(config)\n\tconfigBytes, err := proto.Marshal(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tproc := RunV2RayProtobuf(configBytes)\n\n\tif err := proc.Start(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn proc, nil\n}\n\nvar (\n\ttestBinaryPath    string\n\ttestBinaryPathGen sync.Once\n)\n\nfunc genTestBinaryPath() {\n\ttestBinaryPathGen.Do(func() {\n\t\tvar tempDir string\n\t\tcommon.Must(retry.Timed(5, 100).On(func() error {\n\t\t\tdir, err := os.MkdirTemp(\"\", \"v2ray\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\ttempDir = dir\n\t\t\treturn nil\n\t\t}))\n\t\tfile := filepath.Join(tempDir, \"v2ray.test\")\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tfile += \".exe\"\n\t\t}\n\t\ttestBinaryPath = file\n\t\tfmt.Printf(\"Generated binary path: %s\\n\", file)\n\t})\n}\n\nfunc GetSourcePath() string {\n\treturn filepath.Join(\"github.com\", \"v2fly\", \"v2ray-core\", \"v5\", \"main\")\n}\n\nfunc CloseAllServers(servers []*exec.Cmd) {\n\tlog.Record(&log.GeneralMessage{\n\t\tSeverity: log.Severity_Info,\n\t\tContent:  \"Closing all servers.\",\n\t})\n\tfor _, server := range servers {\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tserver.Process.Kill()\n\t\t} else {\n\t\t\tserver.Process.Signal(syscall.SIGTERM)\n\t\t}\n\t}\n\tfor _, server := range servers {\n\t\tserver.Process.Wait()\n\t}\n\tlog.Record(&log.GeneralMessage{\n\t\tSeverity: log.Severity_Info,\n\t\tContent:  \"All server closed.\",\n\t})\n}\n\nfunc CloseServer(server *exec.Cmd) {\n\tlog.Record(&log.GeneralMessage{\n\t\tSeverity: log.Severity_Info,\n\t\tContent:  \"Closing server.\",\n\t})\n\tif runtime.GOOS == \"windows\" {\n\t\tserver.Process.Kill()\n\t} else {\n\t\tserver.Process.Signal(syscall.SIGTERM)\n\t}\n\tserver.Process.Wait()\n\tlog.Record(&log.GeneralMessage{\n\t\tSeverity: log.Severity_Info,\n\t\tContent:  \"Server closed.\",\n\t})\n}\n\nfunc withDefaultApps(config *core.Config) *core.Config {\n\tconfig.App = append(config.App, serial.ToTypedMessage(&dispatcher.Config{}))\n\tconfig.App = append(config.App, serial.ToTypedMessage(&proxyman.InboundConfig{}))\n\tconfig.App = append(config.App, serial.ToTypedMessage(&proxyman.OutboundConfig{}))\n\treturn config\n}\n\nfunc testTCPConnViaSocks(socksPort, testPort net.Port, payloadSize int, timeout time.Duration) func() error { //nolint: unparam\n\treturn func() error {\n\t\tsocksDialer, err := proxy.SOCKS5(\"tcp\", \"127.0.0.1:\"+socksPort.String(), nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdestAddr := &net.TCPAddr{\n\t\t\tIP:   []byte{127, 0, 0, 1},\n\t\t\tPort: int(testPort),\n\t\t}\n\t\tconn, err := socksDialer.Dial(\"tcp\", destAddr.String())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer conn.Close()\n\n\t\treturn testTCPConn2(conn, payloadSize, timeout)()\n\t}\n}\n\nfunc testTCPConn(port net.Port, payloadSize int, timeout time.Duration) func() error {\n\treturn func() error {\n\t\tconn, err := net.DialTCP(\"tcp\", nil, &net.TCPAddr{\n\t\t\tIP:   []byte{127, 0, 0, 1},\n\t\t\tPort: int(port),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer conn.Close()\n\n\t\treturn testTCPConn2(conn, payloadSize, timeout)()\n\t}\n}\n\nfunc testUDPConn(port net.Port, payloadSize int, timeout time.Duration) func() error { // nolint: unparam\n\treturn func() error {\n\t\tconn, err := net.DialUDP(\"udp\", nil, &net.UDPAddr{\n\t\t\tIP:   []byte{127, 0, 0, 1},\n\t\t\tPort: int(port),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer conn.Close()\n\n\t\treturn testTCPConn2(conn, payloadSize, timeout)()\n\t}\n}\n\nfunc testTCPConn2(conn net.Conn, payloadSize int, timeout time.Duration) func() error {\n\treturn func() (err1 error) {\n\t\tstart := time.Now()\n\t\tdefer func() {\n\t\t\tvar m runtime.MemStats\n\t\t\truntime.ReadMemStats(&m)\n\t\t\t// For info on each, see: https://golang.org/pkg/runtime/#MemStats\n\t\t\tfmt.Println(\"testConn finishes:\", time.Since(start).Milliseconds(), \"ms\\t\",\n\t\t\t\terr1, \"\\tAlloc =\", units.ByteSize(m.Alloc).String(),\n\t\t\t\t\"\\tTotalAlloc =\", units.ByteSize(m.TotalAlloc).String(),\n\t\t\t\t\"\\tSys =\", units.ByteSize(m.Sys).String(),\n\t\t\t\t\"\\tNumGC =\", m.NumGC)\n\t\t}()\n\t\tpayload := make([]byte, payloadSize)\n\t\tcommon.Must2(rand.Read(payload))\n\n\t\tnBytes, err := conn.Write(payload)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif nBytes != len(payload) {\n\t\t\treturn errors.New(\"expect \", len(payload), \" written, but actually \", nBytes)\n\t\t}\n\n\t\tresponse, err := readFrom2(conn, timeout, payloadSize)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_ = response\n\n\t\tif r := bytes.Compare(response, xor(payload)); r != 0 {\n\t\t\treturn errors.New(r)\n\t\t}\n\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/common_coverage.go",
    "content": "//go:build coverage\n// +build coverage\n\npackage scenarios\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n)\n\nfunc BuildV2Ray() error {\n\tgenTestBinaryPath()\n\tif _, err := os.Stat(testBinaryPath); err == nil {\n\t\treturn nil\n\t}\n\n\tcmd := exec.Command(\"go\", \"test\", \"-tags\", \"coverage coveragemain\", \"-coverpkg\", \"github.com/v2fly/v2ray-core/v5/...\", \"-c\", \"-o\", testBinaryPath, GetSourcePath())\n\treturn cmd.Run()\n}\n\nfunc RunV2RayProtobuf(config []byte) *exec.Cmd {\n\tgenTestBinaryPath()\n\n\tcovDir := os.Getenv(\"V2RAY_COV\")\n\tos.MkdirAll(covDir, os.ModeDir)\n\trandomID := uuid.New()\n\tprofile := randomID.String() + \".out\"\n\tproc := exec.Command(testBinaryPath, \"run\", \"-format=pb\", \"-test.run\", \"TestRunMainForCoverage\", \"-test.coverprofile\", profile, \"-test.outputdir\", covDir)\n\tproc.Stdin = bytes.NewBuffer(config)\n\tproc.Stderr = os.Stderr\n\tproc.Stdout = os.Stdout\n\n\treturn proc\n}\n"
  },
  {
    "path": "testing/scenarios/common_instanceMgr.go",
    "content": "package scenarios\n\nimport (\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/instman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n)\n\nfunc NewInstanceManagerInstanceConfig() *core.Config {\n\tconfig := &core.Config{}\n\tconfig.App = append(config.App, serial.ToTypedMessage(&instman.Config{}))\n\treturn config\n}\n\nfunc NewInstanceManagerCoreInstance() (*core.Instance, extension.InstanceManagement) {\n\tcoreConfig := NewInstanceManagerInstanceConfig()\n\tinstance, err := core.New(coreConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tcommon.Must(instance.Start())\n\tinstanceMgr := instance.GetFeature(extension.InstanceManagementType())\n\tInstanceMgrIfce := instanceMgr.(extension.InstanceManagement)\n\treturn instance, InstanceMgrIfce\n}\n"
  },
  {
    "path": "testing/scenarios/common_instanceMgr_test.go",
    "content": "package scenarios\n\nimport \"testing\"\n\nfunc TestInstanceMgrInit(t *testing.T) {\n\tNewInstanceManagerCoreInstance()\n}\n"
  },
  {
    "path": "testing/scenarios/common_regular.go",
    "content": "//go:build !coverage\n// +build !coverage\n\npackage scenarios\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n)\n\nfunc BuildV2Ray() error {\n\tgenTestBinaryPath()\n\tif _, err := os.Stat(testBinaryPath); err == nil {\n\t\treturn nil\n\t}\n\n\tfmt.Printf(\"Building V2Ray into path (%s)\\n\", testBinaryPath)\n\tcmd := exec.Command(\"go\", \"build\", \"-o=\"+testBinaryPath, GetSourcePath())\n\treturn cmd.Run()\n}\n\nfunc RunV2RayProtobuf(config []byte) *exec.Cmd {\n\tgenTestBinaryPath()\n\tproc := exec.Command(testBinaryPath, \"run\", \"-format=pb\")\n\tproc.Stdin = bytes.NewBuffer(config)\n\tproc.Stderr = os.Stderr\n\tproc.Stdout = os.Stdout\n\n\treturn proc\n}\n"
  },
  {
    "path": "testing/scenarios/config/grpc_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17783,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"grpc\",\n        \"transportSettings\": {\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17784,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/grpc_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17783,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"grpc\",\n        \"transportSettings\": {\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/grpc_servicename_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17793,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"grpc\",\n        \"transportSettings\": {\n          \"serviceName\": \"0eae44595474\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17794,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/grpc_servicename_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17793,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"grpc\",\n        \"transportSettings\": {\n          \"serviceName\": \"0eae44595474\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/httpupgrade_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17793,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"httpupgrade\",\n        \"transportSettings\": {\n          \"path\": \"b66efc0c7752\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17794,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/httpupgrade_earlydataShortEarlyData_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17793,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"httpupgrade\",\n        \"transportSettings\": {\n          \"path\": \"b66efc0c7752\",\n          \"maxEarlyData\": 32,\n          \"earlyDataHeaderName\": \"Sec-Websocket-Key\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17794,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/httpupgrade_earlydataShortEarlyData_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17793,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"httpupgrade\",\n        \"transportSettings\": {\n          \"path\": \"b66efc0c7752\",\n          \"maxEarlyData\": 32,\n          \"earlyDataHeaderName\": \"Sec-Websocket-Key\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/httpupgrade_earlydata_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17793,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"httpupgrade\",\n        \"transportSettings\": {\n          \"path\": \"b66efc0c7752\",\n          \"maxEarlyData\": 2048,\n          \"earlyDataHeaderName\": \"Sec-Websocket-Key\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17794,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/httpupgrade_earlydata_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17793,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"httpupgrade\",\n        \"transportSettings\": {\n          \"path\": \"b66efc0c7752\",\n          \"maxEarlyData\": 2048,\n          \"earlyDataHeaderName\": \"Sec-Websocket-Key\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/httpupgrade_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17793,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"httpupgrade\",\n        \"transportSettings\": {\n          \"path\": \"b66efc0c7752\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/meek_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17773,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"meek\",\n        \"transportSettings\": {\n          \"url\": \"https://127.0.0.1:17773/mrss48bvxrkfq1qzeqte5o61mmvc9gx6hq51\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17774,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/meek_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17773,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"meek\",\n        \"transportSettings\": {\n          \"url\": \"http://127.0.0.1:12777\"\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/mekya_client.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"address\": \"127.0.0.1\",\n        \"port\": 17773,\n        \"uuid\": \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n      },\n      \"streamSettings\": {\n        \"transport\": \"mekya\",\n        \"transportSettings\": {\n          \"url\": \"https://127.0.0.1:17773/mrss48bvxrkfq1qzeqte5o61mmvc9gx6hq51\",\n          \"maxWriteDelay\": 80,\n          \"maxRequestSize\": 96000,\n          \"pollingIntervalInitial\": 200,\n          \"h2_pool_size\": 8,\n          \"kcp\": {\n            \"mtu\": {\n              \"value\": 1450\n            },\n            \"tti\": {\n              \"value\": 15\n            },\n            \"uplink_capacity\": {\n              \"value\": 40\n            },\n            \"downlink_capacity\": {\n              \"value\": 2000\n            },\n            \"congestion\": false,\n            \"write_buffer\": {\n              \"size\": 671088640\n            },\n            \"read_buffer\": {\n              \"size\": 671088640\n            }\n          }\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"pinnedPeerCertificateChainSha256\": [\n            \"kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug=\"\n          ],\n          \"allowInsecureIfPinnedPeerCertificate\": true\n        }\n      }\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"protocol\": \"socks\",\n      \"settings\": {\n        \"udpEnabled\": false,\n        \"address\": \"127.0.0.1\",\n        \"packetEncoding\": \"Packet\"\n      },\n      \"port\": 17774,\n      \"listen\": \"127.0.0.1\"\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/config/mekya_server.json",
    "content": "{\n  \"log\": {\n    \"error\": {\n      \"level\": \"Debug\",\n      \"type\": \"Console\"\n    },\n    \"access\": {\n      \"type\": \"None\"\n    }\n  },\n  \"outbounds\": [\n    {\n      \"protocol\": \"freedom\"\n    }\n  ],\n  \"inbounds\": [\n    {\n      \"listen\": \"127.0.0.1\",\n      \"port\": 17773,\n      \"protocol\": \"vmess\",\n      \"settings\": {\n        \"users\": [\n          \"bcc71618-e552-42c2-a2a3-d4c17a9df764\"\n        ]\n      },\n      \"streamSettings\": {\n        \"transport\": \"mekya\",\n        \"transportSettings\": {\n          \"url\": \"http://127.0.0.1:12777\",\n          \"maxWriteSize\": 10485760,\n          \"maxWriteDurationMs\": 5000,\n          \"maxSimultaneousWriteConnection\": 128,\n          \"packetWritingBuffer\": 65536,\n          \"kcp\": {\n            \"mtu\": {\n              \"value\": 1450\n            },\n            \"tti\": {\n              \"value\": 15\n            },\n            \"uplink_capacity\": {\n              \"value\": 40\n            },\n            \"downlink_capacity\": {\n              \"value\": 2000\n            },\n            \"congestion\": false,\n            \"write_buffer\": {\n              \"size\": 671088640\n            },\n            \"read_buffer\": {\n              \"size\": 671088640\n            }\n          }\n        },\n        \"security\": \"tls\",\n        \"securitySettings\": {\n          \"certificate\": [\n            {\n              \"usage\": \"ENCIPHERMENT\",\n              \"certificateFile\": \"cert/self-signed_cert.pem\",\n              \"keyFile\": \"cert/self-signed_key.pem\"\n            }\n          ]\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "testing/scenarios/dns_test.go",
    "content": "package scenarios\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\txproxy \"golang.org/x/net/proxy\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestResolveIP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dns.Config{\n\t\t\t\tHosts: map[string]*net.IPOrDomain{\n\t\t\t\t\t\"google.com\": net.NewIPOrDomain(dest.Address),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tDomainStrategy: router.DomainStrategy_IpIfNonMatch,\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tCidr: []*routercommon.CIDR{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tIp:     []byte{127, 0, 0, 0},\n\t\t\t\t\t\t\t\tPrefix: 8,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType: socks.AuthType_NO_AUTH,\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"Test Account\": \"Test Password\",\n\t\t\t\t\t},\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: false,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"direct\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{\n\t\t\t\t\tDomainStrategy: freedom.Config_USE_IP,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\tnoAuthDialer, err := xproxy.SOCKS5(\"tcp\", net.TCPDestination(net.LocalHostIP, serverPort).NetAddr(), nil, xproxy.Direct)\n\t\tcommon.Must(err)\n\t\tconn, err := noAuthDialer.Dial(\"tcp\", fmt.Sprintf(\"google.com:%d\", dest.Port))\n\t\tcommon.Must(err)\n\t\tdefer conn.Close()\n\n\t\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/dokodemo_test.go",
    "content": "package scenarios\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\nfunc TestDokodemoTCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := uint32(tcp.PickPort())\n\tclientPortRange := uint32(5)\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: &net.PortRange{From: clientPort, To: clientPort + clientPortRange},\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tfor port := clientPort; port <= clientPort+clientPortRange; port++ {\n\t\tif err := testTCPConn(net.Port(port), 1024, time.Second*2)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n\nfunc TestDokodemoUDP(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := uint32(udp.PickPort())\n\tclientPortRange := uint32(5)\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: &net.PortRange{From: clientPort, To: clientPort + clientPortRange},\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor port := clientPort; port <= clientPort+clientPortRange; port++ {\n\t\terrg.Go(testUDPConn(net.Port(port), 1024, time.Second*5))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/feature_test.go",
    "content": "package scenarios\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\txproxy \"golang.org/x/net/proxy\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/inbound\"\n\t_ \"github.com/v2fly/v2ray-core/v5/app/proxyman/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\tv2http \"github.com/v2fly/v2ray-core/v5/proxy/http\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc TestPassiveConnection(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t\tSendFirst:    []byte(\"send first\"),\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tconn, err := net.DialTCP(\"tcp\", nil, &net.TCPAddr{\n\t\tIP:   []byte{127, 0, 0, 1},\n\t\tPort: int(serverPort),\n\t})\n\tcommon.Must(err)\n\n\t{\n\t\tresponse := make([]byte, 1024)\n\t\tnBytes, err := conn.Read(response)\n\t\tcommon.Must(err)\n\t\tif string(response[:nBytes]) != \"send first\" {\n\t\t\tt.Error(\"unexpected first response: \", string(response[:nBytes]))\n\t\t}\n\t}\n\n\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestProxy(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverUserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: serverUserID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tproxyUserID := protocol.NewID(uuid.New())\n\tproxyPort := tcp.PickPort()\n\tproxyConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(proxyPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: proxyUserID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: serverUserID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tProxySettings: &internet.ProxyConfig{\n\t\t\t\t\t\tTag: \"proxy\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"proxy\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(proxyPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: proxyUserID.String(),\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, proxyConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestProxyOverKCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverUserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: serverUserID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tproxyUserID := protocol.NewID(uuid.New())\n\tproxyPort := tcp.PickPort()\n\tproxyConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(proxyPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: proxyUserID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: serverUserID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tProxySettings: &internet.ProxyConfig{\n\t\t\t\t\t\tTag: \"proxy\",\n\t\t\t\t\t},\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"proxy\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(proxyPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: proxyUserID.String(),\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, proxyConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestBlackhole(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\ttcpServer2 := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest2, err := tcpServer2.Start()\n\tcommon.Must(err)\n\tdefer tcpServer2.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverPort2 := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort2),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest2.Address),\n\t\t\t\t\tPort:    uint32(dest2.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag:           \"direct\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag:           \"blocked\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t},\n\t\t},\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"blocked\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tPortRange: net.SinglePortRange(dest2.Port),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(serverPort2, 1024, time.Second*5)(); err == nil {\n\t\tt.Error(\"nil error\")\n\t}\n}\n\nfunc TestForward(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType: socks.AuthType_NO_AUTH,\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"Test Account\": \"Test Password\",\n\t\t\t\t\t},\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: false,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{\n\t\t\t\t\tDestinationOverride: &freedom.DestinationOverride{\n\t\t\t\t\t\tServer: &protocol.ServerEndpoint{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(dest.Port),\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\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\tnoAuthDialer, err := xproxy.SOCKS5(\"tcp\", net.TCPDestination(net.LocalHostIP, serverPort).NetAddr(), nil, xproxy.Direct)\n\t\tcommon.Must(err)\n\t\tconn, err := noAuthDialer.Dial(\"tcp\", \"google.com:80\")\n\t\tcommon.Must(err)\n\t\tdefer conn.Close()\n\n\t\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n\nfunc TestUDPConnection(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tclientPort := udp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n\n\ttime.Sleep(20 * time.Second)\n\n\tif err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestDomainSniffing(t *testing.T) {\n\tsniffingPort := tcp.PickPort()\n\thttpPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"snif\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(sniffingPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tDomainOverride: []proxyman.KnownProtocols{\n\t\t\t\t\t\tproxyman.KnownProtocols_TLS,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tPort:    443,\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"http\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(httpPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"redir\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{\n\t\t\t\t\tDestinationOverride: &freedom.DestinationOverride{\n\t\t\t\t\t\tServer: &protocol.ServerEndpoint{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(sniffingPort),\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{\n\t\t\t\tTag:           \"direct\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"direct\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tInboundTag: []string{\"snif\"},\n\t\t\t\t\t}, {\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"redir\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tInboundTag: []string{\"http\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\ttransport := &http.Transport{\n\t\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\t\treturn url.Parse(\"http://127.0.0.1:\" + httpPort.String())\n\t\t\t},\n\t\t}\n\n\t\tclient := &http.Client{\n\t\t\tTransport: transport,\n\t\t}\n\n\t\tresp, err := client.Get(\"https://www.github.com/\")\n\t\tcommon.Must(err)\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode != 200 {\n\t\t\tt.Error(\"unexpected status code: \", resp.StatusCode)\n\t\t}\n\t\tcommon.Must(resp.Write(io.Discard))\n\t}\n}\n\nfunc TestDialV2Ray(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tclient, err := core.New(clientConfig)\n\tcommon.Must(err)\n\n\tconn, err := core.Dial(context.Background(), client, dest)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/grpc_test.go",
    "content": "package scenarios\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n)\n\nfunc TestGRPCDefault(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"grpc_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/grpc_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"grpc_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/grpc_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"grpc_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"grpc_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"grpc_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"grpc_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"grpc_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"grpc_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17784, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestGRPCWithServiceName(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"grpc_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/grpc_servicename_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"grpc_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/grpc_servicename_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"grpc_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"grpc_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"grpc_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"grpc_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"grpc_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"grpc_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17794, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/http_test.go",
    "content": "package scenarios\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\tv2http \"github.com/v2fly/v2ray-core/v5/proxy/http\"\n\tv2httptest \"github.com/v2fly/v2ray-core/v5/testing/servers/http\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestHttpConformance(t *testing.T) {\n\thttpServerPort := tcp.PickPort()\n\thttpServer := &v2httptest.Server{\n\t\tPort:        httpServerPort,\n\t\tPathHandler: make(map[string]http.HandlerFunc),\n\t}\n\t_, err := httpServer.Start()\n\tcommon.Must(err)\n\tdefer httpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\ttransport := &http.Transport{\n\t\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\t\treturn url.Parse(\"http://127.0.0.1:\" + serverPort.String())\n\t\t\t},\n\t\t}\n\n\t\tclient := &http.Client{\n\t\t\tTransport: transport,\n\t\t}\n\n\t\tresp, err := client.Get(\"http://127.0.0.1:\" + httpServerPort.String())\n\t\tcommon.Must(err)\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode != 200 {\n\t\t\tt.Fatal(\"status: \", resp.StatusCode)\n\t\t}\n\n\t\tcontent, err := io.ReadAll(resp.Body)\n\t\tcommon.Must(err)\n\t\tif string(content) != \"Home\" {\n\t\t\tt.Fatal(\"body: \", string(content))\n\t\t}\n\t}\n}\n\nfunc TestHttpError(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: func(msg []byte) []byte {\n\t\t\treturn []byte{}\n\t\t},\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\ttime.AfterFunc(time.Second*2, func() {\n\t\ttcpServer.ShouldClose = true\n\t})\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\ttransport := &http.Transport{\n\t\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\t\treturn url.Parse(\"http://127.0.0.1:\" + serverPort.String())\n\t\t\t},\n\t\t}\n\n\t\tclient := &http.Client{\n\t\t\tTransport: transport,\n\t\t}\n\n\t\tresp, err := client.Get(\"http://127.0.0.1:\" + dest.Port.String())\n\t\tcommon.Must(err)\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode != 503 {\n\t\t\tt.Error(\"status: \", resp.StatusCode)\n\t\t}\n\t}\n}\n\nfunc TestHTTPConnectMethod(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\ttransport := &http.Transport{\n\t\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\t\treturn url.Parse(\"http://127.0.0.1:\" + serverPort.String())\n\t\t\t},\n\t\t}\n\n\t\tclient := &http.Client{\n\t\t\tTransport: transport,\n\t\t}\n\n\t\tpayload := make([]byte, 1024*64)\n\t\tcommon.Must2(rand.Read(payload))\n\n\t\tctx := context.Background()\n\t\treq, err := http.NewRequestWithContext(ctx, \"Connect\", \"http://\"+dest.NetAddr()+\"/\", bytes.NewReader(payload))\n\t\treq.Header.Set(\"X-a\", \"b\")\n\t\treq.Header.Set(\"X-b\", \"d\")\n\t\tcommon.Must(err)\n\n\t\tresp, err := client.Do(req)\n\t\tcommon.Must(err)\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode != 200 {\n\t\t\tt.Fatal(\"status: \", resp.StatusCode)\n\t\t}\n\n\t\tcontent := make([]byte, len(payload))\n\t\tcommon.Must2(io.ReadFull(resp.Body, content))\n\t\tif r := cmp.Diff(content, xor(payload)); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n}\n\nfunc TestHttpPost(t *testing.T) {\n\thttpServerPort := tcp.PickPort()\n\thttpServer := &v2httptest.Server{\n\t\tPort: httpServerPort,\n\t\tPathHandler: map[string]http.HandlerFunc{\n\t\t\t\"/testpost\": func(w http.ResponseWriter, r *http.Request) {\n\t\t\t\tpayload, err := buf.ReadAllToBytes(r.Body)\n\t\t\t\tr.Body.Close()\n\n\t\t\t\tif err != nil {\n\t\t\t\t\tw.WriteHeader(500)\n\t\t\t\t\tw.Write([]byte(\"Unable to read all payload\"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tpayload = xor(payload)\n\t\t\t\tw.Write(payload)\n\t\t\t},\n\t\t},\n\t}\n\n\t_, err := httpServer.Start()\n\tcommon.Must(err)\n\tdefer httpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\ttransport := &http.Transport{\n\t\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\t\treturn url.Parse(\"http://127.0.0.1:\" + serverPort.String())\n\t\t\t},\n\t\t}\n\n\t\tclient := &http.Client{\n\t\t\tTransport: transport,\n\t\t}\n\n\t\tpayload := make([]byte, 1024*64)\n\t\tcommon.Must2(rand.Read(payload))\n\n\t\tresp, err := client.Post(\"http://127.0.0.1:\"+httpServerPort.String()+\"/testpost\", \"application/x-www-form-urlencoded\", bytes.NewReader(payload))\n\t\tcommon.Must(err)\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode != 200 {\n\t\t\tt.Fatal(\"status: \", resp.StatusCode)\n\t\t}\n\n\t\tcontent, err := io.ReadAll(resp.Body)\n\t\tcommon.Must(err)\n\t\tif r := cmp.Diff(content, xor(payload)); r != \"\" {\n\t\t\tt.Fatal(r)\n\t\t}\n\t}\n}\n\nfunc setProxyBasicAuth(req *http.Request, user, pass string) {\n\treq.SetBasicAuth(user, pass)\n\treq.Header.Set(\"Proxy-Authorization\", req.Header.Get(\"Authorization\"))\n\treq.Header.Del(\"Authorization\")\n}\n\nfunc TestHttpBasicAuth(t *testing.T) {\n\thttpServerPort := tcp.PickPort()\n\thttpServer := &v2httptest.Server{\n\t\tPort:        httpServerPort,\n\t\tPathHandler: make(map[string]http.HandlerFunc),\n\t}\n\t_, err := httpServer.Start()\n\tcommon.Must(err)\n\tdefer httpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&v2http.ServerConfig{\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"a\": \"b\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\ttransport := &http.Transport{\n\t\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\t\treturn url.Parse(\"http://127.0.0.1:\" + serverPort.String())\n\t\t\t},\n\t\t}\n\n\t\tclient := &http.Client{\n\t\t\tTransport: transport,\n\t\t}\n\n\t\t{\n\t\t\tresp, err := client.Get(\"http://127.0.0.1:\" + httpServerPort.String())\n\t\t\tcommon.Must(err)\n\t\t\tdefer resp.Body.Close()\n\t\t\tif resp.StatusCode != 407 {\n\t\t\t\tt.Fatal(\"status: \", resp.StatusCode)\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tctx := context.Background()\n\t\t\treq, err := http.NewRequestWithContext(ctx, \"GET\", \"http://127.0.0.1:\"+httpServerPort.String(), nil)\n\t\t\tcommon.Must(err)\n\n\t\t\tsetProxyBasicAuth(req, \"a\", \"c\")\n\t\t\tresp, err := client.Do(req)\n\t\t\tcommon.Must(err)\n\t\t\tdefer resp.Body.Close()\n\t\t\tif resp.StatusCode != 407 {\n\t\t\t\tt.Fatal(\"status: \", resp.StatusCode)\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tctx := context.Background()\n\t\t\treq, err := http.NewRequestWithContext(ctx, \"GET\", \"http://127.0.0.1:\"+httpServerPort.String(), nil)\n\t\t\tcommon.Must(err)\n\n\t\t\tsetProxyBasicAuth(req, \"a\", \"b\")\n\t\t\tresp, err := client.Do(req)\n\t\t\tcommon.Must(err)\n\t\t\tdefer resp.Body.Close()\n\t\t\tif resp.StatusCode != 200 {\n\t\t\t\tt.Fatal(\"status: \", resp.StatusCode)\n\t\t\t}\n\n\t\t\tcontent, err := io.ReadAll(resp.Body)\n\t\t\tcommon.Must(err)\n\t\t\tif string(content) != \"Home\" {\n\t\t\t\tt.Fatal(\"body: \", string(content))\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/httpupgrade_test.go",
    "content": "package scenarios\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n)\n\nfunc TestHTTPUpgrade(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"httpupgrade_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/httpupgrade_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"httpupgrade_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/httpupgrade_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"httpupgrade_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"httpupgrade_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"httpupgrade_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"httpupgrade_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"httpupgrade_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"httpupgrade_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17794, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestHTTPUpgradeWithEarlyData(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"httpupgrade_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/httpupgrade_earlydata_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"httpupgrade_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/httpupgrade_earlydata_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"httpupgrade_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"httpupgrade_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"httpupgrade_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"httpupgrade_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"httpupgrade_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"httpupgrade_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17794, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestHTTPUpgradeWithShortEarlyData(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"httpupgrade_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/httpupgrade_earlydataShortEarlyData_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"httpupgrade_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/httpupgrade_earlydataShortEarlyData_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"httpupgrade_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"httpupgrade_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"httpupgrade_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"httpupgrade_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"httpupgrade_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"httpupgrade_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17794, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/hy2_test.go",
    "content": "package scenarios\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/hysteria2\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\thyTransport \"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n\ttcpTransport \"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc TestVMessHysteria2Congestion(t *testing.T) {\n\tfor _, v := range []string{\"bbr\", \"brutal\"} {\n\t\ttestVMessHysteria2(t, v)\n\t}\n}\n\nfunc testVMessHysteria2(t *testing.T, congestionType string) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(\n\t\t\t\t\t\t\t\t&tls.Config{\n\t\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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},\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&hyTransport.Config{\n\t\t\t\t\t\t\t\t\tCongestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100},\n\t\t\t\t\t\t\t\t\tPassword:   \"password\",\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(\n\t\t\t\t\t\t\t\t&tls.Config{\n\t\t\t\t\t\t\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&hyTransport.Config{\n\t\t\t\t\t\t\t\t\tCongestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100},\n\t\t\t\t\t\t\t\t\tPassword:   \"password\",\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\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_NONE,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestHysteria2Offical(t *testing.T) {\n\tfor _, v := range []bool{true, false} {\n\t\ttestHysteria2Offical(t, v)\n\t}\n}\n\nfunc testHysteria2Offical(t *testing.T, isUDP bool) {\n\tvar dest net.Destination\n\tvar err error\n\tif isUDP {\n\t\tudpServer := udp.Server{\n\t\t\tMsgProcessor: xor,\n\t\t}\n\t\tdest, err = udpServer.Start()\n\t\tcommon.Must(err)\n\t\tdefer udpServer.Close()\n\t} else {\n\t\ttcpServer := tcp.Server{\n\t\t\tMsgProcessor: xor,\n\t\t}\n\t\tdest, err = tcpServer.Start()\n\t\tcommon.Must(err)\n\t\tdefer tcpServer.Close()\n\t}\n\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(\n\t\t\t\t\t\t\t\t&tls.Config{\n\t\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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},\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&hyTransport.Config{\n\t\t\t\t\t\t\t\t\tCongestion:      &hyTransport.Congestion{Type: \"brutal\", UpMbps: 100, DownMbps: 100},\n\t\t\t\t\t\t\t\t\tUseUdpExtension: true,\n\t\t\t\t\t\t\t\t\tPassword:        \"password\",\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\tProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP, net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(\n\t\t\t\t\t\t\t\t&tls.Config{\n\t\t\t\t\t\t\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocolName: \"hysteria2\",\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&hyTransport.Config{\n\t\t\t\t\t\t\t\t\tCongestion:      &hyTransport.Congestion{Type: \"brutal\", UpMbps: 100, DownMbps: 100},\n\t\t\t\t\t\t\t\t\tUseUdpExtension: true,\n\t\t\t\t\t\t\t\t\tPassword:        \"password\",\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\tProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&hysteria2.Account{}),\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\tif isUDP {\n\t\t\terrg.Go(testUDPConn(clientPort, 1500, time.Second*4))\n\t\t} else {\n\t\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t\t}\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestHysteria2OnTCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(\n\t\t\t\t\t\t\t\t&tls.Config{\n\t\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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},\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_TCP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&tcpTransport.Config{\n\t\t\t\t\t\t\t\t\tHeaderSettings: serial.ToTypedMessage(&http.Config{}),\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\tProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(\n\t\t\t\t\t\t\t\t&tls.Config{\n\t\t\t\t\t\t\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_TCP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&tcpTransport.Config{\n\t\t\t\t\t\t\t\t\tHeaderSettings: serial.ToTypedMessage(&http.Config{}),\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\tProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&hysteria2.Account{}),\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 1; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/meek_test.go",
    "content": "package scenarios\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n)\n\nfunc TestMeek(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"meek_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/meek_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"meek_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/meek_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"meek_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"meek_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"meek_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"meek_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"meek_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"meek_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17774, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/mekya_test.go",
    "content": "package scenarios\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n)\n\nfunc TestMekya(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcoreInst, InstMgrIfce := NewInstanceManagerCoreInstance()\n\tdefer coreInst.Close()\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"mekya_client\",\n\t\tcommon.Must2(os.ReadFile(\"config/mekya_client.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.AddInstance(\n\t\tcontext.TODO(),\n\t\t\"mekya_server\",\n\t\tcommon.Must2(os.ReadFile(\"config/mekya_server.json\")).([]byte),\n\t\t\"jsonv5\"))\n\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"mekya_server\"))\n\tcommon.Must(InstMgrIfce.StartInstance(context.TODO(), \"mekya_client\"))\n\n\tdefer func() {\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"mekya_server\"))\n\t\tcommon.Must(InstMgrIfce.StopInstance(context.TODO(), \"mekya_client\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"mekya_server\"))\n\t\tcommon.Must(InstMgrIfce.UntrackInstance(context.TODO(), \"mekya_client\"))\n\t\tcoreInst.Close()\n\t}()\n\n\tif err := testTCPConnViaSocks(17774, dest.Port, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/policy_test.go",
    "content": "package scenarios\n\nimport (\n\t\"io\"\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc startQuickClosingTCPServer() (net.Listener, error) {\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := listener.Accept()\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tb := make([]byte, 1024)\n\t\t\tconn.Read(b)\n\t\t\tconn.Close()\n\t\t}\n\t}()\n\treturn listener, nil\n}\n\nfunc TestVMessClosing(t *testing.T) {\n\ttcpServer, err := startQuickClosingTCPServer()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tdest := net.DestinationFromAddr(tcpServer.Addr())\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*2)(); err != io.EOF {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestZeroBuffer(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tBuffer: &policy.Policy_Buffer{\n\t\t\t\t\t\t\tConnection: 0,\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*20))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/reverse_test.go",
    "content": "package scenarios\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/reverse\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router/routercommon\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestReverseProxy(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\texternalPort := tcp.PickPort()\n\treversePort := tcp.PickPort()\n\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&reverse.Config{\n\t\t\t\tPortalConfig: []*reverse.PortalConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tTag:    \"portal\",\n\t\t\t\t\t\tDomain: \"test.v2fly.org\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{Type: routercommon.Domain_Full, Value: \"test.v2fly.org\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"portal\",\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\tInboundTag: []string{\"external\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"portal\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"external\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(externalPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(reversePort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&reverse.Config{\n\t\t\t\tBridgeConfig: []*reverse.BridgeConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tTag:    \"bridge\",\n\t\t\t\t\t\tDomain: \"test.v2fly.org\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{Type: routercommon.Domain_Full, Value: \"test.v2fly.org\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"reverse\",\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\tInboundTag: []string{\"bridge\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"freedom\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag:           \"freedom\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"reverse\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(reversePort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 32; i++ {\n\t\terrg.Go(testTCPConn(externalPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestReverseProxyLongRunning(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\texternalPort := tcp.PickPort()\n\treversePort := tcp.PickPort()\n\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\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\tserial.ToTypedMessage(&reverse.Config{\n\t\t\t\tPortalConfig: []*reverse.PortalConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tTag:    \"portal\",\n\t\t\t\t\t\tDomain: \"test.v2fly.org\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{Type: routercommon.Domain_Full, Value: \"test.v2fly.org\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"portal\",\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\tInboundTag: []string{\"external\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"portal\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"external\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(externalPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(reversePort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&policy.Config{\n\t\t\t\tLevel: map[uint32]*policy.Policy{\n\t\t\t\t\t0: {\n\t\t\t\t\t\tTimeout: &policy.Policy_Timeout{\n\t\t\t\t\t\t\tUplinkOnly:   &policy.Second{Value: 0},\n\t\t\t\t\t\t\tDownlinkOnly: &policy.Second{Value: 0},\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\tserial.ToTypedMessage(&reverse.Config{\n\t\t\t\tBridgeConfig: []*reverse.BridgeConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tTag:    \"bridge\",\n\t\t\t\t\t\tDomain: \"test.v2fly.org\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tDomain: []*routercommon.Domain{\n\t\t\t\t\t\t\t{Type: routercommon.Domain_Full, Value: \"test.v2fly.org\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"reverse\",\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\tInboundTag: []string{\"bridge\"},\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"freedom\",\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\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag:           \"freedom\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag: \"reverse\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(reversePort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\n\tdefer CloseAllServers(servers)\n\n\tfor i := 0; i < 4096; i++ {\n\t\tif err := testTCPConn(externalPort, 1024, time.Second*20)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/shadowsocks_test.go",
    "content": "package scenarios\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/shadowsocks\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\nfunc TestShadowsocksChaCha20Poly1305TCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\taccount := serial.ToTypedMessage(&shadowsocks.Account{\n\t\tPassword:   \"shadowsocks-password\",\n\t\tCipherType: shadowsocks.CipherType_CHACHA20_POLY1305,\n\t})\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{\n\t\t\t\t\tUser: &protocol.User{\n\t\t\t\t\t\tAccount: account,\n\t\t\t\t\t\tLevel:   1,\n\t\t\t\t\t},\n\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: account,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errGroup errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20))\n\t}\n\tif err := errGroup.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestShadowsocksAES256GCMTCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\taccount := serial.ToTypedMessage(&shadowsocks.Account{\n\t\tPassword:   \"shadowsocks-password\",\n\t\tCipherType: shadowsocks.CipherType_AES_256_GCM,\n\t})\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{\n\t\t\t\t\tUser: &protocol.User{\n\t\t\t\t\t\tAccount: account,\n\t\t\t\t\t\tLevel:   1,\n\t\t\t\t\t},\n\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: account,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errGroup errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20))\n\t}\n\n\tif err := errGroup.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestShadowsocksAES128GCMUDP(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\taccount := serial.ToTypedMessage(&shadowsocks.Account{\n\t\tPassword:   \"shadowsocks-password\",\n\t\tCipherType: shadowsocks.CipherType_AES_128_GCM,\n\t})\n\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{\n\t\t\t\t\tUser: &protocol.User{\n\t\t\t\t\t\tAccount: account,\n\t\t\t\t\t\tLevel:   1,\n\t\t\t\t\t},\n\t\t\t\t\tNetwork: []net.Network{net.Network_UDP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := udp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_UDP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: account,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errGroup errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrGroup.Go(testUDPConn(clientPort, 1024, time.Second*5))\n\t}\n\tif err := errGroup.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestShadowsocksAES128GCMUDPMux(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\taccount := serial.ToTypedMessage(&shadowsocks.Account{\n\t\tPassword:   \"shadowsocks-password\",\n\t\tCipherType: shadowsocks.CipherType_AES_128_GCM,\n\t})\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{\n\t\t\t\t\tUser: &protocol.User{\n\t\t\t\t\t\tAccount: account,\n\t\t\t\t\t\tLevel:   1,\n\t\t\t\t\t},\n\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := udp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_UDP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tMultiplexSettings: &proxyman.MultiplexingConfig{\n\t\t\t\t\t\tEnabled:     true,\n\t\t\t\t\t\tConcurrency: 8,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: account,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errGroup errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrGroup.Go(testUDPConn(clientPort, 1024, time.Second*5))\n\t}\n\tif err := errGroup.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestShadowsocksNone(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\n\tdefer tcpServer.Close()\n\n\taccount := serial.ToTypedMessage(&shadowsocks.Account{\n\t\tPassword:   \"shadowsocks-password\",\n\t\tCipherType: shadowsocks.CipherType_NONE,\n\t})\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ServerConfig{\n\t\t\t\t\tUser: &protocol.User{\n\t\t\t\t\t\tAccount: account,\n\t\t\t\t\t\tLevel:   1,\n\t\t\t\t\t},\n\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress:  net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:     uint32(dest.Port),\n\t\t\t\t\tNetworks: []net.Network{net.Network_TCP},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&shadowsocks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: account,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\n\tdefer CloseAllServers(servers)\n\n\tvar errGroup errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrGroup.Go(testTCPConn(clientPort, 10240*1024, time.Second*20))\n\t}\n\n\tif err := errGroup.Wait(); err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/socks_test.go",
    "content": "package scenarios\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\txproxy \"golang.org/x/net/proxy\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\tsocks4 \"h12.io/socks\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/app/router\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/blackhole\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/socks\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n)\n\nfunc TestSocksBridgeTCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType: socks.AuthType_PASSWORD,\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"Test Account\": \"Test Password\",\n\t\t\t\t\t},\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: false,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&socks.Account{\n\t\t\t\t\t\t\t\t\t\tUsername: \"Test Account\",\n\t\t\t\t\t\t\t\t\t\tPassword: \"Test Password\",\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestSocksBridageUDP(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType: socks.AuthType_PASSWORD,\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"Test Account\": \"Test Password\",\n\t\t\t\t\t},\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: true,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP, net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&socks.Account{\n\t\t\t\t\t\t\t\t\t\tUsername: \"Test Account\",\n\t\t\t\t\t\t\t\t\t\tPassword: \"Test Password\",\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestSocksBridageUDPWithRouting(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&router.Config{\n\t\t\t\tRule: []*router.RoutingRule{\n\t\t\t\t\t{\n\t\t\t\t\t\tTargetTag: &router.RoutingRule_Tag{\n\t\t\t\t\t\t\tTag: \"out\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tInboundTag: []string{\"socks\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tTag: \"socks\",\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType:   socks.AuthType_NO_AUTH,\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: true,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&blackhole.Config{}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tTag:           \"out\",\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP, net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ClientConfig{\n\t\t\t\t\tServer: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testUDPConn(clientPort, 1024, time.Second*5)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestSocksConformanceMod(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tauthPort := tcp.PickPort()\n\tnoAuthPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(authPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType: socks.AuthType_PASSWORD,\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"Test Account\": \"Test Password\",\n\t\t\t\t\t},\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: false,\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(noAuthPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&socks.ServerConfig{\n\t\t\t\t\tAuthType: socks.AuthType_NO_AUTH,\n\t\t\t\t\tAccounts: map[string]string{\n\t\t\t\t\t\t\"Test Account\": \"Test Password\",\n\t\t\t\t\t},\n\t\t\t\t\tAddress:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tUdpEnabled: false,\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\t{\n\t\tnoAuthDialer, err := xproxy.SOCKS5(\"tcp\", net.TCPDestination(net.LocalHostIP, noAuthPort).NetAddr(), nil, xproxy.Direct)\n\t\tcommon.Must(err)\n\t\tconn, err := noAuthDialer.Dial(\"tcp\", dest.NetAddr())\n\t\tcommon.Must(err)\n\t\tdefer conn.Close()\n\n\t\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n\n\t{\n\t\tauthDialer, err := xproxy.SOCKS5(\"tcp\", net.TCPDestination(net.LocalHostIP, authPort).NetAddr(), &xproxy.Auth{User: \"Test Account\", Password: \"Test Password\"}, xproxy.Direct)\n\t\tcommon.Must(err)\n\t\tconn, err := authDialer.Dial(\"tcp\", dest.NetAddr())\n\t\tcommon.Must(err)\n\t\tdefer conn.Close()\n\n\t\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n\n\t{\n\t\tdialer := socks4.Dial(\"socks4://\" + net.TCPDestination(net.LocalHostIP, noAuthPort).NetAddr())\n\t\tconn, err := dialer(\"tcp\", dest.NetAddr())\n\t\tcommon.Must(err)\n\t\tdefer conn.Close()\n\n\t\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n\n\t{\n\t\tdialer := socks4.Dial(\"socks4://\" + net.TCPDestination(net.LocalHostIP, noAuthPort).NetAddr())\n\t\tconn, err := dialer(\"tcp\", net.TCPDestination(net.LocalHostIP, tcpServer.Port).NetAddr())\n\t\tcommon.Must(err)\n\t\tdefer conn.Close()\n\n\t\tif err := testTCPConn2(conn, 1024, time.Second*5)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/tls_test.go",
    "content": "package scenarios\n\nimport (\n\t\"crypto/x509\"\n\t\"runtime\"\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\"\n)\n\nfunc TestSimpleTLSConnection(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestAutoIssuingCertificate(t *testing.T) {\n\tif runtime.GOOS == \"windows\" {\n\t\t// Not supported on Windows yet.\n\t\treturn\n\t}\n\n\tif runtime.GOARCH == \"arm64\" {\n\t\treturn\n\t}\n\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcaCert, err := cert.Generate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment|x509.KeyUsageCertSign))\n\tcommon.Must(err)\n\tcertPEM, keyPEM := caCert.ToPEM()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{{\n\t\t\t\t\t\t\t\t\tCertificate: certPEM,\n\t\t\t\t\t\t\t\t\tKey:         keyPEM,\n\t\t\t\t\t\t\t\t\tUsage:       tls.Certificate_AUTHORITY_ISSUE,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tServerName: \"v2fly.org\",\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{{\n\t\t\t\t\t\t\t\t\tCertificate: certPEM,\n\t\t\t\t\t\t\t\t\tUsage:       tls.Certificate_AUTHORITY_VERIFY,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tfor i := 0; i < 10; i++ {\n\t\tif err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n\nfunc TestIPAddressesCertificate(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcaCert, err := cert.Generate(nil, cert.IPAddresses(net.LocalHostIP.IP()), cert.Authority(true), cert.KeyUsage(x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment|x509.KeyUsageCertSign))\n\tcommon.Must(err)\n\tcertPEM, keyPEM := caCert.ToPEM()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{{\n\t\t\t\t\t\t\t\t\tCertificate: certPEM,\n\t\t\t\t\t\t\t\t\tKey:         keyPEM,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tDisableSystemRoot: true,\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{{\n\t\t\t\t\t\t\t\t\tCertificate: certPEM,\n\t\t\t\t\t\t\t\t\tUsage:       tls.Certificate_AUTHORITY_VERIFY,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tfor i := 0; i < 10; i++ {\n\t\tif err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n\nfunc TestDNSNamesCertificate(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tcaCert, err := cert.Generate(nil, cert.DNSNames(\"v2fly.org\"), cert.Authority(true), cert.KeyUsage(x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment|x509.KeyUsageCertSign))\n\tcommon.Must(err)\n\tcertPEM, keyPEM := caCert.ToPEM()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{{\n\t\t\t\t\t\t\t\t\tCertificate: certPEM,\n\t\t\t\t\t\t\t\t\tKey:         keyPEM,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tDisableSystemRoot: true,\n\t\t\t\t\t\t\t\tServerName:        \"v2fly.org\",\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{{\n\t\t\t\t\t\t\t\t\tCertificate: certPEM,\n\t\t\t\t\t\t\t\t\tUsage:       tls.Certificate_AUTHORITY_VERIFY,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tfor i := 0; i < 10; i++ {\n\t\tif err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n\nfunc TestTLSOverKCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol:     internet.TransportProtocol_MKCP,\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol:     internet.TransportProtocol_MKCP,\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestTLSOverWebSocket(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol:     internet.TransportProtocol_WebSocket,\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_WebSocket,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_WebSocket,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&websocket.Config{}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*20))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestHTTP2(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_HTTP,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_HTTP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\tHost: []string{\"v2fly.org\"},\n\t\t\t\t\t\t\t\t\tPath: \"/testpath\",\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\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(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\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_HTTP,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_HTTP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&http.Config{\n\t\t\t\t\t\t\t\t\tHost: []string{\"v2fly.org\"},\n\t\t\t\t\t\t\t\t\tPath: \"/testpath\",\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\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tAllowInsecure: true,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 7168*1024, time.Second*40))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestSimpleTLSConnectionPinned(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\tcertificateDer := cert.MustGenerate(nil)\n\tcertificate := tls.ParseCertificate(certificateDer)\n\tcertHash := tls.GenerateCertChainHash([][]byte{certificateDer.Certificate})\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tCertificate: []*tls.Certificate{certificate},\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tSecurityType: serial.GetMessageType(&tls.Config{}),\n\t\t\t\t\t\tSecuritySettings: []*anypb.Any{\n\t\t\t\t\t\t\tserial.ToTypedMessage(&tls.Config{\n\t\t\t\t\t\t\t\tAllowInsecure:                    true,\n\t\t\t\t\t\t\t\tPinnedPeerCertificateChainSha256: [][]byte{certHash},\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/transport_test.go",
    "content": "package scenarios\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"testing\"\n\t\"time\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/quic\"\n\ttcptransport \"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n)\n\nfunc TestHTTPConnectionHeader(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_TCP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&tcptransport.Config{\n\t\t\t\t\t\t\t\t\tHeaderSettings: serial.ToTypedMessage(&http.Config{}),\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_TCP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&tcptransport.Config{\n\t\t\t\t\t\t\t\t\tHeaderSettings: serial.ToTypedMessage(&http.Config{}),\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestDomainSocket(t *testing.T) {\n\tif runtime.GOOS == \"windows\" || runtime.GOOS == \"android\" {\n\t\tt.Skip(\"Not supported on windows and android\")\n\t\treturn\n\t}\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tconst dsPath = \"/tmp/ds_scenario\"\n\tos.Remove(dsPath)\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_DomainSocket,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_DomainSocket,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&domainsocket.Config{\n\t\t\t\t\t\t\t\t\tPath: dsPath,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId: userID.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\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_DomainSocket,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_DomainSocket,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&domainsocket.Config{\n\t\t\t\t\t\t\t\t\tPath: dsPath,\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\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tif err := testTCPConn(clientPort, 1024, time.Second*2)(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessQuic(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocolName: \"quic\",\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocolName: \"quic\",\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&quic.Config{\n\t\t\t\t\t\t\t\t\tHeader: serial.ToTypedMessage(&wechat.VideoConfig{}),\n\t\t\t\t\t\t\t\t\tSecurity: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_NONE,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocolName: \"quic\",\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocolName: \"quic\",\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&quic.Config{\n\t\t\t\t\t\t\t\t\tHeader: serial.ToTypedMessage(&wechat.VideoConfig{}),\n\t\t\t\t\t\t\t\t\tSecurity: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_NONE,\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\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/scenarios/vmess_test.go",
    "content": "package scenarios\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/golang/protobuf/ptypes/any\"\n\t\"golang.org/x/sync/errgroup\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/log\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\tclog \"github.com/v2fly/v2ray-core/v5/common/log\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/freedom\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n)\n\nfunc TestVMessDynamicPort(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\n\tretry := 1\n\tserverPort := tcp.PickPort()\n\tfor {\n\t\tserverConfig := &core.Config{\n\t\t\tApp: []*anypb.Any{\n\t\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t\t}),\n\t\t\t},\n\t\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t\t{\n\t\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t}),\n\t\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\tId: userID.String(),\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\tDetour: &inbound.DetourConfig{\n\t\t\t\t\t\t\tTo: \"detour\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\t\tPortRange: net.SinglePortRange(serverPort + 100),\n\t\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t}),\n\t\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\t\tPortRange: &net.PortRange{\n\t\t\t\t\t\t\tFrom: uint32(serverPort + 1),\n\t\t\t\t\t\t\tTo:   uint32(serverPort + 99),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tListen: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\tAllocationStrategy: &proxyman.AllocationStrategy{\n\t\t\t\t\t\t\tType: proxyman.AllocationStrategy_Random,\n\t\t\t\t\t\t\tConcurrency: &proxyman.AllocationStrategy_AllocationStrategyConcurrency{\n\t\t\t\t\t\t\t\tValue: 2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tRefresh: &proxyman.AllocationStrategy_AllocationStrategyRefresh{\n\t\t\t\t\t\t\t\tValue: 5,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{}),\n\t\t\t\t\tTag:           \"detour\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t\t{\n\t\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tserver, _ := InitializeServerConfig(serverConfig)\n\t\tif server != nil && tcpConnAvailableAtPort(t, serverPort+100) {\n\t\t\tdefer CloseServer(server)\n\t\t\tbreak\n\t\t}\n\t\tretry++\n\t\tif retry > 5 {\n\t\t\tt.Fatal(\"All attempts failed to start server\")\n\t\t}\n\t\tserverPort = tcp.PickPort()\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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},\n\t}\n\n\tserver, err := InitializeServerConfig(clientConfig)\n\tcommon.Must(err)\n\tdefer CloseServer(server)\n\n\tif !tcpConnAvailableAtPort(t, clientPort) {\n\t\tt.Fail()\n\t}\n}\n\nfunc tcpConnAvailableAtPort(t *testing.T, port net.Port) bool {\n\tfor i := 1; ; i++ {\n\t\tif i > 10 {\n\t\t\tt.Log(\"All attempts failed to test tcp conn\")\n\t\t\treturn false\n\t\t}\n\t\ttime.Sleep(time.Millisecond * 10)\n\t\tif err := testTCPConn(port, 1024, time.Second*2)(); err != nil {\n\t\t\tt.Log(\"err \", err)\n\t\t} else {\n\t\t\tt.Log(\"success with\", i, \"attempts\")\n\t\t\tbreak\n\t\t}\n\t}\n\treturn true\n}\n\nfunc TestVMessGCM(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessGCMReadv(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tconst envName = \"V2RAY_BUF_READV\"\n\tcommon.Must(os.Setenv(envName, \"enable\"))\n\tdefer os.Unsetenv(envName)\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessGCMUDP(t *testing.T) {\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := udp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testUDPConn(clientPort, 1024, time.Second*5))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessChacha20(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_CHACHA20_POLY1305,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*20))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessNone(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_NONE,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessKCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*any.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Minute*2))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessKCPLarge(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := udp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&kcp.Config{\n\t\t\t\t\t\t\t\t\tReadBuffer: &kcp.ReadBuffer{\n\t\t\t\t\t\t\t\t\t\tSize: 512 * 1024,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tWriteBuffer: &kcp.WriteBuffer{\n\t\t\t\t\t\t\t\t\t\tSize: 512 * 1024,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tUplinkCapacity: &kcp.UplinkCapacity{\n\t\t\t\t\t\t\t\t\t\tValue: 20,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tDownlinkCapacity: &kcp.DownlinkCapacity{\n\t\t\t\t\t\t\t\t\t\tValue: 20,\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\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tStreamSettings: &internet.StreamConfig{\n\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t\tTransportSettings: []*internet.TransportConfig{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tProtocol: internet.TransportProtocol_MKCP,\n\t\t\t\t\t\t\t\tSettings: serial.ToTypedMessage(&kcp.Config{\n\t\t\t\t\t\t\t\t\tReadBuffer: &kcp.ReadBuffer{\n\t\t\t\t\t\t\t\t\t\tSize: 512 * 1024,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tWriteBuffer: &kcp.WriteBuffer{\n\t\t\t\t\t\t\t\t\t\tSize: 512 * 1024,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tUplinkCapacity: &kcp.UplinkCapacity{\n\t\t\t\t\t\t\t\t\t\tValue: 20,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tDownlinkCapacity: &kcp.DownlinkCapacity{\n\t\t\t\t\t\t\t\t\t\tValue: 20,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 2; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Minute*5))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n\n\tdefer func() {\n\t\t<-time.After(5 * time.Second)\n\t\tCloseAllServers(servers)\n\t}()\n}\n\nfunc TestVMessGCMMux(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tMultiplexSettings: &proxyman.MultiplexingConfig{\n\t\t\t\t\t\tEnabled:     true,\n\t\t\t\t\t\tConcurrency: 4,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tfor range \"abcd\" {\n\t\tvar errg errgroup.Group\n\t\tfor i := 0; i < 16; i++ {\n\t\t\terrg.Go(testTCPConn(clientPort, 10240, time.Second*20))\n\t\t}\n\t\tif err := errg.Wait(); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\ttime.Sleep(time.Second)\n\t}\n}\n\nfunc TestVMessGCMMuxUDP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tudpServer := udp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tudpDest, err := udpServer.Start()\n\tcommon.Must(err)\n\tdefer udpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientUDPPort := udp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientUDPPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(udpDest.Address),\n\t\t\t\t\tPort:    uint32(udpDest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tSenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{\n\t\t\t\t\tMultiplexSettings: &proxyman.MultiplexingConfig{\n\t\t\t\t\t\tEnabled:     true,\n\t\t\t\t\t\tConcurrency: 4,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\n\tfor range \"abcd\" {\n\t\tvar errg errgroup.Group\n\t\tfor i := 0; i < 16; i++ {\n\t\t\terrg.Go(testTCPConn(clientPort, 10240, time.Second*20))\n\t\t\terrg.Go(testUDPConn(clientUDPPort, 1024, time.Second*10))\n\t\t}\n\t\tif err := errg.Wait(); err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\ttime.Sleep(time.Second)\n\t}\n\n\tdefer func() {\n\t\t<-time.After(5 * time.Second)\n\t\tCloseAllServers(servers)\n\t}()\n}\n\nfunc TestVMessZero(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_ZERO,\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tcommon.Must(err)\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 1024*1024, time.Second*30))\n\t}\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessGCMLengthAuth(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\tAlterId: 0,\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTestsEnabled: \"AuthenticatedLength\",\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestVMessGCMLengthAuthPlusNoTerminationSignal(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: xor,\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tuserID := protocol.NewID(uuid.New())\n\tserverPort := tcp.PickPort()\n\tserverConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(serverPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&inbound.Config{\n\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\tId:           userID.String(),\n\t\t\t\t\t\t\t\tAlterId:      0,\n\t\t\t\t\t\t\t\tTestsEnabled: \"AuthenticatedLength|NoTerminationSignal\",\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\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&freedom.Config{}),\n\t\t\t},\n\t\t},\n\t}\n\n\tclientPort := tcp.PickPort()\n\tclientConfig := &core.Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&log.Config{\n\t\t\t\tError: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},\n\t\t\t}),\n\t\t},\n\t\tInbound: []*core.InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(clientPort),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(dest.Address),\n\t\t\t\t\tPort:    uint32(dest.Port),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*core.OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(serverPort),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId:      userID.String(),\n\t\t\t\t\t\t\t\t\t\tAlterId: 0,\n\t\t\t\t\t\t\t\t\t\tSecuritySettings: &protocol.SecurityConfig{\n\t\t\t\t\t\t\t\t\t\t\tType: protocol.SecurityType_AES128_GCM,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTestsEnabled: \"AuthenticatedLength|NoTerminationSignal\",\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},\n\t}\n\n\tservers, err := InitializeServerConfigs(serverConfig, clientConfig)\n\tif err != nil {\n\t\tt.Fatal(\"Failed to initialize all servers: \", err.Error())\n\t}\n\tdefer CloseAllServers(servers)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/servers/http/http.go",
    "content": "package tcp\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype Server struct {\n\tPort        net.Port\n\tPathHandler map[string]http.HandlerFunc\n\tserver      *http.Server\n}\n\nfunc (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) {\n\tif req.URL.Path == \"/\" {\n\t\tresp.Header().Set(\"Content-Type\", \"text/plain; charset=utf-8\")\n\t\tresp.WriteHeader(http.StatusOK)\n\t\tresp.Write([]byte(\"Home\"))\n\t\treturn\n\t}\n\n\thandler, found := s.PathHandler[req.URL.Path]\n\tif found {\n\t\thandler(resp, req)\n\t}\n}\n\nfunc (s *Server) Start() (net.Destination, error) {\n\ts.server = &http.Server{\n\t\tAddr:    \"127.0.0.1:\" + s.Port.String(),\n\t\tHandler: s,\n\t}\n\tgo s.server.ListenAndServe()\n\treturn net.TCPDestination(net.LocalHostIP, s.Port), nil\n}\n\nfunc (s *Server) Close() error {\n\treturn s.server.Close()\n}\n"
  },
  {
    "path": "testing/servers/tcp/port.go",
    "content": "package tcp\n\nimport \"github.com/v2fly/v2ray-core/v5/common/net\"\n\n// PickPort returns an unused TCP port of the system.\nfunc PickPort() net.Port {\n\tlistener := pickPort()\n\tdefer listener.Close()\n\n\taddr := listener.Addr().(*net.TCPAddr)\n\treturn net.Port(addr.Port)\n}\n\nfunc pickPort() net.Listener {\n\tlistener, err := net.Listen(\"tcp4\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\tlistener = pickPort()\n\t}\n\treturn listener\n}\n"
  },
  {
    "path": "testing/servers/tcp/tcp.go",
    "content": "package tcp\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\ntype Server struct {\n\tPort         net.Port\n\tMsgProcessor func(msg []byte) []byte\n\tShouldClose  bool\n\tSendFirst    []byte\n\tListen       net.Address\n\tlistener     net.Listener\n}\n\nfunc (server *Server) Start() (net.Destination, error) {\n\treturn server.StartContext(context.Background(), nil)\n}\n\nfunc (server *Server) StartContext(ctx context.Context, sockopt *internet.SocketConfig) (net.Destination, error) {\n\tlistenerAddr := server.Listen\n\tif listenerAddr == nil {\n\t\tlistenerAddr = net.LocalHostIP\n\t}\n\tlistener, err := internet.ListenSystem(ctx, &net.TCPAddr{\n\t\tIP:   listenerAddr.IP(),\n\t\tPort: int(server.Port),\n\t}, sockopt)\n\tif err != nil {\n\t\treturn net.Destination{}, err\n\t}\n\n\tlocalAddr := listener.Addr().(*net.TCPAddr)\n\tserver.Port = net.Port(localAddr.Port)\n\tserver.listener = listener\n\tgo server.acceptConnections(listener.(*net.TCPListener))\n\n\treturn net.TCPDestination(net.IPAddress(localAddr.IP), net.Port(localAddr.Port)), nil\n}\n\nfunc (server *Server) acceptConnections(listener *net.TCPListener) {\n\tfor {\n\t\tconn, err := listener.Accept()\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Failed accept TCP connection: %v\\n\", err)\n\t\t\treturn\n\t\t}\n\n\t\tgo server.handleConnection(conn)\n\t}\n}\n\nfunc (server *Server) handleConnection(conn net.Conn) {\n\tif len(server.SendFirst) > 0 {\n\t\tconn.Write(server.SendFirst)\n\t}\n\n\tpReader, pWriter := pipe.New(pipe.WithoutSizeLimit())\n\terr := task.Run(context.Background(), func() error {\n\t\tdefer pWriter.Close()\n\n\t\tfor {\n\t\t\tb := buf.New()\n\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\tif err == io.EOF {\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\tcopy(b.Bytes(), server.MsgProcessor(b.Bytes()))\n\t\t\tif err := pWriter.WriteMultiBuffer(buf.MultiBuffer{b}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}, func() error {\n\t\tdefer pReader.Interrupt()\n\n\t\tw := buf.NewWriter(conn)\n\t\tfor {\n\t\t\tmb, err := pReader.ReadMultiBuffer()\n\t\t\tif err != nil {\n\t\t\t\tif err == io.EOF {\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\tif err := w.WriteMultiBuffer(mb); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t})\n\tif err != nil {\n\t\tfmt.Println(\"failed to transfer data: \", err.Error())\n\t}\n\n\tconn.Close()\n}\n\nfunc (server *Server) Close() error {\n\treturn server.listener.Close()\n}\n"
  },
  {
    "path": "testing/servers/udp/port.go",
    "content": "package udp\n\nimport \"github.com/v2fly/v2ray-core/v5/common/net\"\n\n// PickPort returns an unused UDP port of the system.\nfunc PickPort() net.Port {\n\tconn := pickPort()\n\tdefer conn.Close()\n\n\taddr := conn.LocalAddr().(*net.UDPAddr)\n\treturn net.Port(addr.Port)\n}\n\nfunc pickPort() *net.UDPConn {\n\tconn, err := net.ListenUDP(\"udp4\", &net.UDPAddr{\n\t\tIP:   net.LocalHostIP.IP(),\n\t\tPort: 0,\n\t})\n\tif err != nil {\n\t\tconn = pickPort()\n\t}\n\treturn conn\n}\n"
  },
  {
    "path": "testing/servers/udp/udp.go",
    "content": "package udp\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype Server struct {\n\tPort         net.Port\n\tMsgProcessor func(msg []byte) []byte\n\taccepting    bool\n\tconn         *net.UDPConn\n}\n\nfunc (server *Server) Start() (net.Destination, error) {\n\tconn, err := net.ListenUDP(\"udp\", &net.UDPAddr{\n\t\tIP:   []byte{127, 0, 0, 1},\n\t\tPort: int(server.Port),\n\t\tZone: \"\",\n\t})\n\tif err != nil {\n\t\treturn net.Destination{}, err\n\t}\n\tserver.Port = net.Port(conn.LocalAddr().(*net.UDPAddr).Port)\n\tfmt.Println(\"UDP server started on port \", server.Port)\n\n\tserver.conn = conn\n\tgo server.handleConnection(conn)\n\n\tlocalAddr := conn.LocalAddr().(*net.UDPAddr)\n\treturn net.UDPDestination(net.IPAddress(localAddr.IP), net.Port(localAddr.Port)), nil\n}\n\nfunc (server *Server) handleConnection(conn *net.UDPConn) {\n\tserver.accepting = true\n\tfor server.accepting {\n\t\tbuffer := make([]byte, 2*1024)\n\t\tnBytes, addr, err := conn.ReadFromUDP(buffer)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Failed to read from UDP: %v\\n\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tresponse := server.MsgProcessor(buffer[:nBytes])\n\t\tif _, err := conn.WriteToUDP(response, addr); err != nil {\n\t\t\tfmt.Println(\"Failed to write to UDP: \", err.Error())\n\t\t}\n\t}\n}\n\nfunc (server *Server) Close() error {\n\tserver.accepting = false\n\treturn server.conn.Close()\n}\n"
  },
  {
    "path": "transport/config.go",
    "content": "package transport\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// Apply applies this Config.\nfunc (c *Config) Apply() error {\n\tif c == nil {\n\t\treturn nil\n\t}\n\treturn internet.ApplyGlobalTransportSettings(c.TransportSettings)\n}\n"
  },
  {
    "path": "transport/config.pb.go",
    "content": "package transport\n\nimport (\n\tinternet \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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// Global transport settings. This affects all type of connections that go\n// through V2Ray. Deprecated. Use each settings in StreamConfig.\n//\n// Deprecated: Marked as deprecated in transport/config.proto.\ntype Config struct {\n\tstate             protoimpl.MessageState      `protogen:\"open.v1\"`\n\tTransportSettings []*internet.TransportConfig `protobuf:\"bytes,1,rep,name=transport_settings,json=transportSettings,proto3\" json:\"transport_settings,omitempty\"`\n\tunknownFields     protoimpl.UnknownFields\n\tsizeCache         protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetTransportSettings() []*internet.TransportConfig {\n\tif x != nil {\n\t\treturn x.TransportSettings\n\t}\n\treturn nil\n}\n\nvar File_transport_config_proto protoreflect.FileDescriptor\n\nconst file_transport_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x16transport/config.proto\\x12\\x14v2ray.core.transport\\x1a\\x1ftransport/internet/config.proto\\\"k\\n\" +\n\t\"\\x06Config\\x12]\\n\" +\n\t\"\\x12transport_settings\\x18\\x01 \\x03(\\v2..v2ray.core.transport.internet.TransportConfigR\\x11transportSettings:\\x02\\x18\\x01B]\\n\" +\n\t\"\\x18com.v2ray.core.transportP\\x01Z(github.com/v2fly/v2ray-core/v5/transport\\xaa\\x02\\x14V2Ray.Core.Transportb\\x06proto3\"\n\nvar (\n\tfile_transport_config_proto_rawDescOnce sync.Once\n\tfile_transport_config_proto_rawDescData []byte\n)\n\nfunc file_transport_config_proto_rawDescGZIP() []byte {\n\tfile_transport_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_config_proto_rawDesc), len(file_transport_config_proto_rawDesc)))\n\t})\n\treturn file_transport_config_proto_rawDescData\n}\n\nvar file_transport_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_config_proto_goTypes = []any{\n\t(*Config)(nil),                   // 0: v2ray.core.transport.Config\n\t(*internet.TransportConfig)(nil), // 1: v2ray.core.transport.internet.TransportConfig\n}\nvar file_transport_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.Config.transport_settings:type_name -> v2ray.core.transport.internet.TransportConfig\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_config_proto_init() }\nfunc file_transport_config_proto_init() {\n\tif File_transport_config_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: unsafe.Slice(unsafe.StringData(file_transport_config_proto_rawDesc), len(file_transport_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_config_proto = out.File\n\tfile_transport_config_proto_goTypes = nil\n\tfile_transport_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport;\noption csharp_namespace = \"V2Ray.Core.Transport\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport\";\noption java_package = \"com.v2ray.core.transport\";\noption java_multiple_files = true;\n\nimport \"transport/internet/config.proto\";\n\n// Global transport settings. This affects all type of connections that go\n// through V2Ray. Deprecated. Use each settings in StreamConfig.\nmessage Config {\n  option deprecated = true;\n  repeated v2ray.core.transport.internet.TransportConfig transport_settings = 1;\n}\n"
  },
  {
    "path": "transport/internet/config.go",
    "content": "package internet\n\nimport (\n\t\"context\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n)\n\ntype ConfigCreator func() interface{}\n\nvar (\n\tglobalTransportConfigCreatorCache = make(map[string]ConfigCreator)\n\tglobalTransportSettings           []*TransportConfig\n)\n\nconst unknownProtocol = \"unknown\"\n\nfunc transportProtocolToString(protocol TransportProtocol) string {\n\tswitch protocol {\n\tcase TransportProtocol_TCP:\n\t\treturn \"tcp\"\n\tcase TransportProtocol_UDP:\n\t\treturn \"udp\"\n\tcase TransportProtocol_HTTP:\n\t\treturn \"http\"\n\tcase TransportProtocol_MKCP:\n\t\treturn \"mkcp\"\n\tcase TransportProtocol_WebSocket:\n\t\treturn \"websocket\"\n\tcase TransportProtocol_DomainSocket:\n\t\treturn \"domainsocket\"\n\tdefault:\n\t\treturn unknownProtocol\n\t}\n}\n\nfunc RegisterProtocolConfigCreator(name string, creator ConfigCreator) error {\n\tif _, found := globalTransportConfigCreatorCache[name]; found {\n\t\treturn newError(\"protocol \", name, \" is already registered\").AtError()\n\t}\n\tglobalTransportConfigCreatorCache[name] = creator\n\n\tcommon.RegisterConfig(creator(), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn nil, newError(\"transport config should use CreateTransportConfig instead\")\n\t})\n\treturn nil\n}\n\nfunc CreateTransportConfig(name string) (interface{}, error) {\n\tcreator, ok := globalTransportConfigCreatorCache[name]\n\tif !ok {\n\t\treturn nil, newError(\"unknown transport protocol: \", name)\n\t}\n\treturn creator(), nil\n}\n\nfunc (c *TransportConfig) GetTypedSettings() (interface{}, error) {\n\treturn serial.GetInstanceOf(c.Settings)\n}\n\nfunc (c *TransportConfig) GetUnifiedProtocolName() string {\n\tif len(c.ProtocolName) > 0 {\n\t\treturn c.ProtocolName\n\t}\n\n\treturn transportProtocolToString(c.Protocol)\n}\n\nfunc (c *StreamConfig) GetEffectiveProtocol() string {\n\tif c == nil {\n\t\treturn \"tcp\"\n\t}\n\n\tif len(c.ProtocolName) > 0 {\n\t\treturn c.ProtocolName\n\t}\n\n\treturn transportProtocolToString(c.Protocol)\n}\n\nfunc (c *StreamConfig) GetEffectiveTransportSettings() (interface{}, error) {\n\tprotocol := c.GetEffectiveProtocol()\n\treturn c.GetTransportSettingsFor(protocol)\n}\n\nfunc (c *StreamConfig) GetTransportSettingsFor(protocol string) (interface{}, error) {\n\tif c != nil {\n\t\tfor _, settings := range c.TransportSettings {\n\t\t\tif settings.GetUnifiedProtocolName() == protocol {\n\t\t\t\treturn settings.GetTypedSettings()\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, settings := range globalTransportSettings {\n\t\tif settings.GetUnifiedProtocolName() == protocol {\n\t\t\treturn settings.GetTypedSettings()\n\t\t}\n\t}\n\n\treturn CreateTransportConfig(protocol)\n}\n\nfunc (c *StreamConfig) GetEffectiveSecuritySettings() (interface{}, error) {\n\tfor _, settings := range c.SecuritySettings {\n\t\tif serial.V2Type(settings) == c.SecurityType {\n\t\t\treturn serial.GetInstanceOf(settings)\n\t\t}\n\t}\n\treturn serial.GetInstance(c.SecurityType)\n}\n\nfunc (c *StreamConfig) HasSecuritySettings() bool {\n\treturn len(c.SecurityType) > 0\n}\n\nfunc ApplyGlobalTransportSettings(settings []*TransportConfig) error {\n\tfeatures.PrintDeprecatedFeatureWarning(\"global transport settings\")\n\tglobalTransportSettings = settings\n\treturn nil\n}\n\nfunc (c *ProxyConfig) HasTag() bool {\n\treturn c != nil && len(c.Tag) > 0\n}\n\nfunc (m SocketConfig_TProxyMode) IsEnabled() bool {\n\treturn m != SocketConfig_Off\n}\n\nfunc getOriginalMessageName(streamSettings *MemoryStreamConfig) string {\n\tmsgOpts, err := protoext.GetMessageOptions(proto.MessageV2(streamSettings.ProtocolSettings).ProtoReflect().Descriptor())\n\tif err == nil {\n\t\tif msgOpts.TransportOriginalName != \"\" {\n\t\t\treturn msgOpts.TransportOriginalName\n\t\t}\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "transport/internet/config.pb.go",
    "content": "package internet\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\tunsafe \"unsafe\"\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 TransportProtocol int32\n\nconst (\n\tTransportProtocol_TCP          TransportProtocol = 0\n\tTransportProtocol_UDP          TransportProtocol = 1\n\tTransportProtocol_MKCP         TransportProtocol = 2\n\tTransportProtocol_WebSocket    TransportProtocol = 3\n\tTransportProtocol_HTTP         TransportProtocol = 4\n\tTransportProtocol_DomainSocket TransportProtocol = 5\n)\n\n// Enum value maps for TransportProtocol.\nvar (\n\tTransportProtocol_name = map[int32]string{\n\t\t0: \"TCP\",\n\t\t1: \"UDP\",\n\t\t2: \"MKCP\",\n\t\t3: \"WebSocket\",\n\t\t4: \"HTTP\",\n\t\t5: \"DomainSocket\",\n\t}\n\tTransportProtocol_value = map[string]int32{\n\t\t\"TCP\":          0,\n\t\t\"UDP\":          1,\n\t\t\"MKCP\":         2,\n\t\t\"WebSocket\":    3,\n\t\t\"HTTP\":         4,\n\t\t\"DomainSocket\": 5,\n\t}\n)\n\nfunc (x TransportProtocol) Enum() *TransportProtocol {\n\tp := new(TransportProtocol)\n\t*p = x\n\treturn p\n}\n\nfunc (x TransportProtocol) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (TransportProtocol) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (TransportProtocol) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_config_proto_enumTypes[0]\n}\n\nfunc (x TransportProtocol) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use TransportProtocol.Descriptor instead.\nfunc (TransportProtocol) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{0}\n}\n\n// MPTCP is the state of MPTCP settings.\n// Define it here to avoid conflict with TCPFastOpenState.\ntype MPTCPState int32\n\nconst (\n\t// AsIs is to leave the current MPTCP state as is, unmodified.\n\tMPTCPState_AsIs MPTCPState = 0\n\t// Enable is for enabling MPTCP explictly.\n\tMPTCPState_Enable MPTCPState = 1\n\t// Disable is for disabling MPTCP explictly.\n\tMPTCPState_Disable MPTCPState = 2\n)\n\n// Enum value maps for MPTCPState.\nvar (\n\tMPTCPState_name = map[int32]string{\n\t\t0: \"AsIs\",\n\t\t1: \"Enable\",\n\t\t2: \"Disable\",\n\t}\n\tMPTCPState_value = map[string]int32{\n\t\t\"AsIs\":    0,\n\t\t\"Enable\":  1,\n\t\t\"Disable\": 2,\n\t}\n)\n\nfunc (x MPTCPState) Enum() *MPTCPState {\n\tp := new(MPTCPState)\n\t*p = x\n\treturn p\n}\n\nfunc (x MPTCPState) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (MPTCPState) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_config_proto_enumTypes[1].Descriptor()\n}\n\nfunc (MPTCPState) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_config_proto_enumTypes[1]\n}\n\nfunc (x MPTCPState) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use MPTCPState.Descriptor instead.\nfunc (MPTCPState) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{1}\n}\n\ntype SocketConfig_TCPFastOpenState int32\n\nconst (\n\t// AsIs is to leave the current TFO state as is, unmodified.\n\tSocketConfig_AsIs SocketConfig_TCPFastOpenState = 0\n\t// Enable is for enabling TFO explictly.\n\tSocketConfig_Enable SocketConfig_TCPFastOpenState = 1\n\t// Disable is for disabling TFO explictly.\n\tSocketConfig_Disable SocketConfig_TCPFastOpenState = 2\n)\n\n// Enum value maps for SocketConfig_TCPFastOpenState.\nvar (\n\tSocketConfig_TCPFastOpenState_name = map[int32]string{\n\t\t0: \"AsIs\",\n\t\t1: \"Enable\",\n\t\t2: \"Disable\",\n\t}\n\tSocketConfig_TCPFastOpenState_value = map[string]int32{\n\t\t\"AsIs\":    0,\n\t\t\"Enable\":  1,\n\t\t\"Disable\": 2,\n\t}\n)\n\nfunc (x SocketConfig_TCPFastOpenState) Enum() *SocketConfig_TCPFastOpenState {\n\tp := new(SocketConfig_TCPFastOpenState)\n\t*p = x\n\treturn p\n}\n\nfunc (x SocketConfig_TCPFastOpenState) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (SocketConfig_TCPFastOpenState) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_config_proto_enumTypes[2].Descriptor()\n}\n\nfunc (SocketConfig_TCPFastOpenState) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_config_proto_enumTypes[2]\n}\n\nfunc (x SocketConfig_TCPFastOpenState) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use SocketConfig_TCPFastOpenState.Descriptor instead.\nfunc (SocketConfig_TCPFastOpenState) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{3, 0}\n}\n\ntype SocketConfig_TProxyMode int32\n\nconst (\n\t// TProxy is off.\n\tSocketConfig_Off SocketConfig_TProxyMode = 0\n\t// TProxy mode.\n\tSocketConfig_TProxy SocketConfig_TProxyMode = 1\n\t// Redirect mode.\n\tSocketConfig_Redirect SocketConfig_TProxyMode = 2\n)\n\n// Enum value maps for SocketConfig_TProxyMode.\nvar (\n\tSocketConfig_TProxyMode_name = map[int32]string{\n\t\t0: \"Off\",\n\t\t1: \"TProxy\",\n\t\t2: \"Redirect\",\n\t}\n\tSocketConfig_TProxyMode_value = map[string]int32{\n\t\t\"Off\":      0,\n\t\t\"TProxy\":   1,\n\t\t\"Redirect\": 2,\n\t}\n)\n\nfunc (x SocketConfig_TProxyMode) Enum() *SocketConfig_TProxyMode {\n\tp := new(SocketConfig_TProxyMode)\n\t*p = x\n\treturn p\n}\n\nfunc (x SocketConfig_TProxyMode) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (SocketConfig_TProxyMode) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_config_proto_enumTypes[3].Descriptor()\n}\n\nfunc (SocketConfig_TProxyMode) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_config_proto_enumTypes[3]\n}\n\nfunc (x SocketConfig_TProxyMode) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use SocketConfig_TProxyMode.Descriptor instead.\nfunc (SocketConfig_TProxyMode) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{3, 1}\n}\n\ntype TransportConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Type of network that this settings supports.\n\t// Deprecated. Use the string form below.\n\t//\n\t// Deprecated: Marked as deprecated in transport/internet/config.proto.\n\tProtocol TransportProtocol `protobuf:\"varint,1,opt,name=protocol,proto3,enum=v2ray.core.transport.internet.TransportProtocol\" json:\"protocol,omitempty\"`\n\t// Type of network that this settings supports.\n\tProtocolName string `protobuf:\"bytes,3,opt,name=protocol_name,json=protocolName,proto3\" json:\"protocol_name,omitempty\"`\n\t// Specific settings. Must be of the transports.\n\tSettings      *anypb.Any `protobuf:\"bytes,2,opt,name=settings,proto3\" json:\"settings,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *TransportConfig) Reset() {\n\t*x = TransportConfig{}\n\tmi := &file_transport_internet_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TransportConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TransportConfig) ProtoMessage() {}\n\nfunc (x *TransportConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_config_proto_msgTypes[0]\n\tif 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 TransportConfig.ProtoReflect.Descriptor instead.\nfunc (*TransportConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{0}\n}\n\n// Deprecated: Marked as deprecated in transport/internet/config.proto.\nfunc (x *TransportConfig) GetProtocol() TransportProtocol {\n\tif x != nil {\n\t\treturn x.Protocol\n\t}\n\treturn TransportProtocol_TCP\n}\n\nfunc (x *TransportConfig) GetProtocolName() string {\n\tif x != nil {\n\t\treturn x.ProtocolName\n\t}\n\treturn \"\"\n}\n\nfunc (x *TransportConfig) GetSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Settings\n\t}\n\treturn nil\n}\n\ntype StreamConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Effective network. Deprecated. Use the string form below.\n\t//\n\t// Deprecated: Marked as deprecated in transport/internet/config.proto.\n\tProtocol TransportProtocol `protobuf:\"varint,1,opt,name=protocol,proto3,enum=v2ray.core.transport.internet.TransportProtocol\" json:\"protocol,omitempty\"`\n\t// Effective network.\n\tProtocolName      string             `protobuf:\"bytes,5,opt,name=protocol_name,json=protocolName,proto3\" json:\"protocol_name,omitempty\"`\n\tTransportSettings []*TransportConfig `protobuf:\"bytes,2,rep,name=transport_settings,json=transportSettings,proto3\" json:\"transport_settings,omitempty\"`\n\t// Type of security. Must be a message name of the settings proto.\n\tSecurityType string `protobuf:\"bytes,3,opt,name=security_type,json=securityType,proto3\" json:\"security_type,omitempty\"`\n\t// Settings for transport security. For now the only choice is TLS.\n\tSecuritySettings []*anypb.Any  `protobuf:\"bytes,4,rep,name=security_settings,json=securitySettings,proto3\" json:\"security_settings,omitempty\"`\n\tSocketSettings   *SocketConfig `protobuf:\"bytes,6,opt,name=socket_settings,json=socketSettings,proto3\" json:\"socket_settings,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *StreamConfig) Reset() {\n\t*x = StreamConfig{}\n\tmi := &file_transport_internet_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *StreamConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StreamConfig) ProtoMessage() {}\n\nfunc (x *StreamConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_config_proto_msgTypes[1]\n\tif 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 StreamConfig.ProtoReflect.Descriptor instead.\nfunc (*StreamConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{1}\n}\n\n// Deprecated: Marked as deprecated in transport/internet/config.proto.\nfunc (x *StreamConfig) GetProtocol() TransportProtocol {\n\tif x != nil {\n\t\treturn x.Protocol\n\t}\n\treturn TransportProtocol_TCP\n}\n\nfunc (x *StreamConfig) GetProtocolName() string {\n\tif x != nil {\n\t\treturn x.ProtocolName\n\t}\n\treturn \"\"\n}\n\nfunc (x *StreamConfig) GetTransportSettings() []*TransportConfig {\n\tif x != nil {\n\t\treturn x.TransportSettings\n\t}\n\treturn nil\n}\n\nfunc (x *StreamConfig) GetSecurityType() string {\n\tif x != nil {\n\t\treturn x.SecurityType\n\t}\n\treturn \"\"\n}\n\nfunc (x *StreamConfig) GetSecuritySettings() []*anypb.Any {\n\tif x != nil {\n\t\treturn x.SecuritySettings\n\t}\n\treturn nil\n}\n\nfunc (x *StreamConfig) GetSocketSettings() *SocketConfig {\n\tif x != nil {\n\t\treturn x.SocketSettings\n\t}\n\treturn nil\n}\n\ntype ProxyConfig struct {\n\tstate               protoimpl.MessageState `protogen:\"open.v1\"`\n\tTag                 string                 `protobuf:\"bytes,1,opt,name=tag,proto3\" json:\"tag,omitempty\"`\n\tTransportLayerProxy bool                   `protobuf:\"varint,2,opt,name=transportLayerProxy,proto3\" json:\"transportLayerProxy,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *ProxyConfig) Reset() {\n\t*x = ProxyConfig{}\n\tmi := &file_transport_internet_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ProxyConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ProxyConfig) ProtoMessage() {}\n\nfunc (x *ProxyConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_config_proto_msgTypes[2]\n\tif 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 ProxyConfig.ProtoReflect.Descriptor instead.\nfunc (*ProxyConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ProxyConfig) GetTag() string {\n\tif x != nil {\n\t\treturn x.Tag\n\t}\n\treturn \"\"\n}\n\nfunc (x *ProxyConfig) GetTransportLayerProxy() bool {\n\tif x != nil {\n\t\treturn x.TransportLayerProxy\n\t}\n\treturn false\n}\n\n// SocketConfig is options to be applied on network sockets.\ntype SocketConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Mark of the connection. If non-zero, the value will be set to SO_MARK.\n\tMark uint32 `protobuf:\"varint,1,opt,name=mark,proto3\" json:\"mark,omitempty\"`\n\t// TFO is the state of TFO settings.\n\tTfo SocketConfig_TCPFastOpenState `protobuf:\"varint,2,opt,name=tfo,proto3,enum=v2ray.core.transport.internet.SocketConfig_TCPFastOpenState\" json:\"tfo,omitempty\"`\n\t// TProxy is for enabling TProxy socket option.\n\tTproxy SocketConfig_TProxyMode `protobuf:\"varint,3,opt,name=tproxy,proto3,enum=v2ray.core.transport.internet.SocketConfig_TProxyMode\" json:\"tproxy,omitempty\"`\n\t// ReceiveOriginalDestAddress is for enabling IP_RECVORIGDSTADDR socket\n\t// option. This option is for UDP only.\n\tReceiveOriginalDestAddress bool       `protobuf:\"varint,4,opt,name=receive_original_dest_address,json=receiveOriginalDestAddress,proto3\" json:\"receive_original_dest_address,omitempty\"`\n\tBindAddress                []byte     `protobuf:\"bytes,5,opt,name=bind_address,json=bindAddress,proto3\" json:\"bind_address,omitempty\"`\n\tBindPort                   uint32     `protobuf:\"varint,6,opt,name=bind_port,json=bindPort,proto3\" json:\"bind_port,omitempty\"`\n\tAcceptProxyProtocol        bool       `protobuf:\"varint,7,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3\" json:\"accept_proxy_protocol,omitempty\"`\n\tTcpKeepAliveInterval       int32      `protobuf:\"varint,8,opt,name=tcp_keep_alive_interval,json=tcpKeepAliveInterval,proto3\" json:\"tcp_keep_alive_interval,omitempty\"`\n\tTfoQueueLength             uint32     `protobuf:\"varint,9,opt,name=tfo_queue_length,json=tfoQueueLength,proto3\" json:\"tfo_queue_length,omitempty\"`\n\tTcpKeepAliveIdle           int32      `protobuf:\"varint,10,opt,name=tcp_keep_alive_idle,json=tcpKeepAliveIdle,proto3\" json:\"tcp_keep_alive_idle,omitempty\"`\n\tBindToDevice               string     `protobuf:\"bytes,11,opt,name=bind_to_device,json=bindToDevice,proto3\" json:\"bind_to_device,omitempty\"`\n\tRxBufSize                  int64      `protobuf:\"varint,12,opt,name=rx_buf_size,json=rxBufSize,proto3\" json:\"rx_buf_size,omitempty\"`\n\tTxBufSize                  int64      `protobuf:\"varint,13,opt,name=tx_buf_size,json=txBufSize,proto3\" json:\"tx_buf_size,omitempty\"`\n\tForceBufSize               bool       `protobuf:\"varint,14,opt,name=force_buf_size,json=forceBufSize,proto3\" json:\"force_buf_size,omitempty\"`\n\tMptcp                      MPTCPState `protobuf:\"varint,15,opt,name=mptcp,proto3,enum=v2ray.core.transport.internet.MPTCPState\" json:\"mptcp,omitempty\"`\n\tunknownFields              protoimpl.UnknownFields\n\tsizeCache                  protoimpl.SizeCache\n}\n\nfunc (x *SocketConfig) Reset() {\n\t*x = SocketConfig{}\n\tmi := &file_transport_internet_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *SocketConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SocketConfig) ProtoMessage() {}\n\nfunc (x *SocketConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_config_proto_msgTypes[3]\n\tif 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 SocketConfig.ProtoReflect.Descriptor instead.\nfunc (*SocketConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *SocketConfig) GetMark() uint32 {\n\tif x != nil {\n\t\treturn x.Mark\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetTfo() SocketConfig_TCPFastOpenState {\n\tif x != nil {\n\t\treturn x.Tfo\n\t}\n\treturn SocketConfig_AsIs\n}\n\nfunc (x *SocketConfig) GetTproxy() SocketConfig_TProxyMode {\n\tif x != nil {\n\t\treturn x.Tproxy\n\t}\n\treturn SocketConfig_Off\n}\n\nfunc (x *SocketConfig) GetReceiveOriginalDestAddress() bool {\n\tif x != nil {\n\t\treturn x.ReceiveOriginalDestAddress\n\t}\n\treturn false\n}\n\nfunc (x *SocketConfig) GetBindAddress() []byte {\n\tif x != nil {\n\t\treturn x.BindAddress\n\t}\n\treturn nil\n}\n\nfunc (x *SocketConfig) GetBindPort() uint32 {\n\tif x != nil {\n\t\treturn x.BindPort\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetAcceptProxyProtocol() bool {\n\tif x != nil {\n\t\treturn x.AcceptProxyProtocol\n\t}\n\treturn false\n}\n\nfunc (x *SocketConfig) GetTcpKeepAliveInterval() int32 {\n\tif x != nil {\n\t\treturn x.TcpKeepAliveInterval\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetTfoQueueLength() uint32 {\n\tif x != nil {\n\t\treturn x.TfoQueueLength\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetTcpKeepAliveIdle() int32 {\n\tif x != nil {\n\t\treturn x.TcpKeepAliveIdle\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetBindToDevice() string {\n\tif x != nil {\n\t\treturn x.BindToDevice\n\t}\n\treturn \"\"\n}\n\nfunc (x *SocketConfig) GetRxBufSize() int64 {\n\tif x != nil {\n\t\treturn x.RxBufSize\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetTxBufSize() int64 {\n\tif x != nil {\n\t\treturn x.TxBufSize\n\t}\n\treturn 0\n}\n\nfunc (x *SocketConfig) GetForceBufSize() bool {\n\tif x != nil {\n\t\treturn x.ForceBufSize\n\t}\n\treturn false\n}\n\nfunc (x *SocketConfig) GetMptcp() MPTCPState {\n\tif x != nil {\n\t\treturn x.Mptcp\n\t}\n\treturn MPTCPState_AsIs\n}\n\nvar File_transport_internet_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"\\x1ftransport/internet/config.proto\\x12\\x1dv2ray.core.transport.internet\\x1a\\x19google/protobuf/any.proto\\\"\\xba\\x01\\n\" +\n\t\"\\x0fTransportConfig\\x12P\\n\" +\n\t\"\\bprotocol\\x18\\x01 \\x01(\\x0e20.v2ray.core.transport.internet.TransportProtocolB\\x02\\x18\\x01R\\bprotocol\\x12#\\n\" +\n\t\"\\rprotocol_name\\x18\\x03 \\x01(\\tR\\fprotocolName\\x120\\n\" +\n\t\"\\bsettings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\bsettings\\\"\\xa2\\x03\\n\" +\n\t\"\\fStreamConfig\\x12P\\n\" +\n\t\"\\bprotocol\\x18\\x01 \\x01(\\x0e20.v2ray.core.transport.internet.TransportProtocolB\\x02\\x18\\x01R\\bprotocol\\x12#\\n\" +\n\t\"\\rprotocol_name\\x18\\x05 \\x01(\\tR\\fprotocolName\\x12]\\n\" +\n\t\"\\x12transport_settings\\x18\\x02 \\x03(\\v2..v2ray.core.transport.internet.TransportConfigR\\x11transportSettings\\x12#\\n\" +\n\t\"\\rsecurity_type\\x18\\x03 \\x01(\\tR\\fsecurityType\\x12A\\n\" +\n\t\"\\x11security_settings\\x18\\x04 \\x03(\\v2\\x14.google.protobuf.AnyR\\x10securitySettings\\x12T\\n\" +\n\t\"\\x0fsocket_settings\\x18\\x06 \\x01(\\v2+.v2ray.core.transport.internet.SocketConfigR\\x0esocketSettings\\\"Q\\n\" +\n\t\"\\vProxyConfig\\x12\\x10\\n\" +\n\t\"\\x03tag\\x18\\x01 \\x01(\\tR\\x03tag\\x120\\n\" +\n\t\"\\x13transportLayerProxy\\x18\\x02 \\x01(\\bR\\x13transportLayerProxy\\\"\\xbe\\x06\\n\" +\n\t\"\\fSocketConfig\\x12\\x12\\n\" +\n\t\"\\x04mark\\x18\\x01 \\x01(\\rR\\x04mark\\x12N\\n\" +\n\t\"\\x03tfo\\x18\\x02 \\x01(\\x0e2<.v2ray.core.transport.internet.SocketConfig.TCPFastOpenStateR\\x03tfo\\x12N\\n\" +\n\t\"\\x06tproxy\\x18\\x03 \\x01(\\x0e26.v2ray.core.transport.internet.SocketConfig.TProxyModeR\\x06tproxy\\x12A\\n\" +\n\t\"\\x1dreceive_original_dest_address\\x18\\x04 \\x01(\\bR\\x1areceiveOriginalDestAddress\\x12!\\n\" +\n\t\"\\fbind_address\\x18\\x05 \\x01(\\fR\\vbindAddress\\x12\\x1b\\n\" +\n\t\"\\tbind_port\\x18\\x06 \\x01(\\rR\\bbindPort\\x122\\n\" +\n\t\"\\x15accept_proxy_protocol\\x18\\a \\x01(\\bR\\x13acceptProxyProtocol\\x125\\n\" +\n\t\"\\x17tcp_keep_alive_interval\\x18\\b \\x01(\\x05R\\x14tcpKeepAliveInterval\\x12(\\n\" +\n\t\"\\x10tfo_queue_length\\x18\\t \\x01(\\rR\\x0etfoQueueLength\\x12-\\n\" +\n\t\"\\x13tcp_keep_alive_idle\\x18\\n\" +\n\t\" \\x01(\\x05R\\x10tcpKeepAliveIdle\\x12$\\n\" +\n\t\"\\x0ebind_to_device\\x18\\v \\x01(\\tR\\fbindToDevice\\x12\\x1e\\n\" +\n\t\"\\vrx_buf_size\\x18\\f \\x01(\\x03R\\trxBufSize\\x12\\x1e\\n\" +\n\t\"\\vtx_buf_size\\x18\\r \\x01(\\x03R\\ttxBufSize\\x12$\\n\" +\n\t\"\\x0eforce_buf_size\\x18\\x0e \\x01(\\bR\\fforceBufSize\\x12?\\n\" +\n\t\"\\x05mptcp\\x18\\x0f \\x01(\\x0e2).v2ray.core.transport.internet.MPTCPStateR\\x05mptcp\\\"5\\n\" +\n\t\"\\x10TCPFastOpenState\\x12\\b\\n\" +\n\t\"\\x04AsIs\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06Enable\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aDisable\\x10\\x02\\\"/\\n\" +\n\t\"\\n\" +\n\t\"TProxyMode\\x12\\a\\n\" +\n\t\"\\x03Off\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06TProxy\\x10\\x01\\x12\\f\\n\" +\n\t\"\\bRedirect\\x10\\x02*Z\\n\" +\n\t\"\\x11TransportProtocol\\x12\\a\\n\" +\n\t\"\\x03TCP\\x10\\x00\\x12\\a\\n\" +\n\t\"\\x03UDP\\x10\\x01\\x12\\b\\n\" +\n\t\"\\x04MKCP\\x10\\x02\\x12\\r\\n\" +\n\t\"\\tWebSocket\\x10\\x03\\x12\\b\\n\" +\n\t\"\\x04HTTP\\x10\\x04\\x12\\x10\\n\" +\n\t\"\\fDomainSocket\\x10\\x05*/\\n\" +\n\t\"\\n\" +\n\t\"MPTCPState\\x12\\b\\n\" +\n\t\"\\x04AsIs\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06Enable\\x10\\x01\\x12\\v\\n\" +\n\t\"\\aDisable\\x10\\x02Bx\\n\" +\n\t\"!com.v2ray.core.transport.internetP\\x01Z1github.com/v2fly/v2ray-core/v5/transport/internet\\xaa\\x02\\x1dV2Ray.Core.Transport.Internetb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_config_proto_rawDesc), len(file_transport_internet_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_config_proto_rawDescData\n}\n\nvar file_transport_internet_config_proto_enumTypes = make([]protoimpl.EnumInfo, 4)\nvar file_transport_internet_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_transport_internet_config_proto_goTypes = []any{\n\t(TransportProtocol)(0),             // 0: v2ray.core.transport.internet.TransportProtocol\n\t(MPTCPState)(0),                    // 1: v2ray.core.transport.internet.MPTCPState\n\t(SocketConfig_TCPFastOpenState)(0), // 2: v2ray.core.transport.internet.SocketConfig.TCPFastOpenState\n\t(SocketConfig_TProxyMode)(0),       // 3: v2ray.core.transport.internet.SocketConfig.TProxyMode\n\t(*TransportConfig)(nil),            // 4: v2ray.core.transport.internet.TransportConfig\n\t(*StreamConfig)(nil),               // 5: v2ray.core.transport.internet.StreamConfig\n\t(*ProxyConfig)(nil),                // 6: v2ray.core.transport.internet.ProxyConfig\n\t(*SocketConfig)(nil),               // 7: v2ray.core.transport.internet.SocketConfig\n\t(*anypb.Any)(nil),                  // 8: google.protobuf.Any\n}\nvar file_transport_internet_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.TransportConfig.protocol:type_name -> v2ray.core.transport.internet.TransportProtocol\n\t8, // 1: v2ray.core.transport.internet.TransportConfig.settings:type_name -> google.protobuf.Any\n\t0, // 2: v2ray.core.transport.internet.StreamConfig.protocol:type_name -> v2ray.core.transport.internet.TransportProtocol\n\t4, // 3: v2ray.core.transport.internet.StreamConfig.transport_settings:type_name -> v2ray.core.transport.internet.TransportConfig\n\t8, // 4: v2ray.core.transport.internet.StreamConfig.security_settings:type_name -> google.protobuf.Any\n\t7, // 5: v2ray.core.transport.internet.StreamConfig.socket_settings:type_name -> v2ray.core.transport.internet.SocketConfig\n\t2, // 6: v2ray.core.transport.internet.SocketConfig.tfo:type_name -> v2ray.core.transport.internet.SocketConfig.TCPFastOpenState\n\t3, // 7: v2ray.core.transport.internet.SocketConfig.tproxy:type_name -> v2ray.core.transport.internet.SocketConfig.TProxyMode\n\t1, // 8: v2ray.core.transport.internet.SocketConfig.mptcp:type_name -> v2ray.core.transport.internet.MPTCPState\n\t9, // [9:9] is the sub-list for method output_type\n\t9, // [9:9] is the sub-list for method input_type\n\t9, // [9:9] is the sub-list for extension type_name\n\t9, // [9:9] is the sub-list for extension extendee\n\t0, // [0:9] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_config_proto_init() }\nfunc file_transport_internet_config_proto_init() {\n\tif File_transport_internet_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_config_proto_rawDesc), len(file_transport_internet_config_proto_rawDesc)),\n\t\t\tNumEnums:      4,\n\t\t\tNumMessages:   4,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_config_proto_depIdxs,\n\t\tEnumInfos:         file_transport_internet_config_proto_enumTypes,\n\t\tMessageInfos:      file_transport_internet_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_config_proto = out.File\n\tfile_transport_internet_config_proto_goTypes = nil\n\tfile_transport_internet_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet\";\noption java_package = \"com.v2ray.core.transport.internet\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\n\nenum TransportProtocol {\n  TCP = 0;\n  UDP = 1;\n  MKCP = 2;\n  WebSocket = 3;\n  HTTP = 4;\n  DomainSocket = 5;\n}\n\nmessage TransportConfig {\n  // Type of network that this settings supports.\n  // Deprecated. Use the string form below.\n  TransportProtocol protocol = 1 [ deprecated = true ];\n\n  // Type of network that this settings supports.\n  string protocol_name = 3;\n\n  // Specific settings. Must be of the transports.\n  google.protobuf.Any settings = 2;\n}\n\nmessage StreamConfig {\n  // Effective network. Deprecated. Use the string form below.\n  TransportProtocol protocol = 1 [ deprecated = true ];\n\n  // Effective network.\n  string protocol_name = 5;\n\n  repeated TransportConfig transport_settings = 2;\n\n  // Type of security. Must be a message name of the settings proto.\n  string security_type = 3;\n\n  // Settings for transport security. For now the only choice is TLS.\n  repeated google.protobuf.Any security_settings = 4;\n\n  SocketConfig socket_settings = 6;\n}\n\nmessage ProxyConfig {\n  string tag = 1;\n\n  bool transportLayerProxy = 2;\n}\n\n// MPTCP is the state of MPTCP settings.\n// Define it here to avoid conflict with TCPFastOpenState.\nenum MPTCPState {\n  // AsIs is to leave the current MPTCP state as is, unmodified.\n  AsIs = 0;\n  // Enable is for enabling MPTCP explictly.\n  Enable = 1;\n  // Disable is for disabling MPTCP explictly.\n  Disable = 2;\n}\n\n// SocketConfig is options to be applied on network sockets.\nmessage SocketConfig {\n  // Mark of the connection. If non-zero, the value will be set to SO_MARK.\n  uint32 mark = 1;\n\n  enum TCPFastOpenState {\n    // AsIs is to leave the current TFO state as is, unmodified.\n    AsIs = 0;\n    // Enable is for enabling TFO explictly.\n    Enable = 1;\n    // Disable is for disabling TFO explictly.\n    Disable = 2;\n  }\n\n  // TFO is the state of TFO settings.\n  TCPFastOpenState tfo = 2;\n\n  enum TProxyMode {\n    // TProxy is off.\n    Off = 0;\n    // TProxy mode.\n    TProxy = 1;\n    // Redirect mode.\n    Redirect = 2;\n  }\n\n  // TProxy is for enabling TProxy socket option.\n  TProxyMode tproxy = 3;\n\n  // ReceiveOriginalDestAddress is for enabling IP_RECVORIGDSTADDR socket\n  // option. This option is for UDP only.\n  bool receive_original_dest_address = 4;\n\n  bytes bind_address = 5;\n\n  uint32 bind_port = 6;\n\n  bool accept_proxy_protocol = 7;\n\n  int32 tcp_keep_alive_interval = 8;\n\n  uint32 tfo_queue_length = 9;\n\n  int32 tcp_keep_alive_idle = 10;\n\n  string bind_to_device = 11;\n\n  int64 rx_buf_size = 12;\n  int64 tx_buf_size = 13;\n  bool force_buf_size = 14;\n\n\n  MPTCPState mptcp = 15;\n}\n"
  },
  {
    "path": "transport/internet/connection.go",
    "content": "package internet\n\nimport (\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\ntype Connection interface {\n\tnet.Conn\n}\n\ntype AbstractPacketConnReader interface {\n\tReadFrom(p []byte) (n int, addr net.Addr, err error)\n}\n\ntype AbstractPacketConnWriter interface {\n\tWriteTo(p []byte, addr net.Addr) (n int, err error)\n}\n\ntype AbstractPacketConn interface {\n\tAbstractPacketConnReader\n\tAbstractPacketConnWriter\n\tcommon.Closable\n}\n\ntype PacketConn interface {\n\tAbstractPacketConn\n\tnet.PacketConn\n}\n\ntype StatCouterConnection struct {\n\tConnection\n\tReadCounter  stats.Counter\n\tWriteCounter stats.Counter\n}\n\nfunc (c *StatCouterConnection) Read(b []byte) (int, error) {\n\tnBytes, err := c.Connection.Read(b)\n\tif c.ReadCounter != nil {\n\t\tc.ReadCounter.Add(int64(nBytes))\n\t}\n\n\treturn nBytes, err\n}\n\nfunc (c *StatCouterConnection) Write(b []byte) (int, error) {\n\tnBytes, err := c.Connection.Write(b)\n\tif c.WriteCounter != nil {\n\t\tc.WriteCounter.Add(int64(nBytes))\n\t}\n\treturn nBytes, err\n}\n"
  },
  {
    "path": "transport/internet/dialer.go",
    "content": "package internet\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\n// Dialer is the interface for dialing outbound connections.\ntype Dialer interface {\n\t// Dial dials a system connection to the given destination.\n\tDial(ctx context.Context, destination net.Destination) (Connection, error)\n\n\t// Address returns the address used by this Dialer. Maybe nil if not known.\n\tAddress() net.Address\n}\n\n// dialFunc is an interface to dial network connection to a specific destination.\ntype dialFunc func(ctx context.Context, dest net.Destination, streamSettings *MemoryStreamConfig) (Connection, error)\n\nvar transportDialerCache = make(map[string]dialFunc)\n\n// RegisterTransportDialer registers a Dialer with given name.\nfunc RegisterTransportDialer(protocol string, dialer dialFunc) error {\n\tif _, found := transportDialerCache[protocol]; found {\n\t\treturn newError(protocol, \" dialer already registered\").AtError()\n\t}\n\ttransportDialerCache[protocol] = dialer\n\treturn nil\n}\n\n// Dial dials a internet connection towards the given destination.\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *MemoryStreamConfig) (Connection, error) {\n\tif dest.Network == net.Network_TCP {\n\t\tif streamSettings == nil {\n\t\t\ts, err := ToMemoryStreamConfig(nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to create default stream settings\").Base(err)\n\t\t\t}\n\t\t\tstreamSettings = s\n\t\t}\n\n\t\tprotocol := streamSettings.ProtocolName\n\n\t\tif originalProtocolName := getOriginalMessageName(streamSettings); originalProtocolName != \"\" {\n\t\t\tprotocol = originalProtocolName\n\t\t}\n\n\t\tdialer := transportDialerCache[protocol]\n\t\tif dialer == nil {\n\t\t\treturn nil, newError(protocol, \" dialer not registered\").AtError()\n\t\t}\n\t\treturn dialer(ctx, dest, streamSettings)\n\t}\n\n\tif dest.Network == net.Network_UDP {\n\t\tudpDialer := transportDialerCache[\"udp\"]\n\t\tif udpDialer == nil {\n\t\t\treturn nil, newError(\"UDP dialer not registered\").AtError()\n\t\t}\n\t\treturn udpDialer(ctx, dest, streamSettings)\n\t}\n\n\treturn nil, newError(\"unknown network \", dest.Network)\n}\n\n// DialSystem calls system dialer to create a network connection.\nfunc DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {\n\toutbound := session.OutboundFromContext(ctx)\n\n\tvar src net.Address\n\tif outbound != nil {\n\t\tsrc = outbound.Gateway\n\t}\n\n\tif transportLayerOutgoingTag := session.GetTransportLayerProxyTagFromContext(ctx); transportLayerOutgoingTag != \"\" {\n\t\treturn DialTaggedOutbound(ctx, dest, transportLayerOutgoingTag)\n\t}\n\n\toriginalAddr := dest.Address\n\tif outbound != nil && outbound.Resolver != nil && dest.Address.Family().IsDomain() {\n\t\tif addr := outbound.Resolver(ctx, dest.Address.Domain()); addr != nil {\n\t\t\tdest.Address = addr\n\t\t}\n\t}\n\n\tswitch {\n\tcase src != nil && dest.Address != originalAddr:\n\t\tnewError(\"dialing to \", dest, \" resolved from \", originalAddr, \" via \", src).WriteToLog(session.ExportIDToError(ctx))\n\tcase src != nil:\n\t\tnewError(\"dialing to \", dest, \" via \", src).WriteToLog(session.ExportIDToError(ctx))\n\tcase dest.Address != originalAddr:\n\t\tnewError(\"dialing to \", dest, \" resolved from \", originalAddr).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\treturn effectiveSystemDialer.Dial(ctx, src, dest, sockopt)\n}\n\nfunc DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) {\n\tif tagged.Dialer == nil {\n\t\treturn nil, newError(\"tagged dial not enabled\")\n\t}\n\treturn tagged.Dialer(ctx, dest, tag)\n}\n"
  },
  {
    "path": "transport/internet/dialer_test.go",
    "content": "package internet_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc TestDialWithLocalAddr(t *testing.T) {\n\tserver := &tcp.Server{}\n\tdest, err := server.Start()\n\tcommon.Must(err)\n\tdefer server.Close()\n\n\tconn, err := DialSystem(context.Background(), net.TCPDestination(net.LocalHostIP, dest.Port), nil)\n\tcommon.Must(err)\n\tif r := cmp.Diff(conn.RemoteAddr().String(), \"127.0.0.1:\"+dest.Port.String()); r != \"\" {\n\t\tt.Error(r)\n\t}\n\tconn.Close()\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/config.go",
    "content": "package domainsocket\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst (\n\tprotocolName  = \"domainsocket\"\n\tsizeofSunPath = 108\n)\n\nfunc (c *Config) GetUnixAddr() (*net.UnixAddr, error) {\n\tpath := c.Path\n\tif path == \"\" {\n\t\treturn nil, newError(\"empty domain socket path\")\n\t}\n\tif c.Abstract && path[0] != '\\x00' {\n\t\tpath = \"\\x00\" + path\n\t}\n\tif c.Abstract && c.Padding {\n\t\traw := []byte(path)\n\t\taddr := make([]byte, sizeofSunPath)\n\t\tcopy(addr, raw)\n\t\tpath = string(addr)\n\t}\n\treturn &net.UnixAddr{\n\t\tName: path,\n\t\tNet:  \"unix\",\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/config.pb.go",
    "content": "package domainsocket\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Path of the domain socket. This overrides the IP/Port parameter from\n\t// upstream caller.\n\tPath string `protobuf:\"bytes,1,opt,name=path,proto3\" json:\"path,omitempty\"`\n\t// Abstract specifies whether to use abstract namespace or not.\n\t// Traditionally Unix domain socket is file system based. Abstract domain\n\t// socket can be used without acquiring file lock.\n\tAbstract bool `protobuf:\"varint,2,opt,name=abstract,proto3\" json:\"abstract,omitempty\"`\n\t// Some apps, eg. haproxy, use the full length of sockaddr_un.sun_path to\n\t// connect(2) or bind(2) when using abstract UDS.\n\tPadding       bool `protobuf:\"varint,3,opt,name=padding,proto3\" json:\"padding,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_domainsocket_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_domainsocket_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_domainsocket_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetAbstract() bool {\n\tif x != nil {\n\t\treturn x.Abstract\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetPadding() bool {\n\tif x != nil {\n\t\treturn x.Padding\n\t}\n\treturn false\n}\n\nvar File_transport_internet_domainsocket_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_domainsocket_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\",transport/internet/domainsocket/config.proto\\x12*v2ray.core.transport.internet.domainsocket\\x1a common/protoext/extensions.proto\\\"q\\n\" +\n\t\"\\x06Config\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x01 \\x01(\\tR\\x04path\\x12\\x1a\\n\" +\n\t\"\\babstract\\x18\\x02 \\x01(\\bR\\babstract\\x12\\x18\\n\" +\n\t\"\\apadding\\x18\\x03 \\x01(\\bR\\apadding:\\x1d\\x82\\xb5\\x18\\x19\\n\" +\n\t\"\\ttransport\\x12\\fdomainsocketB\\x9f\\x01\\n\" +\n\t\".com.v2ray.core.transport.internet.domainsocketP\\x01Z>github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket\\xaa\\x02*V2Ray.Core.Transport.Internet.DomainSocketb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_domainsocket_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_domainsocket_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_domainsocket_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_domainsocket_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_domainsocket_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_domainsocket_config_proto_rawDesc), len(file_transport_internet_domainsocket_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_domainsocket_config_proto_rawDescData\n}\n\nvar file_transport_internet_domainsocket_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_domainsocket_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.transport.internet.domainsocket.Config\n}\nvar file_transport_internet_domainsocket_config_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_transport_internet_domainsocket_config_proto_init() }\nfunc file_transport_internet_domainsocket_config_proto_init() {\n\tif File_transport_internet_domainsocket_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_domainsocket_config_proto_rawDesc), len(file_transport_internet_domainsocket_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_domainsocket_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_domainsocket_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_domainsocket_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_domainsocket_config_proto = out.File\n\tfile_transport_internet_domainsocket_config_proto_goTypes = nil\n\tfile_transport_internet_domainsocket_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.domainsocket;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.DomainSocket\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket\";\noption java_package = \"com.v2ray.core.transport.internet.domainsocket\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"domainsocket\";\n\n  // Path of the domain socket. This overrides the IP/Port parameter from\n  // upstream caller.\n  string path = 1;\n  // Abstract specifies whether to use abstract namespace or not.\n  // Traditionally Unix domain socket is file system based. Abstract domain\n  // socket can be used without acquiring file lock.\n  bool abstract = 2;\n  // Some apps, eg. haproxy, use the full length of sockaddr_un.sun_path to\n  // connect(2) or bind(2) when using abstract UDS.\n  bool padding = 3;\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/dial.go",
    "content": "//go:build !windows && !wasm\n// +build !windows,!wasm\n\npackage domainsocket\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tsettings := streamSettings.ProtocolSettings.(*Config)\n\taddr, err := settings.GetUnixAddr()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconn, err := net.DialUnix(\"unix\", nil, addr)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial unix: \", settings.Path).Base(err).AtWarning()\n\t}\n\n\tif config := tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\treturn tls.Client(conn, config.GetTLSConfig(tls.WithDestination(dest))), nil\n\t}\n\n\treturn conn, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/errgen.go",
    "content": "package domainsocket\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/domainsocket/errors.generated.go",
    "content": "package domainsocket\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/listener.go",
    "content": "//go:build !windows && !wasm\n// +build !windows,!wasm\n\npackage domainsocket\n\nimport (\n\t\"context\"\n\tgotls \"crypto/tls\"\n\t\"os\"\n\t\"strings\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\ntype Listener struct {\n\taddr      *net.UnixAddr\n\tln        net.Listener\n\ttlsConfig *gotls.Config\n\tconfig    *Config\n\taddConn   internet.ConnHandler\n\tlocker    *fileLocker\n}\n\nfunc Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {\n\tsettings := streamSettings.ProtocolSettings.(*Config)\n\taddr, err := settings.GetUnixAddr()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tunixListener, err := net.ListenUnix(\"unix\", addr)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to listen domain socket\").Base(err).AtWarning()\n\t}\n\n\tln := &Listener{\n\t\taddr:    addr,\n\t\tln:      unixListener,\n\t\tconfig:  settings,\n\t\taddConn: handler,\n\t}\n\n\tif !settings.Abstract {\n\t\tln.locker = &fileLocker{\n\t\t\tpath: settings.Path + \".lock\",\n\t\t}\n\t\tif err := ln.locker.Acquire(); err != nil {\n\t\t\tunixListener.Close()\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif config := tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\tln.tlsConfig = config.GetTLSConfig()\n\t}\n\n\tgo ln.run()\n\n\treturn ln, nil\n}\n\nfunc (ln *Listener) Addr() net.Addr {\n\treturn ln.addr\n}\n\nfunc (ln *Listener) Close() error {\n\tif ln.locker != nil {\n\t\tln.locker.Release()\n\t}\n\treturn ln.ln.Close()\n}\n\nfunc (ln *Listener) run() {\n\tfor {\n\t\tconn, err := ln.ln.Accept()\n\t\tif err != nil {\n\t\t\tif strings.Contains(err.Error(), \"closed\") {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnewError(\"failed to accepted raw connections\").Base(err).AtWarning().WriteToLog()\n\t\t\tcontinue\n\t\t}\n\n\t\tif ln.tlsConfig != nil {\n\t\t\tconn = tls.Server(conn, ln.tlsConfig)\n\t\t}\n\n\t\tln.addConn(internet.Connection(conn))\n\t}\n}\n\ntype fileLocker struct {\n\tpath string\n\tfile *os.File\n}\n\nfunc (fl *fileLocker) Acquire() error {\n\tf, err := os.Create(fl.path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := unix.Flock(int(f.Fd()), unix.LOCK_EX); err != nil {\n\t\tf.Close()\n\t\treturn newError(\"failed to lock file: \", fl.path).Base(err)\n\t}\n\tfl.file = f\n\treturn nil\n}\n\nfunc (fl *fileLocker) Release() {\n\tif err := unix.Flock(int(fl.file.Fd()), unix.LOCK_UN); err != nil {\n\t\tnewError(\"failed to unlock file: \", fl.path).Base(err).WriteToLog()\n\t}\n\tif err := fl.file.Close(); err != nil {\n\t\tnewError(\"failed to close file: \", fl.path).Base(err).WriteToLog()\n\t}\n\tif err := os.Remove(fl.path); err != nil {\n\t\tnewError(\"failed to remove file: \", fl.path).Base(err).WriteToLog()\n\t}\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, Listen))\n}\n"
  },
  {
    "path": "transport/internet/domainsocket/listener_test.go",
    "content": "//go:build !windows && !android\n// +build !windows,!android\n\npackage domainsocket_test\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket\"\n)\n\nfunc TestListen(t *testing.T) {\n\tctx := context.Background()\n\tstreamSettings := &internet.MemoryStreamConfig{\n\t\tProtocolName: \"domainsocket\",\n\t\tProtocolSettings: &Config{\n\t\t\tPath: \"/tmp/ts3\",\n\t\t},\n\t}\n\tlistener, err := Listen(ctx, nil, net.Port(0), streamSettings, func(conn internet.Connection) {\n\t\tdefer conn.Close()\n\n\t\tb := buf.New()\n\t\tdefer b.Release()\n\t\tcommon.Must2(b.ReadFrom(conn))\n\t\tb.WriteString(\"Response\")\n\n\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t})\n\tcommon.Must(err)\n\tdefer listener.Close()\n\n\tconn, err := Dial(ctx, net.Destination{}, streamSettings)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tcommon.Must2(conn.Write([]byte(\"Request\")))\n\n\tb := buf.New()\n\tdefer b.Release()\n\tcommon.Must2(b.ReadFrom(conn))\n\n\tif b.String() != \"RequestResponse\" {\n\t\tt.Error(\"expected response as 'RequestResponse' but got \", b.String())\n\t}\n}\n\nfunc TestListenAbstract(t *testing.T) {\n\tif runtime.GOOS != \"linux\" {\n\t\treturn\n\t}\n\n\tctx := context.Background()\n\tstreamSettings := &internet.MemoryStreamConfig{\n\t\tProtocolName: \"domainsocket\",\n\t\tProtocolSettings: &Config{\n\t\t\tPath:     \"/tmp/ts3\",\n\t\t\tAbstract: true,\n\t\t},\n\t}\n\tlistener, err := Listen(ctx, nil, net.Port(0), streamSettings, func(conn internet.Connection) {\n\t\tdefer conn.Close()\n\n\t\tb := buf.New()\n\t\tdefer b.Release()\n\t\tcommon.Must2(b.ReadFrom(conn))\n\t\tb.WriteString(\"Response\")\n\n\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t})\n\tcommon.Must(err)\n\tdefer listener.Close()\n\n\tconn, err := Dial(ctx, net.Destination{}, streamSettings)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tcommon.Must2(conn.Write([]byte(\"Request\")))\n\n\tb := buf.New()\n\tdefer b.Release()\n\tcommon.Must2(b.ReadFrom(conn))\n\n\tif b.String() != \"RequestResponse\" {\n\t\tt.Error(\"expected response as 'RequestResponse' but got \", b.String())\n\t}\n}\n"
  },
  {
    "path": "transport/internet/dtls/config.pb.go",
    "content": "package dtls\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 DTLSMode int32\n\nconst (\n\tDTLSMode_INVALID DTLSMode = 0\n\tDTLSMode_PSK     DTLSMode = 1\n)\n\n// Enum value maps for DTLSMode.\nvar (\n\tDTLSMode_name = map[int32]string{\n\t\t0: \"INVALID\",\n\t\t1: \"PSK\",\n\t}\n\tDTLSMode_value = map[string]int32{\n\t\t\"INVALID\": 0,\n\t\t\"PSK\":     1,\n\t}\n)\n\nfunc (x DTLSMode) Enum() *DTLSMode {\n\tp := new(DTLSMode)\n\t*p = x\n\treturn p\n}\n\nfunc (x DTLSMode) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (DTLSMode) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_dtls_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (DTLSMode) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_dtls_config_proto_enumTypes[0]\n}\n\nfunc (x DTLSMode) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use DTLSMode.Descriptor instead.\nfunc (DTLSMode) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_dtls_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Config struct {\n\tstate                  protoimpl.MessageState `protogen:\"open.v1\"`\n\tMode                   DTLSMode               `protobuf:\"varint,1,opt,name=mode,proto3,enum=v2ray.core.transport.internet.dtls.DTLSMode\" json:\"mode,omitempty\"`\n\tPsk                    []byte                 `protobuf:\"bytes,2,opt,name=psk,proto3\" json:\"psk,omitempty\"`\n\tMtu                    uint32                 `protobuf:\"varint,3,opt,name=mtu,proto3\" json:\"mtu,omitempty\"`\n\tReplayProtectionWindow uint32                 `protobuf:\"varint,4,opt,name=replay_protection_window,json=replayProtectionWindow,proto3\" json:\"replay_protection_window,omitempty\"`\n\tunknownFields          protoimpl.UnknownFields\n\tsizeCache              protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_dtls_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_dtls_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_dtls_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetMode() DTLSMode {\n\tif x != nil {\n\t\treturn x.Mode\n\t}\n\treturn DTLSMode_INVALID\n}\n\nfunc (x *Config) GetPsk() []byte {\n\tif x != nil {\n\t\treturn x.Psk\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetMtu() uint32 {\n\tif x != nil {\n\t\treturn x.Mtu\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetReplayProtectionWindow() uint32 {\n\tif x != nil {\n\t\treturn x.ReplayProtectionWindow\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_dtls_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_dtls_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$transport/internet/dtls/config.proto\\x12\\\"v2ray.core.transport.internet.dtls\\x1a common/protoext/extensions.proto\\\"\\xbf\\x01\\n\" +\n\t\"\\x06Config\\x12@\\n\" +\n\t\"\\x04mode\\x18\\x01 \\x01(\\x0e2,.v2ray.core.transport.internet.dtls.DTLSModeR\\x04mode\\x12\\x10\\n\" +\n\t\"\\x03psk\\x18\\x02 \\x01(\\fR\\x03psk\\x12\\x10\\n\" +\n\t\"\\x03mtu\\x18\\x03 \\x01(\\rR\\x03mtu\\x128\\n\" +\n\t\"\\x18replay_protection_window\\x18\\x04 \\x01(\\rR\\x16replayProtectionWindow:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\ttransport\\x12\\x04dtls* \\n\" +\n\t\"\\bDTLSMode\\x12\\v\\n\" +\n\t\"\\aINVALID\\x10\\x00\\x12\\a\\n\" +\n\t\"\\x03PSK\\x10\\x01B\\x87\\x01\\n\" +\n\t\"&com.v2ray.core.transport.internet.dtlsP\\x01Z6github.com/v2fly/v2ray-core/v5/transport/internet/dtls\\xaa\\x02\\\"V2Ray.Core.Transport.Internet.Dtlsb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_dtls_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_dtls_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_dtls_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_dtls_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_dtls_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_dtls_config_proto_rawDesc), len(file_transport_internet_dtls_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_dtls_config_proto_rawDescData\n}\n\nvar file_transport_internet_dtls_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_transport_internet_dtls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_dtls_config_proto_goTypes = []any{\n\t(DTLSMode)(0),  // 0: v2ray.core.transport.internet.dtls.DTLSMode\n\t(*Config)(nil), // 1: v2ray.core.transport.internet.dtls.Config\n}\nvar file_transport_internet_dtls_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.dtls.Config.mode:type_name -> v2ray.core.transport.internet.dtls.DTLSMode\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_dtls_config_proto_init() }\nfunc file_transport_internet_dtls_config_proto_init() {\n\tif File_transport_internet_dtls_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_dtls_config_proto_rawDesc), len(file_transport_internet_dtls_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_dtls_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_dtls_config_proto_depIdxs,\n\t\tEnumInfos:         file_transport_internet_dtls_config_proto_enumTypes,\n\t\tMessageInfos:      file_transport_internet_dtls_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_dtls_config_proto = out.File\n\tfile_transport_internet_dtls_config_proto_goTypes = nil\n\tfile_transport_internet_dtls_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/dtls/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.dtls;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Dtls\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/dtls\";\noption java_package = \"com.v2ray.core.transport.internet.dtls\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nenum DTLSMode {\n  INVALID = 0;\n  PSK = 1;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"dtls\";\n\n  DTLSMode mode = 1;\n  bytes psk = 2;\n\n  uint32 mtu = 3;\n  uint32 replay_protection_window = 4;\n}"
  },
  {
    "path": "transport/internet/dtls/dialer.go",
    "content": "package dtls\n\nimport (\n\t\"context\"\n\n\t\"github.com/pion/dtls/v2\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc dialDTLS(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {\n\ttransportConfiguration := streamSettings.ProtocolSettings.(*Config)\n\n\tnewError(\"dialing DTLS to \", dest).WriteToLog()\n\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.Dialer()\n\n\trawConn, err := dialer.Dial(ctx, nil, dest, streamSettings.SocketSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial to dest: \", err).AtWarning().Base(err)\n\t}\n\tconfig := &dtls.Config{}\n\tconfig.MTU = int(transportConfiguration.Mtu)\n\tconfig.ReplayProtectionWindow = int(transportConfiguration.ReplayProtectionWindow)\n\n\tswitch transportConfiguration.Mode {\n\tcase DTLSMode_PSK:\n\t\tconfig.PSK = func(bytes []byte) ([]byte, error) {\n\t\t\treturn transportConfiguration.Psk, nil\n\t\t}\n\t\tconfig.PSKIdentityHint = []byte(\"\")\n\t\tconfig.CipherSuites = []dtls.CipherSuiteID{dtls.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256}\n\tdefault:\n\t\treturn nil, newError(\"unknow dtls mode\")\n\t}\n\treturn dtls.Client(rawConn, config)\n}\n\nfunc dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tnewError(\"creating connection to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tconn, err := dialDTLS(ctx, dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial request to \", dest).Base(err)\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, dial))\n}\n"
  },
  {
    "path": "transport/internet/dtls/dtls.go",
    "content": "package dtls\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst protocolName = \"dtls\"\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/dtls/errors.generated.go",
    "content": "package dtls\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/dtls/listener.go",
    "content": "package dtls\n\nimport (\n\t\"context\"\n\t\"io\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pion/dtls/v2\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\ntype Listener struct {\n\tconfig *Config\n\n\tsync.Mutex\n\taddConn internet.ConnHandler\n\thub     *udp.Hub\n\n\tsessions map[ConnectionID]*dTLSConnWrapped\n}\n\nfunc (l *Listener) Close() error {\n\treturn l.hub.Close()\n}\n\nfunc (l *Listener) Addr() net.Addr {\n\treturn l.hub.Addr()\n}\n\ntype ConnectionID struct {\n\tRemote net.Address\n\tPort   net.Port\n}\n\nfunc newDTLSServerConn(src net.Destination, parent *Listener) *dTLSConn {\n\tctx := context.Background()\n\tctx, finish := context.WithCancel(ctx)\n\treturn &dTLSConn{\n\t\tsrc:      src,\n\t\tparent:   parent,\n\t\treadChan: make(chan *buf.Buffer, 256),\n\t\tctx:      ctx,\n\t\tfinish:   finish,\n\t}\n}\n\ntype dTLSConnWrapped struct {\n\tunencryptedConn *dTLSConn\n\tdTLSConn        *dtls.Conn\n}\n\ntype dTLSConn struct {\n\tsrc    net.Destination\n\tparent *Listener\n\n\treadChan chan *buf.Buffer\n\tctx      context.Context\n\tfinish   func()\n}\n\nfunc (l *dTLSConn) Read(b []byte) (n int, err error) {\n\tselect {\n\tcase pack := <-l.readChan:\n\t\tn := copy(b, pack.Bytes())\n\t\tdefer pack.Release()\n\t\tif n < int(pack.Len()) {\n\t\t\treturn n, io.ErrShortBuffer\n\t\t}\n\t\treturn n, nil\n\tcase <-l.ctx.Done():\n\t\treturn 0, l.ctx.Err()\n\t}\n}\n\nfunc (l *dTLSConn) Write(b []byte) (n int, err error) {\n\treturn l.parent.hub.WriteTo(b, l.src)\n}\n\nfunc (l *dTLSConn) Close() error {\n\tl.finish()\n\tl.parent.Remove(l.src)\n\treturn nil\n}\n\nfunc (l *dTLSConn) LocalAddr() gonet.Addr {\n\treturn nil\n}\n\nfunc (l *dTLSConn) RemoteAddr() gonet.Addr {\n\treturn &net.UDPAddr{\n\t\tIP:   l.src.Address.IP(),\n\t\tPort: int(l.src.Port.Value()),\n\t}\n}\n\nfunc (l *dTLSConn) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (l *dTLSConn) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (l *dTLSConn) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (l *dTLSConn) OnReceive(payload *buf.Buffer) {\n\tselect {\n\tcase l.readChan <- payload:\n\tdefault:\n\t}\n}\n\nfunc NewListener(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (*Listener, error) {\n\ttransportConfiguration := streamSettings.ProtocolSettings.(*Config)\n\thub, err := udp.ListenUDP(ctx, address, port, streamSettings, udp.HubCapacity(1024))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tl := &Listener{\n\t\taddConn:  addConn,\n\t\tconfig:   transportConfiguration,\n\t\tsessions: make(map[ConnectionID]*dTLSConnWrapped),\n\t}\n\tl.Lock()\n\tl.hub = hub\n\tl.Unlock()\n\tnewError(\"listening on \", address, \":\", port).WriteToLog()\n\n\tgo l.handlePackets()\n\treturn l, err\n}\n\nfunc (l *Listener) handlePackets() {\n\treceive := l.hub.Receive()\n\tfor payload := range receive {\n\t\tl.OnReceive(payload.Payload, payload.Source)\n\t}\n}\n\nfunc newDTLSConnWrapped(unencryptedConnection *dTLSConn, transportConfiguration *Config) (*dtls.Conn, error) {\n\tconfig := &dtls.Config{}\n\tconfig.MTU = int(transportConfiguration.Mtu)\n\tconfig.ReplayProtectionWindow = int(transportConfiguration.ReplayProtectionWindow)\n\n\tswitch transportConfiguration.Mode {\n\tcase DTLSMode_PSK:\n\t\tconfig.PSK = func(bytes []byte) ([]byte, error) {\n\t\t\treturn transportConfiguration.Psk, nil\n\t\t}\n\t\tconfig.PSKIdentityHint = []byte(\"\")\n\t\tconfig.CipherSuites = []dtls.CipherSuiteID{dtls.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256}\n\tdefault:\n\t\tnewError(\"unknown dtls mode\").WriteToLog()\n\t}\n\tdtlsConn, err := dtls.Server(unencryptedConnection, config)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create dtls server conn\").Base(err)\n\t}\n\treturn dtlsConn, err\n}\n\nfunc (l *Listener) OnReceive(payload *buf.Buffer, src net.Destination) {\n\tid := ConnectionID{\n\t\tRemote: src.Address,\n\t\tPort:   src.Port,\n\t}\n\tl.Lock()\n\tdefer l.Unlock()\n\tconn, found := l.sessions[id]\n\tif !found {\n\t\tvar err error\n\t\tunEncryptedConn := newDTLSServerConn(src, l)\n\t\tconn = &dTLSConnWrapped{unencryptedConn: unEncryptedConn}\n\t\tl.sessions[id] = conn\n\t\tgo func() {\n\t\t\tconn.dTLSConn, err = newDTLSConnWrapped(unEncryptedConn, l.config)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"unable to accept new dtls connection\").Base(err).WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tl.addConn(internet.Connection(conn.dTLSConn))\n\t\t}()\n\t}\n\tconn.unencryptedConn.OnReceive(payload)\n}\n\nfunc (l *Listener) Remove(src net.Destination) {\n\tl.Lock()\n\tdefer l.Unlock()\n\tid := ConnectionID{\n\t\tRemote: src.Address,\n\t\tPort:   src.Port,\n\t}\n\tdelete(l.sessions, id)\n}\n\nfunc ListenDTLS(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {\n\treturn NewListener(ctx, address, port, streamSettings, addConn)\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, ListenDTLS))\n}\n"
  },
  {
    "path": "transport/internet/errors.generated.go",
    "content": "package internet\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/filelocker.go",
    "content": "package internet\n\nimport (\n\t\"os\"\n)\n\n// FileLocker is UDS access lock\ntype FileLocker struct {\n\tpath string\n\tfile *os.File\n}\n"
  },
  {
    "path": "transport/internet/filelocker_other.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage internet\n\nimport (\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// Acquire lock\nfunc (fl *FileLocker) Acquire() error {\n\tf, err := os.Create(fl.path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := unix.Flock(int(f.Fd()), unix.LOCK_EX); err != nil {\n\t\tf.Close()\n\t\treturn newError(\"failed to lock file: \", fl.path).Base(err)\n\t}\n\tfl.file = f\n\treturn nil\n}\n\n// Release lock\nfunc (fl *FileLocker) Release() {\n\tif err := unix.Flock(int(fl.file.Fd()), unix.LOCK_UN); err != nil {\n\t\tnewError(\"failed to unlock file: \", fl.path).Base(err).WriteToLog()\n\t}\n\tif err := fl.file.Close(); err != nil {\n\t\tnewError(\"failed to close file: \", fl.path).Base(err).WriteToLog()\n\t}\n\tif err := os.Remove(fl.path); err != nil {\n\t\tnewError(\"failed to remove file: \", fl.path).Base(err).WriteToLog()\n\t}\n}\n"
  },
  {
    "path": "transport/internet/filelocker_windows.go",
    "content": "package internet\n\n// Acquire lock\nfunc (fl *FileLocker) Acquire() error {\n\treturn nil\n}\n\n// Release lock\nfunc (fl *FileLocker) Release() {\n\treturn\n}\n"
  },
  {
    "path": "transport/internet/grpc/config.go",
    "content": "package grpc\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst protocolName = \"gun\"\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/grpc/config.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.11\n// \tprotoc        v6.33.1\n// source: transport/internet/grpc/config.proto\n\npackage grpc\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate               protoimpl.MessageState `protogen:\"open.v1\"`\n\tHost                string                 `protobuf:\"bytes,1,opt,name=host,proto3\" json:\"host,omitempty\"`\n\tServiceName         string                 `protobuf:\"bytes,2,opt,name=service_name,json=serviceName,proto3\" json:\"service_name,omitempty\"`\n\tIdleTimeout         int32                  `protobuf:\"varint,3,opt,name=idle_timeout,json=idleTimeout,proto3\" json:\"idle_timeout,omitempty\"`\n\tHealthCheckTimeout  int32                  `protobuf:\"varint,4,opt,name=health_check_timeout,json=healthCheckTimeout,proto3\" json:\"health_check_timeout,omitempty\"`\n\tPermitWithoutStream bool                   `protobuf:\"varint,5,opt,name=permit_without_stream,json=permitWithoutStream,proto3\" json:\"permit_without_stream,omitempty\"`\n\tInitialWindowsSize  int32                  `protobuf:\"varint,6,opt,name=initial_windows_size,json=initialWindowsSize,proto3\" json:\"initial_windows_size,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_grpc_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_grpc_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_grpc_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetHost() string {\n\tif x != nil {\n\t\treturn x.Host\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetServiceName() string {\n\tif x != nil {\n\t\treturn x.ServiceName\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetIdleTimeout() int32 {\n\tif x != nil {\n\t\treturn x.IdleTimeout\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetHealthCheckTimeout() int32 {\n\tif x != nil {\n\t\treturn x.HealthCheckTimeout\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetPermitWithoutStream() bool {\n\tif x != nil {\n\t\treturn x.PermitWithoutStream\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetInitialWindowsSize() int32 {\n\tif x != nil {\n\t\treturn x.InitialWindowsSize\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_grpc_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_grpc_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$transport/internet/grpc/config.proto\\x12+v2ray.core.transport.internet.grpc.encoding\\x1a common/protoext/extensions.proto\\\"\\x9c\\x02\\n\" +\n\t\"\\x06Config\\x12\\x12\\n\" +\n\t\"\\x04host\\x18\\x01 \\x01(\\tR\\x04host\\x12!\\n\" +\n\t\"\\fservice_name\\x18\\x02 \\x01(\\tR\\vserviceName\\x12!\\n\" +\n\t\"\\fidle_timeout\\x18\\x03 \\x01(\\x05R\\vidleTimeout\\x120\\n\" +\n\t\"\\x14health_check_timeout\\x18\\x04 \\x01(\\x05R\\x12healthCheckTimeout\\x122\\n\" +\n\t\"\\x15permit_without_stream\\x18\\x05 \\x01(\\bR\\x13permitWithoutStream\\x120\\n\" +\n\t\"\\x14initial_windows_size\\x18\\x06 \\x01(\\x05R\\x12initialWindowsSize: \\x82\\xb5\\x18\\x1c\\n\" +\n\t\"\\ttransport\\x12\\x04grpc\\x8a\\xff)\\x03gun\\x90\\xff)\\x01B\\x85\\x01\\n\" +\n\t\"&com.v2ray.core.transport.internet.grpcZ6github.com/v2fly/v2ray-core/v5/transport/internet/grpc\\xaa\\x02\\\"V2Ray.Core.Transport.Internet.Grpcb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_grpc_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_grpc_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_grpc_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_grpc_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_grpc_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_grpc_config_proto_rawDesc), len(file_transport_internet_grpc_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_grpc_config_proto_rawDescData\n}\n\nvar file_transport_internet_grpc_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_grpc_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.transport.internet.grpc.encoding.Config\n}\nvar file_transport_internet_grpc_config_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_transport_internet_grpc_config_proto_init() }\nfunc file_transport_internet_grpc_config_proto_init() {\n\tif File_transport_internet_grpc_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_grpc_config_proto_rawDesc), len(file_transport_internet_grpc_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_grpc_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_grpc_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_grpc_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_grpc_config_proto = out.File\n\tfile_transport_internet_grpc_config_proto_goTypes = nil\n\tfile_transport_internet_grpc_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/grpc/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.grpc.encoding;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Grpc\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/grpc\";\noption java_package = \"com.v2ray.core.transport.internet.grpc\";\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"grpc\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  option (v2ray.core.common.protoext.message_opt).transport_original_name = \"gun\";\n\n  string host = 1;\n  string service_name = 2;\n  int32 idle_timeout = 3;\n  int32 health_check_timeout = 4;\n  bool permit_without_stream = 5;\n  int32 initial_windows_size = 6;\n}"
  },
  {
    "path": "transport/internet/grpc/dial.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage grpc\n\nimport (\n\t\"context\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/backoff\"\n\t\"google.golang.org/grpc/connectivity\"\n\t\"google.golang.org/grpc/credentials\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n\t\"google.golang.org/grpc/keepalive\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/grpc/encoding\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tnewError(\"creating connection to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tconn, err := dialgRPC(ctx, dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial Grpc\").Base(err)\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n\ntype transportConnectionState struct {\n\tscopedDialerMap    map[net.Destination]*grpc.ClientConn\n\tscopedDialerAccess sync.Mutex\n}\n\nfunc (t *transportConnectionState) IsTransientStorageLifecycleReceiver() {\n}\n\nfunc (t *transportConnectionState) Close() error {\n\tt.scopedDialerAccess.Lock()\n\tdefer t.scopedDialerAccess.Unlock()\n\tfor _, conn := range t.scopedDialerMap {\n\t\t_ = conn.Close()\n\t}\n\tt.scopedDialerMap = nil\n\treturn nil\n}\n\ntype dialerCanceller func()\n\nfunc dialgRPC(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {\n\tgrpcSettings := streamSettings.ProtocolSettings.(*Config)\n\n\tconn, canceller, err := getGrpcClient(ctx, dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"Cannot dial grpc\").Base(err)\n\t}\n\tclient := encoding.NewGunServiceClient(conn)\n\tgunService, err := client.(encoding.GunServiceClientX).TunCustomName(ctx, grpcSettings.ServiceName)\n\tif err != nil {\n\t\tcanceller()\n\t\treturn nil, newError(\"Cannot dial grpc\").Base(err)\n\t}\n\treturn encoding.NewGunConn(gunService, nil), nil\n}\n\nfunc getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (*grpc.ClientConn, dialerCanceller, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tstate, err := transportEnvironment.TransientStorage().Get(ctx, \"grpc-transport-connection-state\")\n\tgrpcSettings := streamSettings.ProtocolSettings.(*Config)\n\ttlsConfig := tls.ConfigFromStreamSettings(streamSettings)\n\ttransportCredentials := insecure.NewCredentials()\n\tif tlsConfig != nil {\n\t\ttransportCredentials = credentials.NewTLS(tlsConfig.GetTLSConfig(tls.WithDestination(dest)))\n\t}\n\tdialOptions := []grpc.DialOption{\n\t\tgrpc.WithTransportCredentials(transportCredentials),\n\t\tgrpc.WithConnectParams(grpc.ConnectParams{\n\t\t\tBackoff: backoff.Config{\n\t\t\t\tBaseDelay:  500 * time.Millisecond,\n\t\t\t\tMultiplier: 1.5,\n\t\t\t\tJitter:     0.2,\n\t\t\t\tMaxDelay:   19 * time.Second,\n\t\t\t},\n\t\t\tMinConnectTimeout: 5 * time.Second,\n\t\t}),\n\t\tgrpc.WithContextDialer(func(ctxGrpc context.Context, s string) (gonet.Conn, error) {\n\t\t\trawHost, rawPort, err := net.SplitHostPort(s)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif len(rawPort) == 0 {\n\t\t\t\trawPort = \"443\"\n\t\t\t}\n\t\t\tport, err := net.PortFromString(rawPort)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\taddress := net.ParseAddress(rawHost)\n\t\t\tdetachedContext := core.ToBackgroundDetachedContext(ctx)\n\t\t\treturn internet.DialSystem(detachedContext, net.TCPDestination(address, port), streamSettings.SocketSettings)\n\t\t}),\n\t\tgrpc.WithDisableServiceConfig(),\n\t}\n\tif grpcSettings.IdleTimeout > 0 || grpcSettings.HealthCheckTimeout > 0 || grpcSettings.PermitWithoutStream {\n\t\tdialOptions = append(dialOptions, grpc.WithKeepaliveParams(keepalive.ClientParameters{\n\t\t\tTime:                time.Second * time.Duration(grpcSettings.IdleTimeout),\n\t\t\tTimeout:             time.Second * time.Duration(grpcSettings.HealthCheckTimeout),\n\t\t\tPermitWithoutStream: grpcSettings.PermitWithoutStream,\n\t\t}))\n\t}\n\tif grpcSettings.InitialWindowsSize > 0 {\n\t\tdialOptions = append(dialOptions, grpc.WithInitialWindowSize(grpcSettings.InitialWindowsSize))\n\t}\n\tif err != nil {\n\t\tstate = &transportConnectionState{}\n\t\ttransportEnvironment.TransientStorage().Put(ctx, \"grpc-transport-connection-state\", state)\n\t\tstate, err = transportEnvironment.TransientStorage().Get(ctx, \"grpc-transport-connection-state\")\n\t\tif err != nil {\n\t\t\treturn nil, nil, newError(\"failed to get grpc transport connection state\").Base(err)\n\t\t}\n\t}\n\tstateTyped := state.(*transportConnectionState)\n\n\tstateTyped.scopedDialerAccess.Lock()\n\tdefer stateTyped.scopedDialerAccess.Unlock()\n\n\tif stateTyped.scopedDialerMap == nil {\n\t\tstateTyped.scopedDialerMap = make(map[net.Destination]*grpc.ClientConn)\n\t}\n\n\tcanceller := func() {\n\t\tstateTyped.scopedDialerAccess.Lock()\n\t\tdefer stateTyped.scopedDialerAccess.Unlock()\n\t\tdelete(stateTyped.scopedDialerMap, dest)\n\t}\n\n\tif client, found := stateTyped.scopedDialerMap[dest]; found && client.GetState() != connectivity.Shutdown {\n\t\treturn client, canceller, nil\n\t}\n\n\tconn, err := grpc.NewClient(\n\t\tdest.Address.String()+\":\"+dest.Port.String(),\n\t\tdialOptions...,\n\t)\n\tcanceller = func() {\n\t\tstateTyped.scopedDialerAccess.Lock()\n\t\tdefer stateTyped.scopedDialerAccess.Unlock()\n\t\tdelete(stateTyped.scopedDialerMap, dest)\n\t\tif err != nil {\n\t\t\tconn.Close()\n\t\t}\n\t}\n\tstateTyped.scopedDialerMap[dest] = conn\n\treturn conn, canceller, err\n}\n"
  },
  {
    "path": "transport/internet/grpc/encoding/conn.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage encoding\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"google.golang.org/grpc/peer\"\n)\n\n// GunService is the abstract interface of GunService_TunClient and GunService_TunServer\ntype GunService interface {\n\tContext() context.Context\n\tSend(*Hunk) error\n\tRecv() (*Hunk, error)\n}\n\n// GunConn implements net.Conn for gun tunnel\ntype GunConn struct {\n\tservice GunService\n\treader  io.Reader\n\tover    context.CancelFunc\n\tlocal   net.Addr\n\tremote  net.Addr\n}\n\n// Read implements net.Conn.Read()\nfunc (c *GunConn) Read(b []byte) (n int, err error) {\n\tif c.reader == nil {\n\t\th, err := c.service.Recv()\n\t\tif err != nil {\n\t\t\treturn 0, newError(\"unable to read from gun tunnel\").Base(err)\n\t\t}\n\t\tc.reader = bytes.NewReader(h.Data)\n\t}\n\tn, err = c.reader.Read(b)\n\tif err == io.EOF {\n\t\tc.reader = nil\n\t\treturn n, nil\n\t}\n\treturn n, err\n}\n\n// Write implements net.Conn.Write()\nfunc (c *GunConn) Write(b []byte) (n int, err error) {\n\terr = c.service.Send(&Hunk{Data: b})\n\tif err != nil {\n\t\treturn 0, newError(\"Unable to send data over gun\").Base(err)\n\t}\n\treturn len(b), nil\n}\n\n// Close implements net.Conn.Close()\nfunc (c *GunConn) Close() error {\n\tif c.over != nil {\n\t\tc.over()\n\t}\n\treturn nil\n}\n\n// LocalAddr implements net.Conn.LocalAddr()\nfunc (c *GunConn) LocalAddr() net.Addr {\n\treturn c.local\n}\n\n// RemoteAddr implements net.Conn.RemoteAddr()\nfunc (c *GunConn) RemoteAddr() net.Addr {\n\treturn c.remote\n}\n\n// SetDeadline implements net.Conn.SetDeadline()\nfunc (*GunConn) SetDeadline(time.Time) error {\n\treturn nil\n}\n\n// SetReadDeadline implements net.Conn.SetReadDeadline()\nfunc (*GunConn) SetReadDeadline(time.Time) error {\n\treturn nil\n}\n\n// SetWriteDeadline implements net.Conn.SetWriteDeadline()\nfunc (*GunConn) SetWriteDeadline(time.Time) error {\n\treturn nil\n}\n\n// NewGunConn creates GunConn which handles gun tunnel\nfunc NewGunConn(service GunService, over context.CancelFunc) *GunConn {\n\tconn := &GunConn{\n\t\tservice: service,\n\t\treader:  nil,\n\t\tover:    over,\n\t}\n\n\tconn.local = &net.TCPAddr{\n\t\tIP:   []byte{0, 0, 0, 0},\n\t\tPort: 0,\n\t}\n\tpr, ok := peer.FromContext(service.Context())\n\tif ok {\n\t\tconn.remote = pr.Addr\n\t} else {\n\t\tconn.remote = &net.TCPAddr{\n\t\t\tIP:   []byte{0, 0, 0, 0},\n\t\t\tPort: 0,\n\t\t}\n\t}\n\n\treturn conn\n}\n"
  },
  {
    "path": "transport/internet/grpc/encoding/customSeviceName.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage encoding\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n)\n\nfunc ServerDesc(name string) grpc.ServiceDesc {\n\treturn grpc.ServiceDesc{\n\t\tServiceName: name,\n\t\tHandlerType: (*GunServiceServer)(nil),\n\t\tMethods:     []grpc.MethodDesc{},\n\t\tStreams: []grpc.StreamDesc{\n\t\t\t{\n\t\t\t\tStreamName:    \"Tun\",\n\t\t\t\tHandler:       _GunService_Tun_Handler,\n\t\t\t\tServerStreams: true,\n\t\t\t\tClientStreams: true,\n\t\t\t},\n\t\t},\n\t\tMetadata: \"gun.proto\",\n\t}\n}\n\nfunc (c *gunServiceClient) TunCustomName(ctx context.Context, name string, opts ...grpc.CallOption) (GunService_TunClient, error) {\n\tstream, err := c.cc.NewStream(ctx, &ServerDesc(name).Streams[0], \"/\"+name+\"/Tun\", opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[Hunk, Hunk]{ClientStream: stream}\n\treturn x, nil\n}\n\ntype GunServiceClientX interface {\n\tTunCustomName(ctx context.Context, name string, opts ...grpc.CallOption) (GunService_TunClient, error)\n\tTun(ctx context.Context, opts ...grpc.CallOption) (GunService_TunClient, error)\n}\n\nfunc RegisterGunServiceServerX(s *grpc.Server, srv GunServiceServer, name string) {\n\tdesc := ServerDesc(name)\n\ts.RegisterService(&desc, srv)\n}\n"
  },
  {
    "path": "transport/internet/grpc/encoding/encoding.go",
    "content": "package encoding\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/grpc/encoding/errors.generated.go",
    "content": "package encoding\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/grpc/encoding/stream.pb.go",
    "content": "package encoding\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Hunk struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tData          []byte                 `protobuf:\"bytes,1,opt,name=data,proto3\" json:\"data,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Hunk) Reset() {\n\t*x = Hunk{}\n\tmi := &file_transport_internet_grpc_encoding_stream_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Hunk) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Hunk) ProtoMessage() {}\n\nfunc (x *Hunk) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_grpc_encoding_stream_proto_msgTypes[0]\n\tif 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 Hunk.ProtoReflect.Descriptor instead.\nfunc (*Hunk) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_grpc_encoding_stream_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Hunk) GetData() []byte {\n\tif x != nil {\n\t\treturn x.Data\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_grpc_encoding_stream_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_grpc_encoding_stream_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"-transport/internet/grpc/encoding/stream.proto\\x12+v2ray.core.transport.internet.grpc.encoding\\\"\\x1a\\n\" +\n\t\"\\x04Hunk\\x12\\x12\\n\" +\n\t\"\\x04data\\x18\\x01 \\x01(\\fR\\x04data2}\\n\" +\n\t\"\\n\" +\n\t\"GunService\\x12o\\n\" +\n\t\"\\x03Tun\\x121.v2ray.core.transport.internet.grpc.encoding.Hunk\\x1a1.v2ray.core.transport.internet.grpc.encoding.Hunk(\\x010\\x01B\\xa0\\x01\\n\" +\n\t\"/com.v2ray.core.transport.internet.grpc.encodingZ?github.com/v2fly/v2ray-core/v5/transport/internet/grpc/encoding\\xaa\\x02+V2Ray.Core.Transport.Internet.Grpc.Encodingb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_grpc_encoding_stream_proto_rawDescOnce sync.Once\n\tfile_transport_internet_grpc_encoding_stream_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_grpc_encoding_stream_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_grpc_encoding_stream_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_grpc_encoding_stream_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_grpc_encoding_stream_proto_rawDesc), len(file_transport_internet_grpc_encoding_stream_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_grpc_encoding_stream_proto_rawDescData\n}\n\nvar file_transport_internet_grpc_encoding_stream_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_grpc_encoding_stream_proto_goTypes = []any{\n\t(*Hunk)(nil), // 0: v2ray.core.transport.internet.grpc.encoding.Hunk\n}\nvar file_transport_internet_grpc_encoding_stream_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.grpc.encoding.GunService.Tun:input_type -> v2ray.core.transport.internet.grpc.encoding.Hunk\n\t0, // 1: v2ray.core.transport.internet.grpc.encoding.GunService.Tun:output_type -> v2ray.core.transport.internet.grpc.encoding.Hunk\n\t1, // [1:2] is the sub-list for method output_type\n\t0, // [0:1] 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_transport_internet_grpc_encoding_stream_proto_init() }\nfunc file_transport_internet_grpc_encoding_stream_proto_init() {\n\tif File_transport_internet_grpc_encoding_stream_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: unsafe.Slice(unsafe.StringData(file_transport_internet_grpc_encoding_stream_proto_rawDesc), len(file_transport_internet_grpc_encoding_stream_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_transport_internet_grpc_encoding_stream_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_grpc_encoding_stream_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_grpc_encoding_stream_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_grpc_encoding_stream_proto = out.File\n\tfile_transport_internet_grpc_encoding_stream_proto_goTypes = nil\n\tfile_transport_internet_grpc_encoding_stream_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/grpc/encoding/stream.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.grpc.encoding;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Grpc.Encoding\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/grpc/encoding\";\noption java_package = \"com.v2ray.core.transport.internet.grpc.encoding\";\n\nmessage Hunk {\n  bytes data = 1;\n}\n\nservice GunService {\n  rpc Tun (stream Hunk) returns (stream Hunk);\n}\n"
  },
  {
    "path": "transport/internet/grpc/encoding/stream_grpc.pb.go",
    "content": "package encoding\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.64.0 or later.\nconst _ = grpc.SupportPackageIsVersion9\n\nconst (\n\tGunService_Tun_FullMethodName = \"/v2ray.core.transport.internet.grpc.encoding.GunService/Tun\"\n)\n\n// GunServiceClient is the client API for GunService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype GunServiceClient interface {\n\tTun(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[Hunk, Hunk], error)\n}\n\ntype gunServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewGunServiceClient(cc grpc.ClientConnInterface) GunServiceClient {\n\treturn &gunServiceClient{cc}\n}\n\nfunc (c *gunServiceClient) Tun(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[Hunk, Hunk], error) {\n\tcOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)\n\tstream, err := c.cc.NewStream(ctx, &GunService_ServiceDesc.Streams[0], GunService_Tun_FullMethodName, cOpts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tx := &grpc.GenericClientStream[Hunk, Hunk]{ClientStream: stream}\n\treturn x, nil\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype GunService_TunClient = grpc.BidiStreamingClient[Hunk, Hunk]\n\n// GunServiceServer is the server API for GunService service.\n// All implementations must embed UnimplementedGunServiceServer\n// for forward compatibility.\ntype GunServiceServer interface {\n\tTun(grpc.BidiStreamingServer[Hunk, Hunk]) error\n\tmustEmbedUnimplementedGunServiceServer()\n}\n\n// UnimplementedGunServiceServer must be embedded to have\n// forward compatible implementations.\n//\n// NOTE: this should be embedded by value instead of pointer to avoid a nil\n// pointer dereference when methods are called.\ntype UnimplementedGunServiceServer struct{}\n\nfunc (UnimplementedGunServiceServer) Tun(grpc.BidiStreamingServer[Hunk, Hunk]) error {\n\treturn status.Errorf(codes.Unimplemented, \"method Tun not implemented\")\n}\nfunc (UnimplementedGunServiceServer) mustEmbedUnimplementedGunServiceServer() {}\nfunc (UnimplementedGunServiceServer) testEmbeddedByValue()                    {}\n\n// UnsafeGunServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to GunServiceServer will\n// result in compilation errors.\ntype UnsafeGunServiceServer interface {\n\tmustEmbedUnimplementedGunServiceServer()\n}\n\nfunc RegisterGunServiceServer(s grpc.ServiceRegistrar, srv GunServiceServer) {\n\t// If the following call pancis, it indicates UnimplementedGunServiceServer was\n\t// embedded by pointer and is nil.  This will cause panics if an\n\t// unimplemented method is ever invoked, so we test this at initialization\n\t// time to prevent it from happening at runtime later due to I/O.\n\tif t, ok := srv.(interface{ testEmbeddedByValue() }); ok {\n\t\tt.testEmbeddedByValue()\n\t}\n\ts.RegisterService(&GunService_ServiceDesc, srv)\n}\n\nfunc _GunService_Tun_Handler(srv interface{}, stream grpc.ServerStream) error {\n\treturn srv.(GunServiceServer).Tun(&grpc.GenericServerStream[Hunk, Hunk]{ServerStream: stream})\n}\n\n// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.\ntype GunService_TunServer = grpc.BidiStreamingServer[Hunk, Hunk]\n\n// GunService_ServiceDesc is the grpc.ServiceDesc for GunService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar GunService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"v2ray.core.transport.internet.grpc.encoding.GunService\",\n\tHandlerType: (*GunServiceServer)(nil),\n\tMethods:     []grpc.MethodDesc{},\n\tStreams: []grpc.StreamDesc{\n\t\t{\n\t\t\tStreamName:    \"Tun\",\n\t\t\tHandler:       _GunService_Tun_Handler,\n\t\t\tServerStreams: true,\n\t\t\tClientStreams: true,\n\t\t},\n\t},\n\tMetadata: \"transport/internet/grpc/encoding/stream.proto\",\n}\n"
  },
  {
    "path": "transport/internet/grpc/errors.generated.go",
    "content": "package grpc\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/grpc/grpc.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage grpc\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/grpc/hub.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage grpc\n\nimport (\n\t\"context\"\n\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/credentials\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/grpc/encoding\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\ntype Listener struct {\n\tencoding.UnimplementedGunServiceServer\n\tctx     context.Context\n\thandler internet.ConnHandler\n\tlocal   net.Addr\n\tconfig  *Config\n\n\ts *grpc.Server\n}\n\nfunc (l Listener) Tun(server encoding.GunService_TunServer) error {\n\ttunCtx, cancel := context.WithCancel(l.ctx)\n\tl.handler(encoding.NewGunConn(server, cancel))\n\t<-tunCtx.Done()\n\treturn nil\n}\n\nfunc (l Listener) Close() error {\n\tl.s.Stop()\n\treturn nil\n}\n\nfunc (l Listener) Addr() net.Addr {\n\treturn l.local\n}\n\nfunc Listen(ctx context.Context, address net.Address, port net.Port, settings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {\n\tgrpcSettings := settings.ProtocolSettings.(*Config)\n\tvar listener *Listener\n\tif port == net.Port(0) { // unix\n\t\tlistener = &Listener{\n\t\t\thandler: handler,\n\t\t\tlocal: &net.UnixAddr{\n\t\t\t\tName: address.Domain(),\n\t\t\t\tNet:  \"unix\",\n\t\t\t},\n\t\t\tconfig: grpcSettings,\n\t\t}\n\t} else { // tcp\n\t\tlistener = &Listener{\n\t\t\thandler: handler,\n\t\t\tlocal: &net.TCPAddr{\n\t\t\t\tIP:   address.IP(),\n\t\t\t\tPort: int(port),\n\t\t\t},\n\t\t\tconfig: grpcSettings,\n\t\t}\n\t}\n\n\tlistener.ctx = ctx\n\n\tconfig := tls.ConfigFromStreamSettings(settings)\n\n\tvar s *grpc.Server\n\tif config == nil {\n\t\ts = grpc.NewServer()\n\t} else {\n\t\t// gRPC server may silently ignore TLS errors\n\t\ts = grpc.NewServer(grpc.Creds(credentials.NewTLS(config.GetTLSConfig(tls.WithNextProto(\"h2\")))))\n\t}\n\tlistener.s = s\n\n\tif settings.SocketSettings != nil && settings.SocketSettings.AcceptProxyProtocol {\n\t\tnewError(\"accepting PROXY protocol\").AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tgo func() {\n\t\tvar streamListener net.Listener\n\t\tvar err error\n\t\tif port == net.Port(0) { // unix\n\t\t\tstreamListener, err = internet.ListenSystem(ctx, &net.UnixAddr{\n\t\t\t\tName: address.Domain(),\n\t\t\t\tNet:  \"unix\",\n\t\t\t}, settings.SocketSettings)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to listen on \", address).Base(err).AtError().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn\n\t\t\t}\n\t\t} else { // tcp\n\t\t\tstreamListener, err = internet.ListenSystem(ctx, &net.TCPAddr{\n\t\t\t\tIP:   address.IP(),\n\t\t\t\tPort: int(port),\n\t\t\t}, settings.SocketSettings)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to listen on \", address, \":\", port).Base(err).AtError().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tencoding.RegisterGunServiceServerX(s, listener, grpcSettings.ServiceName)\n\n\t\tif err = s.Serve(streamListener); err != nil {\n\t\t\tnewError(\"Listener for grpc ended\").Base(err).WriteToLog()\n\t\t}\n\t}()\n\n\treturn listener, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, Listen))\n}\n"
  },
  {
    "path": "transport/internet/header.go",
    "content": "package internet\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype PacketHeader interface {\n\tSize() int32\n\tSerialize([]byte)\n}\n\nfunc CreatePacketHeader(config interface{}) (PacketHeader, error) {\n\theader, err := common.CreateObject(context.Background(), config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif h, ok := header.(PacketHeader); ok {\n\t\treturn h, nil\n\t}\n\treturn nil, newError(\"not a packet header\")\n}\n\ntype ConnectionAuthenticator interface {\n\tClient(net.Conn) net.Conn\n\tServer(net.Conn) net.Conn\n}\n\nfunc CreateConnectionAuthenticator(config interface{}) (ConnectionAuthenticator, error) {\n\tauth, err := common.CreateObject(context.Background(), config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif a, ok := auth.(ConnectionAuthenticator); ok {\n\t\treturn a, nil\n\t}\n\treturn nil, newError(\"not a ConnectionAuthenticator\")\n}\n"
  },
  {
    "path": "transport/internet/header_test.go",
    "content": "package internet_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/srtp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/utp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wireguard\"\n)\n\nfunc TestAllHeadersLoadable(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput interface{}\n\t\tSize  int32\n\t}{\n\t\t{\n\t\t\tInput: new(noop.Config),\n\t\t\tSize:  0,\n\t\t},\n\t\t{\n\t\t\tInput: new(srtp.Config),\n\t\t\tSize:  4,\n\t\t},\n\t\t{\n\t\t\tInput: new(utp.Config),\n\t\t\tSize:  4,\n\t\t},\n\t\t{\n\t\t\tInput: new(wechat.VideoConfig),\n\t\t\tSize:  13,\n\t\t},\n\t\t{\n\t\t\tInput: new(wireguard.WireguardConfig),\n\t\t\tSize:  4,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\theader, err := CreatePacketHeader(testCase.Input)\n\t\tcommon.Must(err)\n\t\tif header.Size() != testCase.Size {\n\t\t\tt.Error(\"expected size \", testCase.Size, \" but got \", header.Size())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "transport/internet/headers/http/config.go",
    "content": "package http\n\nimport (\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\nfunc pickString(arr []string) string {\n\tn := len(arr)\n\tswitch n {\n\tcase 0:\n\t\treturn \"\"\n\tcase 1:\n\t\treturn arr[0]\n\tdefault:\n\t\treturn arr[dice.Roll(n)]\n\t}\n}\n\nfunc (v *RequestConfig) PickURI() string {\n\treturn pickString(v.Uri)\n}\n\nfunc (v *RequestConfig) PickHeaders() []string {\n\tn := len(v.Header)\n\tif n == 0 {\n\t\treturn nil\n\t}\n\theaders := make([]string, n)\n\tfor idx, headerConfig := range v.Header {\n\t\theaderName := headerConfig.Name\n\t\theaderValue := pickString(headerConfig.Value)\n\t\theaders[idx] = headerName + \": \" + headerValue\n\t}\n\treturn headers\n}\n\nfunc (v *RequestConfig) GetVersionValue() string {\n\tif v == nil || v.Version == nil {\n\t\treturn \"1.1\"\n\t}\n\treturn v.Version.Value\n}\n\nfunc (v *RequestConfig) GetMethodValue() string {\n\tif v == nil || v.Method == nil {\n\t\treturn \"GET\"\n\t}\n\treturn v.Method.Value\n}\n\nfunc (v *RequestConfig) GetFullVersion() string {\n\treturn \"HTTP/\" + v.GetVersionValue()\n}\n\nfunc (v *ResponseConfig) HasHeader(header string) bool {\n\tcHeader := strings.ToLower(header)\n\tfor _, tHeader := range v.Header {\n\t\tif strings.EqualFold(tHeader.Name, cHeader) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (v *ResponseConfig) PickHeaders() []string {\n\tn := len(v.Header)\n\tif n == 0 {\n\t\treturn nil\n\t}\n\theaders := make([]string, n)\n\tfor idx, headerConfig := range v.Header {\n\t\theaderName := headerConfig.Name\n\t\theaderValue := pickString(headerConfig.Value)\n\t\theaders[idx] = headerName + \": \" + headerValue\n\t}\n\treturn headers\n}\n\nfunc (v *ResponseConfig) GetVersionValue() string {\n\tif v == nil || v.Version == nil {\n\t\treturn \"1.1\"\n\t}\n\treturn v.Version.Value\n}\n\nfunc (v *ResponseConfig) GetFullVersion() string {\n\treturn \"HTTP/\" + v.GetVersionValue()\n}\n\nfunc (v *ResponseConfig) GetStatusValue() *Status {\n\tif v == nil || v.Status == nil {\n\t\treturn &Status{\n\t\t\tCode:   \"200\",\n\t\t\tReason: \"OK\",\n\t\t}\n\t}\n\treturn v.Status\n}\n"
  },
  {
    "path": "transport/internet/headers/http/config.pb.go",
    "content": "package http\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Header struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// \"Accept\", \"Cookie\", etc\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Each entry must be valid in one piece. Random entry will be chosen if\n\t// multiple entries present.\n\tValue         []string `protobuf:\"bytes,2,rep,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Header) Reset() {\n\t*x = Header{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\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_transport_internet_headers_http_config_proto_msgTypes[0]\n\tif 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_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Header) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetValue() []string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// HTTP version. Default value \"1.1\".\ntype Version struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Version) Reset() {\n\t*x = Version{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\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_transport_internet_headers_http_config_proto_msgTypes[1]\n\tif 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_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Version) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\n// HTTP method. Default value \"GET\".\ntype Method struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         string                 `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Method) Reset() {\n\t*x = Method{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Method) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Method) ProtoMessage() {}\n\nfunc (x *Method) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[2]\n\tif 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 Method.ProtoReflect.Descriptor instead.\nfunc (*Method) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *Method) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\ntype RequestConfig struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Full HTTP version like \"1.1\".\n\tVersion *Version `protobuf:\"bytes,1,opt,name=version,proto3\" json:\"version,omitempty\"`\n\t// GET, POST, CONNECT etc\n\tMethod *Method `protobuf:\"bytes,2,opt,name=method,proto3\" json:\"method,omitempty\"`\n\t// URI like \"/login.php\"\n\tUri           []string  `protobuf:\"bytes,3,rep,name=uri,proto3\" json:\"uri,omitempty\"`\n\tHeader        []*Header `protobuf:\"bytes,4,rep,name=header,proto3\" json:\"header,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *RequestConfig) Reset() {\n\t*x = RequestConfig{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *RequestConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RequestConfig) ProtoMessage() {}\n\nfunc (x *RequestConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[3]\n\tif 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 RequestConfig.ProtoReflect.Descriptor instead.\nfunc (*RequestConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *RequestConfig) GetVersion() *Version {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn nil\n}\n\nfunc (x *RequestConfig) GetMethod() *Method {\n\tif x != nil {\n\t\treturn x.Method\n\t}\n\treturn nil\n}\n\nfunc (x *RequestConfig) GetUri() []string {\n\tif x != nil {\n\t\treturn x.Uri\n\t}\n\treturn nil\n}\n\nfunc (x *RequestConfig) GetHeader() []*Header {\n\tif x != nil {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\ntype Status struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Status code. Default \"200\".\n\tCode string `protobuf:\"bytes,1,opt,name=code,proto3\" json:\"code,omitempty\"`\n\t// Statue reason. Default \"OK\".\n\tReason        string `protobuf:\"bytes,2,opt,name=reason,proto3\" json:\"reason,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Status) Reset() {\n\t*x = Status{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Status) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Status) ProtoMessage() {}\n\nfunc (x *Status) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[4]\n\tif 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 Status.ProtoReflect.Descriptor instead.\nfunc (*Status) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *Status) GetCode() string {\n\tif x != nil {\n\t\treturn x.Code\n\t}\n\treturn \"\"\n}\n\nfunc (x *Status) GetReason() string {\n\tif x != nil {\n\t\treturn x.Reason\n\t}\n\treturn \"\"\n}\n\ntype ResponseConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tVersion       *Version               `protobuf:\"bytes,1,opt,name=version,proto3\" json:\"version,omitempty\"`\n\tStatus        *Status                `protobuf:\"bytes,2,opt,name=status,proto3\" json:\"status,omitempty\"`\n\tHeader        []*Header              `protobuf:\"bytes,3,rep,name=header,proto3\" json:\"header,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ResponseConfig) Reset() {\n\t*x = ResponseConfig{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ResponseConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ResponseConfig) ProtoMessage() {}\n\nfunc (x *ResponseConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[5]\n\tif 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 ResponseConfig.ProtoReflect.Descriptor instead.\nfunc (*ResponseConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *ResponseConfig) GetVersion() *Version {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn nil\n}\n\nfunc (x *ResponseConfig) GetStatus() *Status {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn nil\n}\n\nfunc (x *ResponseConfig) GetHeader() []*Header {\n\tif x != nil {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Settings for authenticating requests. If not set, client side will not send\n\t// authenication header, and server side will bypass authentication.\n\tRequest *RequestConfig `protobuf:\"bytes,1,opt,name=request,proto3\" json:\"request,omitempty\"`\n\t// Settings for authenticating responses. If not set, client side will bypass\n\t// authentication, and server side will not send authentication header.\n\tResponse      *ResponseConfig `protobuf:\"bytes,2,opt,name=response,proto3\" json:\"response,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_http_config_proto_msgTypes[6]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_http_config_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *Config) GetRequest() *RequestConfig {\n\tif x != nil {\n\t\treturn x.Request\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetResponse() *ResponseConfig {\n\tif x != nil {\n\t\treturn x.Response\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_headers_http_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_http_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\",transport/internet/headers/http/config.proto\\x12*v2ray.core.transport.internet.headers.http\\\"2\\n\" +\n\t\"\\x06Header\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x03(\\tR\\x05value\\\"\\x1f\\n\" +\n\t\"\\aVersion\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\tR\\x05value\\\"\\x1e\\n\" +\n\t\"\\x06Method\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\tR\\x05value\\\"\\x88\\x02\\n\" +\n\t\"\\rRequestConfig\\x12M\\n\" +\n\t\"\\aversion\\x18\\x01 \\x01(\\v23.v2ray.core.transport.internet.headers.http.VersionR\\aversion\\x12J\\n\" +\n\t\"\\x06method\\x18\\x02 \\x01(\\v22.v2ray.core.transport.internet.headers.http.MethodR\\x06method\\x12\\x10\\n\" +\n\t\"\\x03uri\\x18\\x03 \\x03(\\tR\\x03uri\\x12J\\n\" +\n\t\"\\x06header\\x18\\x04 \\x03(\\v22.v2ray.core.transport.internet.headers.http.HeaderR\\x06header\\\"4\\n\" +\n\t\"\\x06Status\\x12\\x12\\n\" +\n\t\"\\x04code\\x18\\x01 \\x01(\\tR\\x04code\\x12\\x16\\n\" +\n\t\"\\x06reason\\x18\\x02 \\x01(\\tR\\x06reason\\\"\\xf7\\x01\\n\" +\n\t\"\\x0eResponseConfig\\x12M\\n\" +\n\t\"\\aversion\\x18\\x01 \\x01(\\v23.v2ray.core.transport.internet.headers.http.VersionR\\aversion\\x12J\\n\" +\n\t\"\\x06status\\x18\\x02 \\x01(\\v22.v2ray.core.transport.internet.headers.http.StatusR\\x06status\\x12J\\n\" +\n\t\"\\x06header\\x18\\x03 \\x03(\\v22.v2ray.core.transport.internet.headers.http.HeaderR\\x06header\\\"\\xb5\\x01\\n\" +\n\t\"\\x06Config\\x12S\\n\" +\n\t\"\\arequest\\x18\\x01 \\x01(\\v29.v2ray.core.transport.internet.headers.http.RequestConfigR\\arequest\\x12V\\n\" +\n\t\"\\bresponse\\x18\\x02 \\x01(\\v2:.v2ray.core.transport.internet.headers.http.ResponseConfigR\\bresponseB\\x9f\\x01\\n\" +\n\t\".com.v2ray.core.transport.internet.headers.httpP\\x01Z>github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\\xaa\\x02*V2Ray.Core.Transport.Internet.Headers.Httpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_http_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_http_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_http_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_http_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_http_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_http_config_proto_rawDesc), len(file_transport_internet_headers_http_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_http_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_http_config_proto_msgTypes = make([]protoimpl.MessageInfo, 7)\nvar file_transport_internet_headers_http_config_proto_goTypes = []any{\n\t(*Header)(nil),         // 0: v2ray.core.transport.internet.headers.http.Header\n\t(*Version)(nil),        // 1: v2ray.core.transport.internet.headers.http.Version\n\t(*Method)(nil),         // 2: v2ray.core.transport.internet.headers.http.Method\n\t(*RequestConfig)(nil),  // 3: v2ray.core.transport.internet.headers.http.RequestConfig\n\t(*Status)(nil),         // 4: v2ray.core.transport.internet.headers.http.Status\n\t(*ResponseConfig)(nil), // 5: v2ray.core.transport.internet.headers.http.ResponseConfig\n\t(*Config)(nil),         // 6: v2ray.core.transport.internet.headers.http.Config\n}\nvar file_transport_internet_headers_http_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.headers.http.RequestConfig.version:type_name -> v2ray.core.transport.internet.headers.http.Version\n\t2, // 1: v2ray.core.transport.internet.headers.http.RequestConfig.method:type_name -> v2ray.core.transport.internet.headers.http.Method\n\t0, // 2: v2ray.core.transport.internet.headers.http.RequestConfig.header:type_name -> v2ray.core.transport.internet.headers.http.Header\n\t1, // 3: v2ray.core.transport.internet.headers.http.ResponseConfig.version:type_name -> v2ray.core.transport.internet.headers.http.Version\n\t4, // 4: v2ray.core.transport.internet.headers.http.ResponseConfig.status:type_name -> v2ray.core.transport.internet.headers.http.Status\n\t0, // 5: v2ray.core.transport.internet.headers.http.ResponseConfig.header:type_name -> v2ray.core.transport.internet.headers.http.Header\n\t3, // 6: v2ray.core.transport.internet.headers.http.Config.request:type_name -> v2ray.core.transport.internet.headers.http.RequestConfig\n\t5, // 7: v2ray.core.transport.internet.headers.http.Config.response:type_name -> v2ray.core.transport.internet.headers.http.ResponseConfig\n\t8, // [8:8] is the sub-list for method output_type\n\t8, // [8:8] is the sub-list for method input_type\n\t8, // [8:8] is the sub-list for extension type_name\n\t8, // [8:8] is the sub-list for extension extendee\n\t0, // [0:8] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_headers_http_config_proto_init() }\nfunc file_transport_internet_headers_http_config_proto_init() {\n\tif File_transport_internet_headers_http_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_http_config_proto_rawDesc), len(file_transport_internet_headers_http_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   7,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_http_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_http_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_http_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_http_config_proto = out.File\n\tfile_transport_internet_headers_http_config_proto_goTypes = nil\n\tfile_transport_internet_headers_http_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/http/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.http;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Http\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\";\noption java_package = \"com.v2ray.core.transport.internet.headers.http\";\noption java_multiple_files = true;\n\nmessage Header {\n  // \"Accept\", \"Cookie\", etc\n  string name = 1;\n\n  // Each entry must be valid in one piece. Random entry will be chosen if\n  // multiple entries present.\n  repeated string value = 2;\n}\n\n// HTTP version. Default value \"1.1\".\nmessage Version {\n  string value = 1;\n}\n\n// HTTP method. Default value \"GET\".\nmessage Method {\n  string value = 1;\n}\n\nmessage RequestConfig {\n  // Full HTTP version like \"1.1\".\n  Version version = 1;\n\n  // GET, POST, CONNECT etc\n  Method method = 2;\n\n  // URI like \"/login.php\"\n  repeated string uri = 3;\n\n  repeated Header header = 4;\n}\n\nmessage Status {\n  // Status code. Default \"200\".\n  string code = 1;\n\n  // Statue reason. Default \"OK\".\n  string reason = 2;\n}\n\nmessage ResponseConfig {\n  Version version = 1;\n\n  Status status = 2;\n\n  repeated Header header = 3;\n}\n\nmessage Config {\n  // Settings for authenticating requests. If not set, client side will not send\n  // authenication header, and server side will bypass authentication.\n  RequestConfig request = 1;\n\n  // Settings for authenticating responses. If not set, client side will bypass\n  // authentication, and server side will not send authentication header.\n  ResponseConfig response = 2;\n}\n"
  },
  {
    "path": "transport/internet/headers/http/errors.generated.go",
    "content": "package http\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/headers/http/http.go",
    "content": "package http\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\nconst (\n\t// CRLF is the line ending in HTTP header\n\tCRLF = \"\\r\\n\"\n\n\t// ENDING is the double line ending between HTTP header and body.\n\tENDING = CRLF + CRLF\n\n\t// max length of HTTP header. Safety precaution for DDoS attack.\n\tmaxHeaderLength = 8192\n)\n\nvar (\n\tErrHeaderToLong = newError(\"Header too long.\")\n\n\tErrHeaderMisMatch = newError(\"Header Mismatch.\")\n)\n\ntype Reader interface {\n\tRead(io.Reader) (*buf.Buffer, error)\n}\n\ntype Writer interface {\n\tWrite(io.Writer) error\n}\n\ntype NoOpReader struct{}\n\nfunc (NoOpReader) Read(io.Reader) (*buf.Buffer, error) {\n\treturn nil, nil\n}\n\ntype NoOpWriter struct{}\n\nfunc (NoOpWriter) Write(io.Writer) error {\n\treturn nil\n}\n\ntype HeaderReader struct {\n\treq            *http.Request\n\texpectedHeader *RequestConfig\n}\n\nfunc (h *HeaderReader) ExpectThisRequest(expectedHeader *RequestConfig) *HeaderReader {\n\th.expectedHeader = expectedHeader\n\treturn h\n}\n\nfunc (h *HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {\n\tbuffer := buf.New()\n\ttotalBytes := int32(0)\n\tendingDetected := false\n\n\tvar headerBuf bytes.Buffer\n\n\tfor totalBytes < maxHeaderLength {\n\t\t_, err := buffer.ReadFrom(reader)\n\t\tif err != nil {\n\t\t\tbuffer.Release()\n\t\t\treturn nil, err\n\t\t}\n\t\tif n := bytes.Index(buffer.Bytes(), []byte(ENDING)); n != -1 {\n\t\t\theaderBuf.Write(buffer.BytesRange(0, int32(n+len(ENDING))))\n\t\t\tbuffer.Advance(int32(n + len(ENDING)))\n\t\t\tendingDetected = true\n\t\t\tbreak\n\t\t}\n\t\tlenEnding := int32(len(ENDING))\n\t\tif buffer.Len() >= lenEnding {\n\t\t\ttotalBytes += buffer.Len() - lenEnding\n\t\t\theaderBuf.Write(buffer.BytesRange(0, buffer.Len()-lenEnding))\n\t\t\tleftover := buffer.BytesFrom(-lenEnding)\n\t\t\tbuffer.Clear()\n\t\t\tcopy(buffer.Extend(lenEnding), leftover)\n\n\t\t\tif _, err := readRequest(bufio.NewReader(bytes.NewReader(headerBuf.Bytes()))); err != io.ErrUnexpectedEOF {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\n\tif !endingDetected {\n\t\tbuffer.Release()\n\t\treturn nil, ErrHeaderToLong\n\t}\n\n\tif h.expectedHeader == nil {\n\t\tif buffer.IsEmpty() {\n\t\t\tbuffer.Release()\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn buffer, nil\n\t}\n\n\t// Parse the request\n\tif req, err := readRequest(bufio.NewReader(bytes.NewReader(headerBuf.Bytes()))); err != nil {\n\t\treturn nil, err\n\t} else { // nolint: revive\n\t\th.req = req\n\t}\n\n\t// Check req\n\tpath := h.req.URL.Path\n\thasThisURI := false\n\tfor _, u := range h.expectedHeader.Uri {\n\t\tif u == path {\n\t\t\thasThisURI = true\n\t\t}\n\t}\n\n\tif !hasThisURI {\n\t\treturn nil, ErrHeaderMisMatch\n\t}\n\n\tif buffer.IsEmpty() {\n\t\tbuffer.Release()\n\t\treturn nil, nil\n\t}\n\n\treturn buffer, nil\n}\n\ntype HeaderWriter struct {\n\theader *buf.Buffer\n}\n\nfunc NewHeaderWriter(header *buf.Buffer) *HeaderWriter {\n\treturn &HeaderWriter{\n\t\theader: header,\n\t}\n}\n\nfunc (w *HeaderWriter) Write(writer io.Writer) error {\n\tif w.header == nil {\n\t\treturn nil\n\t}\n\terr := buf.WriteAllBytes(writer, w.header.Bytes())\n\tw.header.Release()\n\tw.header = nil\n\treturn err\n}\n\ntype Conn struct {\n\tnet.Conn\n\n\treadBuffer          *buf.Buffer\n\toneTimeReader       Reader\n\toneTimeWriter       Writer\n\terrorWriter         Writer\n\terrorMismatchWriter Writer\n\terrorTooLongWriter  Writer\n\terrReason           error\n}\n\nfunc NewConn(conn net.Conn, reader Reader, writer Writer, errorWriter Writer, errorMismatchWriter Writer, errorTooLongWriter Writer) *Conn {\n\treturn &Conn{\n\t\tConn:                conn,\n\t\toneTimeReader:       reader,\n\t\toneTimeWriter:       writer,\n\t\terrorWriter:         errorWriter,\n\t\terrorMismatchWriter: errorMismatchWriter,\n\t\terrorTooLongWriter:  errorTooLongWriter,\n\t}\n}\n\nfunc (c *Conn) Read(b []byte) (int, error) {\n\tif c.oneTimeReader != nil {\n\t\tbuffer, err := c.oneTimeReader.Read(c.Conn)\n\t\tif err != nil {\n\t\t\tc.errReason = err\n\t\t\treturn 0, err\n\t\t}\n\t\tc.readBuffer = buffer\n\t\tc.oneTimeReader = nil\n\t}\n\n\tif !c.readBuffer.IsEmpty() {\n\t\tnBytes, _ := c.readBuffer.Read(b)\n\t\tif c.readBuffer.IsEmpty() {\n\t\t\tc.readBuffer.Release()\n\t\t\tc.readBuffer = nil\n\t\t}\n\t\treturn nBytes, nil\n\t}\n\n\treturn c.Conn.Read(b)\n}\n\n// Write implements io.Writer.\nfunc (c *Conn) Write(b []byte) (int, error) {\n\tif c.oneTimeWriter != nil {\n\t\terr := c.oneTimeWriter.Write(c.Conn)\n\t\tc.oneTimeWriter = nil\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\treturn c.Conn.Write(b)\n}\n\n// Close implements net.Conn.Close().\nfunc (c *Conn) Close() error {\n\tif c.oneTimeWriter != nil && c.errorWriter != nil {\n\t\t// Connection is being closed but header wasn't sent. This means the client request\n\t\t// is probably not valid. Sending back a server error header in this case.\n\n\t\t// Write response based on error reason\n\t\tswitch c.errReason {\n\t\tcase ErrHeaderMisMatch:\n\t\t\tc.errorMismatchWriter.Write(c.Conn)\n\t\tcase ErrHeaderToLong:\n\t\t\tc.errorTooLongWriter.Write(c.Conn)\n\t\tdefault:\n\t\t\tc.errorWriter.Write(c.Conn)\n\t\t}\n\t}\n\n\treturn c.Conn.Close()\n}\n\nfunc formResponseHeader(config *ResponseConfig) *HeaderWriter {\n\theader := buf.New()\n\tcommon.Must2(header.WriteString(strings.Join([]string{config.GetFullVersion(), config.GetStatusValue().Code, config.GetStatusValue().Reason}, \" \")))\n\tcommon.Must2(header.WriteString(CRLF))\n\n\theaders := config.PickHeaders()\n\tfor _, h := range headers {\n\t\tcommon.Must2(header.WriteString(h))\n\t\tcommon.Must2(header.WriteString(CRLF))\n\t}\n\tif !config.HasHeader(\"Date\") {\n\t\tcommon.Must2(header.WriteString(\"Date: \"))\n\t\tcommon.Must2(header.WriteString(time.Now().Format(http.TimeFormat)))\n\t\tcommon.Must2(header.WriteString(CRLF))\n\t}\n\tcommon.Must2(header.WriteString(CRLF))\n\treturn &HeaderWriter{\n\t\theader: header,\n\t}\n}\n\ntype Authenticator struct {\n\tconfig *Config\n}\n\nfunc (a Authenticator) GetClientWriter() *HeaderWriter {\n\theader := buf.New()\n\tconfig := a.config.Request\n\tcommon.Must2(header.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickURI(), config.GetFullVersion()}, \" \")))\n\tcommon.Must2(header.WriteString(CRLF))\n\n\theaders := config.PickHeaders()\n\tfor _, h := range headers {\n\t\tcommon.Must2(header.WriteString(h))\n\t\tcommon.Must2(header.WriteString(CRLF))\n\t}\n\tcommon.Must2(header.WriteString(CRLF))\n\treturn &HeaderWriter{\n\t\theader: header,\n\t}\n}\n\nfunc (a Authenticator) GetServerWriter() *HeaderWriter {\n\treturn formResponseHeader(a.config.Response)\n}\n\nfunc (a Authenticator) Client(conn net.Conn) net.Conn {\n\tif a.config.Request == nil && a.config.Response == nil {\n\t\treturn conn\n\t}\n\tvar reader Reader = NoOpReader{}\n\tif a.config.Request != nil {\n\t\treader = new(HeaderReader)\n\t}\n\n\tvar writer Writer = NoOpWriter{}\n\tif a.config.Response != nil {\n\t\twriter = a.GetClientWriter()\n\t}\n\treturn NewConn(conn, reader, writer, NoOpWriter{}, NoOpWriter{}, NoOpWriter{})\n}\n\nfunc (a Authenticator) Server(conn net.Conn) net.Conn {\n\tif a.config.Request == nil && a.config.Response == nil {\n\t\treturn conn\n\t}\n\treturn NewConn(conn, new(HeaderReader).ExpectThisRequest(a.config.Request), a.GetServerWriter(),\n\t\tformResponseHeader(resp400),\n\t\tformResponseHeader(resp404),\n\t\tformResponseHeader(resp400))\n}\n\nfunc NewAuthenticator(ctx context.Context, config *Config) (Authenticator, error) {\n\treturn Authenticator{\n\t\tconfig: config,\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewAuthenticator(ctx, config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/headers/http/http_test.go",
    "content": "package http_test\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n)\n\nfunc TestReaderWriter(t *testing.T) {\n\tcache := buf.New()\n\tb := buf.New()\n\tcommon.Must2(b.WriteString(\"abcd\" + ENDING))\n\twriter := NewHeaderWriter(b)\n\terr := writer.Write(cache)\n\tcommon.Must(err)\n\tif v := cache.Len(); v != 8 {\n\t\tt.Error(\"cache len: \", v)\n\t}\n\t_, err = cache.Write([]byte{'e', 'f', 'g'})\n\tcommon.Must(err)\n\n\treader := &HeaderReader{}\n\t_, err = reader.Read(cache)\n\tif err != nil && !strings.HasPrefix(err.Error(), \"malformed HTTP request\") {\n\t\tt.Error(\"unknown error \", err)\n\t}\n}\n\nfunc TestRequestHeader(t *testing.T) {\n\tauth, err := NewAuthenticator(context.Background(), &Config{\n\t\tRequest: &RequestConfig{\n\t\t\tUri: []string{\"/\"},\n\t\t\tHeader: []*Header{\n\t\t\t\t{\n\t\t\t\t\tName:  \"Test\",\n\t\t\t\t\tValue: []string{\"Value\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\n\tcache := buf.New()\n\terr = auth.GetClientWriter().Write(cache)\n\tcommon.Must(err)\n\n\tif cache.String() != \"GET / HTTP/1.1\\r\\nTest: Value\\r\\n\\r\\n\" {\n\t\tt.Error(\"cache: \", cache.String())\n\t}\n}\n\nfunc TestLongRequestHeader(t *testing.T) {\n\tpayload := make([]byte, buf.Size+2)\n\tcommon.Must2(rand.Read(payload[:buf.Size-2]))\n\tcopy(payload[buf.Size-2:], ENDING)\n\tpayload = append(payload, []byte(\"abcd\")...)\n\n\treader := HeaderReader{}\n\t_, err := reader.Read(bytes.NewReader(payload))\n\n\tif err != nil && !(strings.HasPrefix(err.Error(), \"invalid\") || strings.HasPrefix(err.Error(), \"malformed\")) {\n\t\tt.Error(\"unknown error \", err)\n\t}\n}\n\nfunc TestConnection(t *testing.T) {\n\tauth, err := NewAuthenticator(context.Background(), &Config{\n\t\tRequest: &RequestConfig{\n\t\t\tMethod: &Method{Value: \"Post\"},\n\t\t\tUri:    []string{\"/testpath\"},\n\t\t\tHeader: []*Header{\n\t\t\t\t{\n\t\t\t\t\tName:  \"Host\",\n\t\t\t\t\tValue: []string{\"www.v2fly.org\", \"www.google.com\"},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:  \"User-Agent\",\n\t\t\t\t\tValue: []string{\"Test-Agent\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tResponse: &ResponseConfig{\n\t\t\tVersion: &Version{\n\t\t\t\tValue: \"1.1\",\n\t\t\t},\n\t\t\tStatus: &Status{\n\t\t\t\tCode:   \"404\",\n\t\t\t\tReason: \"Not Found\",\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tcommon.Must(err)\n\n\tgo func() {\n\t\tconn, err := listener.Accept()\n\t\tcommon.Must(err)\n\t\tauthConn := auth.Server(conn)\n\t\tb := make([]byte, 256)\n\t\tfor {\n\t\t\tn, err := authConn.Read(b)\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t_, err = authConn.Write(b[:n])\n\t\t\tcommon.Must(err)\n\t\t}\n\t}()\n\n\tconn, err := net.DialTCP(\"tcp\", nil, listener.Addr().(*net.TCPAddr))\n\tcommon.Must(err)\n\n\tauthConn := auth.Client(conn)\n\tdefer authConn.Close()\n\n\tauthConn.Write([]byte(\"Test payload\"))\n\tauthConn.Write([]byte(\"Test payload 2\"))\n\n\texpectedResponse := \"Test payloadTest payload 2\"\n\tactualResponse := make([]byte, 256)\n\tdeadline := time.Now().Add(time.Second * 5)\n\ttotalBytes := 0\n\tfor {\n\t\tn, err := authConn.Read(actualResponse[totalBytes:])\n\t\tcommon.Must(err)\n\t\ttotalBytes += n\n\t\tif totalBytes >= len(expectedResponse) || time.Now().After(deadline) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif string(actualResponse[:totalBytes]) != expectedResponse {\n\t\tt.Error(\"response: \", string(actualResponse[:totalBytes]))\n\t}\n}\n\nfunc TestConnectionInvPath(t *testing.T) {\n\tauth, err := NewAuthenticator(context.Background(), &Config{\n\t\tRequest: &RequestConfig{\n\t\t\tMethod: &Method{Value: \"Post\"},\n\t\t\tUri:    []string{\"/testpath\"},\n\t\t\tHeader: []*Header{\n\t\t\t\t{\n\t\t\t\t\tName:  \"Host\",\n\t\t\t\t\tValue: []string{\"www.v2fly.org\", \"www.google.com\"},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:  \"User-Agent\",\n\t\t\t\t\tValue: []string{\"Test-Agent\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tResponse: &ResponseConfig{\n\t\t\tVersion: &Version{\n\t\t\t\tValue: \"1.1\",\n\t\t\t},\n\t\t\tStatus: &Status{\n\t\t\t\tCode:   \"404\",\n\t\t\t\tReason: \"Not Found\",\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\n\tauthR, err := NewAuthenticator(context.Background(), &Config{\n\t\tRequest: &RequestConfig{\n\t\t\tMethod: &Method{Value: \"Post\"},\n\t\t\tUri:    []string{\"/testpathErr\"},\n\t\t\tHeader: []*Header{\n\t\t\t\t{\n\t\t\t\t\tName:  \"Host\",\n\t\t\t\t\tValue: []string{\"www.v2fly.org\", \"www.google.com\"},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:  \"User-Agent\",\n\t\t\t\t\tValue: []string{\"Test-Agent\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tResponse: &ResponseConfig{\n\t\t\tVersion: &Version{\n\t\t\t\tValue: \"1.1\",\n\t\t\t},\n\t\t\tStatus: &Status{\n\t\t\t\tCode:   \"404\",\n\t\t\t\tReason: \"Not Found\",\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tcommon.Must(err)\n\n\tgo func() {\n\t\tconn, err := listener.Accept()\n\t\tcommon.Must(err)\n\t\tauthConn := auth.Server(conn)\n\t\tb := make([]byte, 256)\n\t\tfor {\n\t\t\tn, err := authConn.Read(b)\n\t\t\tif err != nil {\n\t\t\t\tauthConn.Close()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t_, err = authConn.Write(b[:n])\n\t\t\tcommon.Must(err)\n\t\t}\n\t}()\n\n\tconn, err := net.DialTCP(\"tcp\", nil, listener.Addr().(*net.TCPAddr))\n\tcommon.Must(err)\n\n\tauthConn := authR.Client(conn)\n\tdefer authConn.Close()\n\n\tauthConn.Write([]byte(\"Test payload\"))\n\tauthConn.Write([]byte(\"Test payload 2\"))\n\n\texpectedResponse := \"Test payloadTest payload 2\"\n\tactualResponse := make([]byte, 256)\n\tdeadline := time.Now().Add(time.Second * 5)\n\ttotalBytes := 0\n\tfor {\n\t\tn, err := authConn.Read(actualResponse[totalBytes:])\n\t\tif err == nil {\n\t\t\tt.Error(\"Error Expected\", err)\n\t\t} else {\n\t\t\treturn\n\t\t}\n\t\ttotalBytes += n\n\t\tif totalBytes >= len(expectedResponse) || time.Now().After(deadline) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc TestConnectionInvReq(t *testing.T) {\n\tauth, err := NewAuthenticator(context.Background(), &Config{\n\t\tRequest: &RequestConfig{\n\t\t\tMethod: &Method{Value: \"Post\"},\n\t\t\tUri:    []string{\"/testpath\"},\n\t\t\tHeader: []*Header{\n\t\t\t\t{\n\t\t\t\t\tName:  \"Host\",\n\t\t\t\t\tValue: []string{\"www.v2fly.org\", \"www.google.com\"},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:  \"User-Agent\",\n\t\t\t\t\tValue: []string{\"Test-Agent\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tResponse: &ResponseConfig{\n\t\t\tVersion: &Version{\n\t\t\t\tValue: \"1.1\",\n\t\t\t},\n\t\t\tStatus: &Status{\n\t\t\t\tCode:   \"404\",\n\t\t\t\tReason: \"Not Found\",\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tcommon.Must(err)\n\n\tgo func() {\n\t\tconn, err := listener.Accept()\n\t\tcommon.Must(err)\n\t\tauthConn := auth.Server(conn)\n\t\tb := make([]byte, 256)\n\t\tfor {\n\t\t\tn, err := authConn.Read(b)\n\t\t\tif err != nil {\n\t\t\t\tauthConn.Close()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t_, err = authConn.Write(b[:n])\n\t\t\tcommon.Must(err)\n\t\t}\n\t}()\n\n\tconn, err := net.DialTCP(\"tcp\", nil, listener.Addr().(*net.TCPAddr))\n\tcommon.Must(err)\n\n\tconn.Write([]byte(\"ABCDEFGHIJKMLN\\r\\n\\r\\n\"))\n\tl, _, err := bufio.NewReader(conn).ReadLine()\n\tcommon.Must(err)\n\tif !strings.HasPrefix(string(l), \"HTTP/1.1 400 Bad Request\") {\n\t\tt.Error(\"Resp to non http conn\", string(l))\n\t}\n}\n"
  },
  {
    "path": "transport/internet/headers/http/linkedreadRequest.go",
    "content": "package http\n\nimport (\n\t\"bufio\"\n\t\"net/http\"\n\t_ \"unsafe\"\n)\n\n//go:linkname readRequest net/http.readRequest\nfunc readRequest(b *bufio.Reader) (req *http.Request, err error)\n"
  },
  {
    "path": "transport/internet/headers/http/resp.go",
    "content": "package http\n\nvar resp400 = &ResponseConfig{\n\tVersion: &Version{\n\t\tValue: \"1.1\",\n\t},\n\tStatus: &Status{\n\t\tCode:   \"400\",\n\t\tReason: \"Bad Request\",\n\t},\n\tHeader: []*Header{\n\t\t{\n\t\t\tName:  \"Connection\",\n\t\t\tValue: []string{\"close\"},\n\t\t},\n\t\t{\n\t\t\tName:  \"Cache-Control\",\n\t\t\tValue: []string{\"private\"},\n\t\t},\n\t\t{\n\t\t\tName:  \"Content-Length\",\n\t\t\tValue: []string{\"0\"},\n\t\t},\n\t},\n}\n\nvar resp404 = &ResponseConfig{\n\tVersion: &Version{\n\t\tValue: \"1.1\",\n\t},\n\tStatus: &Status{\n\t\tCode:   \"404\",\n\t\tReason: \"Not Found\",\n\t},\n\tHeader: []*Header{\n\t\t{\n\t\t\tName:  \"Connection\",\n\t\t\tValue: []string{\"close\"},\n\t\t},\n\t\t{\n\t\t\tName:  \"Cache-Control\",\n\t\t\tValue: []string{\"private\"},\n\t\t},\n\t\t{\n\t\t\tName:  \"Content-Length\",\n\t\t\tValue: []string{\"0\"},\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "transport/internet/headers/noop/config.pb.go",
    "content": "package noop\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_headers_noop_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_noop_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_noop_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype ConnectionConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ConnectionConfig) Reset() {\n\t*x = ConnectionConfig{}\n\tmi := &file_transport_internet_headers_noop_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ConnectionConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ConnectionConfig) ProtoMessage() {}\n\nfunc (x *ConnectionConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_noop_config_proto_msgTypes[1]\n\tif 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 ConnectionConfig.ProtoReflect.Descriptor instead.\nfunc (*ConnectionConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_noop_config_proto_rawDescGZIP(), []int{1}\n}\n\nvar File_transport_internet_headers_noop_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_noop_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\",transport/internet/headers/noop/config.proto\\x12*v2ray.core.transport.internet.headers.noop\\\"\\b\\n\" +\n\t\"\\x06Config\\\"\\x12\\n\" +\n\t\"\\x10ConnectionConfigB\\x9f\\x01\\n\" +\n\t\".com.v2ray.core.transport.internet.headers.noopP\\x01Z>github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop\\xaa\\x02*V2Ray.Core.Transport.Internet.Headers.Noopb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_noop_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_noop_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_noop_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_noop_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_noop_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_noop_config_proto_rawDesc), len(file_transport_internet_headers_noop_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_noop_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_noop_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_headers_noop_config_proto_goTypes = []any{\n\t(*Config)(nil),           // 0: v2ray.core.transport.internet.headers.noop.Config\n\t(*ConnectionConfig)(nil), // 1: v2ray.core.transport.internet.headers.noop.ConnectionConfig\n}\nvar file_transport_internet_headers_noop_config_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_transport_internet_headers_noop_config_proto_init() }\nfunc file_transport_internet_headers_noop_config_proto_init() {\n\tif File_transport_internet_headers_noop_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_noop_config_proto_rawDesc), len(file_transport_internet_headers_noop_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_noop_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_noop_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_noop_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_noop_config_proto = out.File\n\tfile_transport_internet_headers_noop_config_proto_goTypes = nil\n\tfile_transport_internet_headers_noop_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/noop/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.noop;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Noop\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop\";\noption java_package = \"com.v2ray.core.transport.internet.headers.noop\";\noption java_multiple_files = true;\n\nmessage Config {}\n\nmessage ConnectionConfig {}\n"
  },
  {
    "path": "transport/internet/headers/noop/noop.go",
    "content": "package noop\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype Header struct{}\n\nfunc (Header) Size() int32 {\n\treturn 0\n}\n\n// Serialize implements PacketHeader.\nfunc (Header) Serialize([]byte) {}\n\nfunc NewHeader(context.Context, interface{}) (interface{}, error) {\n\treturn Header{}, nil\n}\n\ntype ConnectionHeader struct{}\n\nfunc (ConnectionHeader) Client(conn net.Conn) net.Conn {\n\treturn conn\n}\n\nfunc (ConnectionHeader) Server(conn net.Conn) net.Conn {\n\treturn conn\n}\n\nfunc NewConnectionHeader(context.Context, interface{}) (interface{}, error) {\n\treturn ConnectionHeader{}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), NewHeader))\n\tcommon.Must(common.RegisterConfig((*ConnectionConfig)(nil), NewConnectionHeader))\n}\n"
  },
  {
    "path": "transport/internet/headers/srtp/config.pb.go",
    "content": "package srtp\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tVersion       uint32                 `protobuf:\"varint,1,opt,name=version,proto3\" json:\"version,omitempty\"`\n\tPadding       bool                   `protobuf:\"varint,2,opt,name=padding,proto3\" json:\"padding,omitempty\"`\n\tExtension     bool                   `protobuf:\"varint,3,opt,name=extension,proto3\" json:\"extension,omitempty\"`\n\tCsrcCount     uint32                 `protobuf:\"varint,4,opt,name=csrc_count,json=csrcCount,proto3\" json:\"csrc_count,omitempty\"`\n\tMarker        bool                   `protobuf:\"varint,5,opt,name=marker,proto3\" json:\"marker,omitempty\"`\n\tPayloadType   uint32                 `protobuf:\"varint,6,opt,name=payload_type,json=payloadType,proto3\" json:\"payload_type,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_headers_srtp_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_srtp_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_srtp_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetVersion() uint32 {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetPadding() bool {\n\tif x != nil {\n\t\treturn x.Padding\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetExtension() bool {\n\tif x != nil {\n\t\treturn x.Extension\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetCsrcCount() uint32 {\n\tif x != nil {\n\t\treturn x.CsrcCount\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetMarker() bool {\n\tif x != nil {\n\t\treturn x.Marker\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetPayloadType() uint32 {\n\tif x != nil {\n\t\treturn x.PayloadType\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_headers_srtp_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_srtp_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\",transport/internet/headers/srtp/config.proto\\x12*v2ray.core.transport.internet.headers.srtp\\\"\\xb4\\x01\\n\" +\n\t\"\\x06Config\\x12\\x18\\n\" +\n\t\"\\aversion\\x18\\x01 \\x01(\\rR\\aversion\\x12\\x18\\n\" +\n\t\"\\apadding\\x18\\x02 \\x01(\\bR\\apadding\\x12\\x1c\\n\" +\n\t\"\\textension\\x18\\x03 \\x01(\\bR\\textension\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"csrc_count\\x18\\x04 \\x01(\\rR\\tcsrcCount\\x12\\x16\\n\" +\n\t\"\\x06marker\\x18\\x05 \\x01(\\bR\\x06marker\\x12!\\n\" +\n\t\"\\fpayload_type\\x18\\x06 \\x01(\\rR\\vpayloadTypeB\\x9f\\x01\\n\" +\n\t\".com.v2ray.core.transport.internet.headers.srtpP\\x01Z>github.com/v2fly/v2ray-core/v5/transport/internet/headers/srtp\\xaa\\x02*V2Ray.Core.Transport.Internet.Headers.Srtpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_srtp_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_srtp_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_srtp_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_srtp_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_srtp_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_srtp_config_proto_rawDesc), len(file_transport_internet_headers_srtp_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_srtp_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_srtp_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_headers_srtp_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.transport.internet.headers.srtp.Config\n}\nvar file_transport_internet_headers_srtp_config_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_transport_internet_headers_srtp_config_proto_init() }\nfunc file_transport_internet_headers_srtp_config_proto_init() {\n\tif File_transport_internet_headers_srtp_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_srtp_config_proto_rawDesc), len(file_transport_internet_headers_srtp_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_srtp_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_srtp_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_srtp_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_srtp_config_proto = out.File\n\tfile_transport_internet_headers_srtp_config_proto_goTypes = nil\n\tfile_transport_internet_headers_srtp_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/srtp/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.srtp;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Srtp\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/srtp\";\noption java_package = \"com.v2ray.core.transport.internet.headers.srtp\";\noption java_multiple_files = true;\n\nmessage Config {\n  uint32 version = 1;\n\tbool padding = 2;\n\tbool extension   = 3;\n\tuint32 csrc_count = 4;\n\tbool marker     = 5;\n\tuint32 payload_type = 6;\n}\n"
  },
  {
    "path": "transport/internet/headers/srtp/srtp.go",
    "content": "package srtp\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\ntype SRTP struct {\n\theader uint16\n\tnumber uint16\n}\n\nfunc (*SRTP) Size() int32 {\n\treturn 4\n}\n\n// Serialize implements PacketHeader.\nfunc (s *SRTP) Serialize(b []byte) {\n\ts.number++\n\tbinary.BigEndian.PutUint16(b, s.header)\n\tbinary.BigEndian.PutUint16(b[2:], s.number)\n}\n\n// New returns a new SRTP instance based on the given config.\nfunc New(ctx context.Context, config interface{}) (interface{}, error) {\n\treturn &SRTP{\n\t\theader: 0xB5E8,\n\t\tnumber: dice.RollUint16(),\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), New))\n}\n"
  },
  {
    "path": "transport/internet/headers/srtp/srtp_test.go",
    "content": "package srtp_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/srtp\"\n)\n\nfunc TestSRTPWrite(t *testing.T) {\n\tcontent := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'}\n\tsrtpRaw, err := New(context.Background(), &Config{})\n\tcommon.Must(err)\n\n\tsrtp := srtpRaw.(*SRTP)\n\n\tpayload := buf.New()\n\tsrtp.Serialize(payload.Extend(srtp.Size()))\n\tpayload.Write(content)\n\n\texpectedLen := int32(len(content)) + srtp.Size()\n\tif payload.Len() != expectedLen {\n\t\tt.Error(\"expected \", expectedLen, \" of bytes, but got \", payload.Len())\n\t}\n}\n"
  },
  {
    "path": "transport/internet/headers/tls/config.pb.go",
    "content": "package tls\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 PacketConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *PacketConfig) Reset() {\n\t*x = PacketConfig{}\n\tmi := &file_transport_internet_headers_tls_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *PacketConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PacketConfig) ProtoMessage() {}\n\nfunc (x *PacketConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_tls_config_proto_msgTypes[0]\n\tif 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 PacketConfig.ProtoReflect.Descriptor instead.\nfunc (*PacketConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_tls_config_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_transport_internet_headers_tls_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_tls_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"+transport/internet/headers/tls/config.proto\\x12)v2ray.core.transport.internet.headers.tls\\\"\\x0e\\n\" +\n\t\"\\fPacketConfigB\\x9c\\x01\\n\" +\n\t\"-com.v2ray.core.transport.internet.headers.tlsP\\x01Z=github.com/v2fly/v2ray-core/v5/transport/internet/headers/tls\\xaa\\x02)V2Ray.Core.Transport.Internet.Headers.Tlsb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_tls_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_tls_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_tls_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_tls_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_tls_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_tls_config_proto_rawDesc), len(file_transport_internet_headers_tls_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_tls_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_tls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_headers_tls_config_proto_goTypes = []any{\n\t(*PacketConfig)(nil), // 0: v2ray.core.transport.internet.headers.tls.PacketConfig\n}\nvar file_transport_internet_headers_tls_config_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_transport_internet_headers_tls_config_proto_init() }\nfunc file_transport_internet_headers_tls_config_proto_init() {\n\tif File_transport_internet_headers_tls_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_tls_config_proto_rawDesc), len(file_transport_internet_headers_tls_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_tls_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_tls_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_tls_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_tls_config_proto = out.File\n\tfile_transport_internet_headers_tls_config_proto_goTypes = nil\n\tfile_transport_internet_headers_tls_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/tls/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.tls;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Tls\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/tls\";\noption java_package = \"com.v2ray.core.transport.internet.headers.tls\";\noption java_multiple_files = true;\n\nmessage PacketConfig {}\n"
  },
  {
    "path": "transport/internet/headers/tls/dtls.go",
    "content": "package tls\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\n// DTLS writes header as DTLS. See https://tools.ietf.org/html/rfc6347\ntype DTLS struct {\n\tepoch    uint16\n\tlength   uint16\n\tsequence uint32\n}\n\n// Size implements PacketHeader.\nfunc (*DTLS) Size() int32 {\n\treturn 1 + 2 + 2 + 6 + 2\n}\n\n// Serialize implements PacketHeader.\nfunc (d *DTLS) Serialize(b []byte) {\n\tb[0] = 23 // application data\n\tb[1] = 254\n\tb[2] = 253\n\tb[3] = byte(d.epoch >> 8)\n\tb[4] = byte(d.epoch)\n\tb[5] = 0\n\tb[6] = 0\n\tb[7] = byte(d.sequence >> 24)\n\tb[8] = byte(d.sequence >> 16)\n\tb[9] = byte(d.sequence >> 8)\n\tb[10] = byte(d.sequence)\n\td.sequence++\n\tb[11] = byte(d.length >> 8)\n\tb[12] = byte(d.length)\n\td.length += 17\n\tif d.length > 100 {\n\t\td.length -= 50\n\t}\n}\n\n// New creates a new UTP header for the given config.\nfunc New(ctx context.Context, config interface{}) (interface{}, error) {\n\treturn &DTLS{\n\t\tepoch:    dice.RollUint16(),\n\t\tsequence: 0,\n\t\tlength:   17,\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*PacketConfig)(nil), New))\n}\n"
  },
  {
    "path": "transport/internet/headers/tls/dtls_test.go",
    "content": "package tls_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/tls\"\n)\n\nfunc TestDTLSWrite(t *testing.T) {\n\tcontent := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'}\n\tdtlsRaw, err := New(context.Background(), &PacketConfig{})\n\tcommon.Must(err)\n\n\tdtls := dtlsRaw.(*DTLS)\n\n\tpayload := buf.New()\n\tdtls.Serialize(payload.Extend(dtls.Size()))\n\tpayload.Write(content)\n\n\tif payload.Len() != int32(len(content))+dtls.Size() {\n\t\tt.Error(\"payload len: \", payload.Len(), \" want \", int32(len(content))+dtls.Size())\n\t}\n}\n"
  },
  {
    "path": "transport/internet/headers/utp/config.pb.go",
    "content": "package utp\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tVersion       uint32                 `protobuf:\"varint,1,opt,name=version,proto3\" json:\"version,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_headers_utp_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_utp_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_utp_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetVersion() uint32 {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_headers_utp_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_utp_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"+transport/internet/headers/utp/config.proto\\x12)v2ray.core.transport.internet.headers.utp\\\"\\\"\\n\" +\n\t\"\\x06Config\\x12\\x18\\n\" +\n\t\"\\aversion\\x18\\x01 \\x01(\\rR\\aversionB\\x9c\\x01\\n\" +\n\t\"-com.v2ray.core.transport.internet.headers.utpP\\x01Z=github.com/v2fly/v2ray-core/v5/transport/internet/headers/utp\\xaa\\x02)V2Ray.Core.Transport.Internet.Headers.Utpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_utp_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_utp_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_utp_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_utp_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_utp_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_utp_config_proto_rawDesc), len(file_transport_internet_headers_utp_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_utp_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_utp_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_headers_utp_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.transport.internet.headers.utp.Config\n}\nvar file_transport_internet_headers_utp_config_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_transport_internet_headers_utp_config_proto_init() }\nfunc file_transport_internet_headers_utp_config_proto_init() {\n\tif File_transport_internet_headers_utp_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_utp_config_proto_rawDesc), len(file_transport_internet_headers_utp_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_utp_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_utp_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_utp_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_utp_config_proto = out.File\n\tfile_transport_internet_headers_utp_config_proto_goTypes = nil\n\tfile_transport_internet_headers_utp_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/utp/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.utp;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Utp\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/utp\";\noption java_package = \"com.v2ray.core.transport.internet.headers.utp\";\noption java_multiple_files = true;\n\nmessage Config {\n  uint32 version = 1;\n}\n"
  },
  {
    "path": "transport/internet/headers/utp/utp.go",
    "content": "package utp\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\ntype UTP struct {\n\theader       byte\n\textension    byte\n\tconnectionID uint16\n}\n\nfunc (*UTP) Size() int32 {\n\treturn 4\n}\n\n// Serialize implements PacketHeader.\nfunc (u *UTP) Serialize(b []byte) {\n\tbinary.BigEndian.PutUint16(b, u.connectionID)\n\tb[2] = u.header\n\tb[3] = u.extension\n}\n\n// New creates a new UTP header for the given config.\nfunc New(ctx context.Context, config interface{}) (interface{}, error) {\n\treturn &UTP{\n\t\theader:       1,\n\t\textension:    0,\n\t\tconnectionID: dice.RollUint16(),\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), New))\n}\n"
  },
  {
    "path": "transport/internet/headers/utp/utp_test.go",
    "content": "package utp_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/utp\"\n)\n\nfunc TestUTPWrite(t *testing.T) {\n\tcontent := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'}\n\tutpRaw, err := New(context.Background(), &Config{})\n\tcommon.Must(err)\n\n\tutp := utpRaw.(*UTP)\n\n\tpayload := buf.New()\n\tutp.Serialize(payload.Extend(utp.Size()))\n\tpayload.Write(content)\n\n\tif payload.Len() != int32(len(content))+utp.Size() {\n\t\tt.Error(\"unexpected payload length: \", payload.Len())\n\t}\n}\n"
  },
  {
    "path": "transport/internet/headers/wechat/config.pb.go",
    "content": "package wechat\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 VideoConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *VideoConfig) Reset() {\n\t*x = VideoConfig{}\n\tmi := &file_transport_internet_headers_wechat_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *VideoConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*VideoConfig) ProtoMessage() {}\n\nfunc (x *VideoConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_wechat_config_proto_msgTypes[0]\n\tif 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 VideoConfig.ProtoReflect.Descriptor instead.\nfunc (*VideoConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_wechat_config_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_transport_internet_headers_wechat_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_wechat_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\".transport/internet/headers/wechat/config.proto\\x12,v2ray.core.transport.internet.headers.wechat\\\"\\r\\n\" +\n\t\"\\vVideoConfigB\\xa5\\x01\\n\" +\n\t\"0com.v2ray.core.transport.internet.headers.wechatP\\x01Z@github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\\xaa\\x02,V2Ray.Core.Transport.Internet.Headers.Wechatb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_wechat_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_wechat_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_wechat_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_wechat_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_wechat_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_wechat_config_proto_rawDesc), len(file_transport_internet_headers_wechat_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_wechat_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_wechat_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_headers_wechat_config_proto_goTypes = []any{\n\t(*VideoConfig)(nil), // 0: v2ray.core.transport.internet.headers.wechat.VideoConfig\n}\nvar file_transport_internet_headers_wechat_config_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_transport_internet_headers_wechat_config_proto_init() }\nfunc file_transport_internet_headers_wechat_config_proto_init() {\n\tif File_transport_internet_headers_wechat_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_wechat_config_proto_rawDesc), len(file_transport_internet_headers_wechat_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_wechat_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_wechat_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_wechat_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_wechat_config_proto = out.File\n\tfile_transport_internet_headers_wechat_config_proto_goTypes = nil\n\tfile_transport_internet_headers_wechat_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/wechat/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.wechat;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Wechat\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\";\noption java_package = \"com.v2ray.core.transport.internet.headers.wechat\";\noption java_multiple_files = true;\n\nmessage VideoConfig {}\n"
  },
  {
    "path": "transport/internet/headers/wechat/wechat.go",
    "content": "package wechat\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n)\n\ntype VideoChat struct {\n\tsn uint32\n}\n\nfunc (vc *VideoChat) Size() int32 {\n\treturn 13\n}\n\n// Serialize implements PacketHeader.\nfunc (vc *VideoChat) Serialize(b []byte) {\n\tvc.sn++\n\tb[0] = 0xa1\n\tb[1] = 0x08\n\tbinary.BigEndian.PutUint32(b[2:], vc.sn) // b[2:6]\n\tb[6] = 0x00\n\tb[7] = 0x10\n\tb[8] = 0x11\n\tb[9] = 0x18\n\tb[10] = 0x30\n\tb[11] = 0x22\n\tb[12] = 0x30\n}\n\n// NewVideoChat returns a new VideoChat instance based on given config.\nfunc NewVideoChat(ctx context.Context, config interface{}) (interface{}, error) {\n\treturn &VideoChat{\n\t\tsn: uint32(dice.RollUint16()),\n\t}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*VideoConfig)(nil), NewVideoChat))\n}\n"
  },
  {
    "path": "transport/internet/headers/wechat/wechat_test.go",
    "content": "package wechat_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wechat\"\n)\n\nfunc TestUTPWrite(t *testing.T) {\n\tvideoRaw, err := NewVideoChat(context.Background(), &VideoConfig{})\n\tcommon.Must(err)\n\n\tvideo := videoRaw.(*VideoChat)\n\n\tpayload := buf.New()\n\tvideo.Serialize(payload.Extend(video.Size()))\n\n\tif payload.Len() != video.Size() {\n\t\tt.Error(\"expected payload size \", video.Size(), \" but got \", payload.Len())\n\t}\n}\n"
  },
  {
    "path": "transport/internet/headers/wireguard/config.pb.go",
    "content": "package wireguard\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 WireguardConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *WireguardConfig) Reset() {\n\t*x = WireguardConfig{}\n\tmi := &file_transport_internet_headers_wireguard_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *WireguardConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*WireguardConfig) ProtoMessage() {}\n\nfunc (x *WireguardConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_headers_wireguard_config_proto_msgTypes[0]\n\tif 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 WireguardConfig.ProtoReflect.Descriptor instead.\nfunc (*WireguardConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_headers_wireguard_config_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_transport_internet_headers_wireguard_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_headers_wireguard_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"1transport/internet/headers/wireguard/config.proto\\x12/v2ray.core.transport.internet.headers.wireguard\\\"\\x11\\n\" +\n\t\"\\x0fWireguardConfigB\\xae\\x01\\n\" +\n\t\"3com.v2ray.core.transport.internet.headers.wireguardP\\x01ZCgithub.com/v2fly/v2ray-core/v5/transport/internet/headers/wireguard\\xaa\\x02/V2Ray.Core.Transport.Internet.Headers.Wireguardb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_headers_wireguard_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_headers_wireguard_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_headers_wireguard_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_headers_wireguard_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_headers_wireguard_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_headers_wireguard_config_proto_rawDesc), len(file_transport_internet_headers_wireguard_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_headers_wireguard_config_proto_rawDescData\n}\n\nvar file_transport_internet_headers_wireguard_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_headers_wireguard_config_proto_goTypes = []any{\n\t(*WireguardConfig)(nil), // 0: v2ray.core.transport.internet.headers.wireguard.WireguardConfig\n}\nvar file_transport_internet_headers_wireguard_config_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_transport_internet_headers_wireguard_config_proto_init() }\nfunc file_transport_internet_headers_wireguard_config_proto_init() {\n\tif File_transport_internet_headers_wireguard_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_headers_wireguard_config_proto_rawDesc), len(file_transport_internet_headers_wireguard_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_headers_wireguard_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_headers_wireguard_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_headers_wireguard_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_headers_wireguard_config_proto = out.File\n\tfile_transport_internet_headers_wireguard_config_proto_goTypes = nil\n\tfile_transport_internet_headers_wireguard_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/headers/wireguard/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.headers.wireguard;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Headers.Wireguard\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wireguard\";\noption java_package = \"com.v2ray.core.transport.internet.headers.wireguard\";\noption java_multiple_files = true;\n\nmessage WireguardConfig {}\n"
  },
  {
    "path": "transport/internet/headers/wireguard/wireguard.go",
    "content": "package wireguard\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype Wireguard struct{}\n\nfunc (Wireguard) Size() int32 {\n\treturn 4\n}\n\n// Serialize implements PacketHeader.\nfunc (Wireguard) Serialize(b []byte) {\n\tb[0] = 0x04\n\tb[1] = 0x00\n\tb[2] = 0x00\n\tb[3] = 0x00\n}\n\n// NewWireguard returns a new VideoChat instance based on given config.\nfunc NewWireguard(ctx context.Context, config interface{}) (interface{}, error) {\n\treturn Wireguard{}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*WireguardConfig)(nil), NewWireguard))\n}\n"
  },
  {
    "path": "transport/internet/http/config.go",
    "content": "package http\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst protocolName = \"http\"\n\nfunc (c *Config) getHosts() []string {\n\tif len(c.Host) == 0 {\n\t\treturn []string{\"www.example.com\"}\n\t}\n\treturn c.Host\n}\n\nfunc (c *Config) isValidHost(host string) bool {\n\thosts := c.getHosts()\n\tfor _, h := range hosts {\n\t\tif h == host {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Config) getRandomHost() string {\n\thosts := c.getHosts()\n\treturn hosts[dice.Roll(len(hosts))]\n}\n\nfunc (c *Config) getNormalizedPath() string {\n\tif c.Path == \"\" {\n\t\treturn \"/\"\n\t}\n\tif c.Path[0] != '/' {\n\t\treturn \"/\" + c.Path\n\t}\n\treturn c.Path\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/http/config.pb.go",
    "content": "package http\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\thttp \"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tHost          []string               `protobuf:\"bytes,1,rep,name=host,proto3\" json:\"host,omitempty\"`\n\tPath          string                 `protobuf:\"bytes,2,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tMethod        string                 `protobuf:\"bytes,3,opt,name=method,proto3\" json:\"method,omitempty\"`\n\tHeader        []*http.Header         `protobuf:\"bytes,4,rep,name=header,proto3\" json:\"header,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_http_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_http_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_http_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetHost() []string {\n\tif x != nil {\n\t\treturn x.Host\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetMethod() string {\n\tif x != nil {\n\t\treturn x.Method\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetHeader() []*http.Header {\n\tif x != nil {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_http_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_http_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$transport/internet/http/config.proto\\x12\\\"v2ray.core.transport.internet.http\\x1a common/protoext/extensions.proto\\x1a,transport/internet/headers/http/config.proto\\\"\\xb1\\x01\\n\" +\n\t\"\\x06Config\\x12\\x12\\n\" +\n\t\"\\x04host\\x18\\x01 \\x03(\\tR\\x04host\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x02 \\x01(\\tR\\x04path\\x12\\x16\\n\" +\n\t\"\\x06method\\x18\\x03 \\x01(\\tR\\x06method\\x12J\\n\" +\n\t\"\\x06header\\x18\\x04 \\x03(\\v22.v2ray.core.transport.internet.headers.http.HeaderR\\x06header:\\x1b\\x82\\xb5\\x18\\x17\\n\" +\n\t\"\\ttransport\\x12\\x02h2\\x8a\\xff)\\x04httpB\\x87\\x01\\n\" +\n\t\"&com.v2ray.core.transport.internet.httpP\\x01Z6github.com/v2fly/v2ray-core/v5/transport/internet/http\\xaa\\x02\\\"V2Ray.Core.Transport.Internet.Httpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_http_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_http_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_http_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_http_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_http_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_http_config_proto_rawDesc), len(file_transport_internet_http_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_http_config_proto_rawDescData\n}\n\nvar file_transport_internet_http_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_http_config_proto_goTypes = []any{\n\t(*Config)(nil),      // 0: v2ray.core.transport.internet.http.Config\n\t(*http.Header)(nil), // 1: v2ray.core.transport.internet.headers.http.Header\n}\nvar file_transport_internet_http_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.http.Config.header:type_name -> v2ray.core.transport.internet.headers.http.Header\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_http_config_proto_init() }\nfunc file_transport_internet_http_config_proto_init() {\n\tif File_transport_internet_http_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_http_config_proto_rawDesc), len(file_transport_internet_http_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_http_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_http_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_http_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_http_config_proto = out.File\n\tfile_transport_internet_http_config_proto_goTypes = nil\n\tfile_transport_internet_http_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/http/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.http;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Http\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/http\";\noption java_package = \"com.v2ray.core.transport.internet.http\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nimport \"transport/internet/headers/http/config.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"h2\";\n\n  option (v2ray.core.common.protoext.message_opt).transport_original_name = \"http\";\n  repeated string host = 1;\n  string path = 2;\n  string method = 3;\n  repeated v2ray.core.transport.internet.headers.http.Header header = 4;\n}\n"
  },
  {
    "path": "transport/internet/http/dialer.go",
    "content": "package http\n\nimport (\n\t\"context\"\n\tgotls \"crypto/tls\"\n\tgonet \"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\n\t\"golang.org/x/net/http2\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nvar (\n\tglobalDialerMap    map[net.Destination]*http.Client\n\tglobalDialerAccess sync.Mutex\n)\n\ntype dialerCanceller func()\n\nfunc getHTTPClient(ctx context.Context, dest net.Destination, securityEngine *security.Engine, streamSettings *internet.MemoryStreamConfig) (*http.Client, dialerCanceller) {\n\tglobalDialerAccess.Lock()\n\tdefer globalDialerAccess.Unlock()\n\n\tcanceller := func() {\n\t\tglobalDialerAccess.Lock()\n\t\tdefer globalDialerAccess.Unlock()\n\t\tdelete(globalDialerMap, dest)\n\t}\n\n\tif globalDialerMap == nil {\n\t\tglobalDialerMap = make(map[net.Destination]*http.Client)\n\t}\n\n\tif client, found := globalDialerMap[dest]; found {\n\t\treturn client, canceller\n\t}\n\n\ttransport := &http2.Transport{\n\t\tDialTLSContext: func(_ context.Context, network, addr string, tlsConfig *gotls.Config) (gonet.Conn, error) {\n\t\t\trawHost, rawPort, err := net.SplitHostPort(addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif len(rawPort) == 0 {\n\t\t\t\trawPort = \"443\"\n\t\t\t}\n\t\t\tport, err := net.PortFromString(rawPort)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\taddress := net.ParseAddress(rawHost)\n\n\t\t\tdetachedContext := core.ToBackgroundDetachedContext(ctx)\n\t\t\tpconn, err := internet.DialSystem(detachedContext, net.TCPDestination(address, port), streamSettings.SocketSettings)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tcn, err := (*securityEngine).Client(pconn,\n\t\t\t\tsecurity.OptionWithDestination{Dest: dest})\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tprotocol := \"\"\n\t\t\tif connAPLNGetter, ok := cn.(security.ConnectionApplicationProtocol); ok {\n\t\t\t\tconnectionALPN, err := connAPLNGetter.GetConnectionApplicationProtocol()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, newError(\"failed to get connection ALPN\").Base(err).AtWarning()\n\t\t\t\t}\n\t\t\t\tprotocol = connectionALPN\n\t\t\t}\n\n\t\t\tif protocol != http2.NextProtoTLS {\n\t\t\t\treturn nil, newError(\"http2: unexpected ALPN protocol \" + protocol + \"; want q\" + http2.NextProtoTLS).AtError()\n\t\t\t}\n\t\t\treturn cn, nil\n\t\t},\n\t}\n\n\tclient := &http.Client{\n\t\tTransport: transport,\n\t}\n\n\tglobalDialerMap[dest] = client\n\treturn client, canceller\n}\n\n// Dial dials a new TCP connection to the given destination.\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\thttpSettings := streamSettings.ProtocolSettings.(*Config)\n\tsecurityEngine, err := security.CreateSecurityEngineFromSettings(ctx, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create security engine\").Base(err)\n\t}\n\tif securityEngine == nil {\n\t\treturn nil, newError(\"TLS must be enabled for http transport.\").AtWarning()\n\t}\n\tclient, canceller := getHTTPClient(ctx, dest, &securityEngine, streamSettings)\n\n\topts := pipe.OptionsFromContext(ctx)\n\tpreader, pwriter := pipe.New(opts...)\n\tbreader := &buf.BufferedReader{Reader: preader}\n\n\thttpMethod := \"PUT\"\n\tif httpSettings.Method != \"\" {\n\t\thttpMethod = httpSettings.Method\n\t}\n\n\thttpHeaders := make(http.Header)\n\n\tfor _, httpHeader := range httpSettings.Header {\n\t\tfor _, httpHeaderValue := range httpHeader.Value {\n\t\t\thttpHeaders.Set(httpHeader.Name, httpHeaderValue)\n\t\t}\n\t}\n\n\trequest := &http.Request{\n\t\tMethod: httpMethod,\n\t\tHost:   httpSettings.getRandomHost(),\n\t\tBody:   breader,\n\t\tURL: &url.URL{\n\t\t\tScheme: \"https\",\n\t\t\tHost:   dest.NetAddr(),\n\t\t\tPath:   httpSettings.getNormalizedPath(),\n\t\t},\n\t\tProto:      \"HTTP/2\",\n\t\tProtoMajor: 2,\n\t\tProtoMinor: 0,\n\t\tHeader:     httpHeaders,\n\t}\n\t// Disable any compression method from server.\n\trequest.Header.Set(\"Accept-Encoding\", \"identity\")\n\n\tresponse, err := client.Do(request) // nolint: bodyclose\n\tif err != nil {\n\t\tcanceller()\n\t\treturn nil, newError(\"failed to dial to \", dest).Base(err).AtWarning()\n\t}\n\tif response.StatusCode != 200 {\n\t\treturn nil, newError(\"unexpected status\", response.StatusCode).AtWarning()\n\t}\n\n\tbwriter := buf.NewBufferedWriter(pwriter)\n\tcommon.Must(bwriter.SetBuffered(false))\n\treturn net.NewConnection(\n\t\tnet.ConnectionOutput(response.Body),\n\t\tnet.ConnectionInput(bwriter),\n\t\tnet.ConnectionOnClose(common.ChainedClosable{breader, bwriter, response.Body}),\n\t), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n"
  },
  {
    "path": "transport/internet/http/errors.generated.go",
    "content": "package http\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/http/http.go",
    "content": "package http\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/http/http_test.go",
    "content": "package http_test\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/http\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc TestHTTPConnection(t *testing.T) {\n\tport := tcp.PickPort()\n\n\tlistener, err := Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"http\",\n\t\tProtocolSettings: &Config{},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.CommonName(\"www.v2fly.org\")))},\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tb := buf.New()\n\t\t\tdefer b.Release()\n\n\t\t\tfor {\n\t\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t_, err := conn.Write(b.Bytes())\n\t\t\t\tcommon.Must(err)\n\t\t\t}\n\t\t}()\n\t})\n\tcommon.Must(err)\n\n\tdefer listener.Close()\n\n\ttime.Sleep(time.Second)\n\n\tdctx := context.Background()\n\tconn, err := Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"http\",\n\t\tProtocolSettings: &Config{},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\tAllowInsecure: true,\n\t\t},\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst N = 1024\n\tb1 := make([]byte, N)\n\tcommon.Must2(rand.Read(b1))\n\tb2 := buf.New()\n\n\tnBytes, err := conn.Write(b1)\n\tcommon.Must(err)\n\tif nBytes != N {\n\t\tt.Error(\"write: \", nBytes)\n\t}\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tnBytes, err = conn.Write(b1)\n\tcommon.Must(err)\n\tif nBytes != N {\n\t\tt.Error(\"write: \", nBytes)\n\t}\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/http/hub.go",
    "content": "package http\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/net/http2\"\n\t\"golang.org/x/net/http2/h2c\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\thttp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\ntype Listener struct {\n\tserver  *http.Server\n\thandler internet.ConnHandler\n\tlocal   net.Addr\n\tconfig  *Config\n}\n\nfunc (l *Listener) Addr() net.Addr {\n\treturn l.local\n}\n\nfunc (l *Listener) Close() error {\n\treturn l.server.Close()\n}\n\ntype flushWriter struct {\n\tw io.Writer\n\td *done.Instance\n}\n\nfunc (fw flushWriter) Write(p []byte) (n int, err error) {\n\tif fw.d.Done() {\n\t\treturn 0, io.ErrClosedPipe\n\t}\n\n\tn, err = fw.w.Write(p)\n\tif f, ok := fw.w.(http.Flusher); ok {\n\t\tf.Flush()\n\t}\n\treturn\n}\n\nfunc (l *Listener) ServeHTTP(writer http.ResponseWriter, request *http.Request) {\n\thost := request.Host\n\tif len(l.config.Host) != 0 && !l.config.isValidHost(host) {\n\t\twriter.WriteHeader(404)\n\t\treturn\n\t}\n\tpath := l.config.getNormalizedPath()\n\tif !strings.HasPrefix(request.URL.Path, path) {\n\t\twriter.WriteHeader(404)\n\t\treturn\n\t}\n\n\twriter.Header().Set(\"Cache-Control\", \"no-store\")\n\n\tfor _, httpHeader := range l.config.Header {\n\t\tfor _, httpHeaderValue := range httpHeader.Value {\n\t\t\twriter.Header().Set(httpHeader.Name, httpHeaderValue)\n\t\t}\n\t}\n\n\twriter.WriteHeader(200)\n\tif f, ok := writer.(http.Flusher); ok {\n\t\tf.Flush()\n\t}\n\n\tremoteAddr := l.Addr()\n\tdest, err := net.ParseDestination(request.RemoteAddr)\n\tif err != nil {\n\t\tnewError(\"failed to parse request remote addr: \", request.RemoteAddr).Base(err).WriteToLog()\n\t} else {\n\t\tremoteAddr = &net.TCPAddr{\n\t\t\tIP:   dest.Address.IP(),\n\t\t\tPort: int(dest.Port),\n\t\t}\n\t}\n\n\tforwardedAddress := http_proto.ParseXForwardedFor(request.Header)\n\tif len(forwardedAddress) > 0 && forwardedAddress[0].Family().IsIP() {\n\t\tremoteAddr = &net.TCPAddr{\n\t\t\tIP:   forwardedAddress[0].IP(),\n\t\t\tPort: 0,\n\t\t}\n\t}\n\n\tdone := done.New()\n\tconn := net.NewConnection(\n\t\tnet.ConnectionOutput(request.Body),\n\t\tnet.ConnectionInput(flushWriter{w: writer, d: done}),\n\t\tnet.ConnectionOnClose(common.ChainedClosable{done, request.Body}),\n\t\tnet.ConnectionLocalAddr(l.Addr()),\n\t\tnet.ConnectionRemoteAddr(remoteAddr),\n\t)\n\tl.handler(conn)\n\t<-done.Wait()\n}\n\nfunc Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {\n\thttpSettings := streamSettings.ProtocolSettings.(*Config)\n\tvar listener *Listener\n\tif port == net.Port(0) { // unix\n\t\tlistener = &Listener{\n\t\t\thandler: handler,\n\t\t\tlocal: &net.UnixAddr{\n\t\t\t\tName: address.Domain(),\n\t\t\t\tNet:  \"unix\",\n\t\t\t},\n\t\t\tconfig: httpSettings,\n\t\t}\n\t} else { // tcp\n\t\tlistener = &Listener{\n\t\t\thandler: handler,\n\t\t\tlocal: &net.TCPAddr{\n\t\t\t\tIP:   address.IP(),\n\t\t\t\tPort: int(port),\n\t\t\t},\n\t\t\tconfig: httpSettings,\n\t\t}\n\t}\n\n\tvar server *http.Server\n\tconfig := tls.ConfigFromStreamSettings(streamSettings)\n\tif config == nil {\n\t\th2s := &http2.Server{}\n\n\t\tserver = &http.Server{\n\t\t\tAddr:              serial.Concat(address, \":\", port),\n\t\t\tHandler:           h2c.NewHandler(listener, h2s),\n\t\t\tReadHeaderTimeout: time.Second * 4,\n\t\t}\n\t} else {\n\t\tserver = &http.Server{\n\t\t\tAddr:              serial.Concat(address, \":\", port),\n\t\t\tTLSConfig:         config.GetTLSConfig(tls.WithNextProto(\"h2\")),\n\t\t\tHandler:           listener,\n\t\t\tReadHeaderTimeout: time.Second * 4,\n\t\t}\n\t}\n\n\tif streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol {\n\t\tnewError(\"accepting PROXY protocol\").AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tlistener.server = server\n\tgo func() {\n\t\tvar streamListener net.Listener\n\t\tvar err error\n\t\tif port == net.Port(0) { // unix\n\t\t\tstreamListener, err = internet.ListenSystem(ctx, &net.UnixAddr{\n\t\t\t\tName: address.Domain(),\n\t\t\t\tNet:  \"unix\",\n\t\t\t}, streamSettings.SocketSettings)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to listen on \", address).Base(err).AtError().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn\n\t\t\t}\n\t\t} else { // tcp\n\t\t\tstreamListener, err = internet.ListenSystem(ctx, &net.TCPAddr{\n\t\t\t\tIP:   address.IP(),\n\t\t\t\tPort: int(port),\n\t\t\t}, streamSettings.SocketSettings)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to listen on \", address, \":\", port).Base(err).AtError().WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif config == nil {\n\t\t\terr = server.Serve(streamListener)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"stopping serving H2C\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t}\n\t\t} else {\n\t\t\terr = server.ServeTLS(streamListener, \"\", \"\")\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"stopping serving TLS\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn listener, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, Listen))\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/config.go",
    "content": "package httpupgrade\n\nfunc (c *Config) GetNormalizedPath() string {\n\tpath := c.Path\n\tif path == \"\" {\n\t\treturn \"/\"\n\t}\n\tif path[0] != '/' {\n\t\treturn \"/\" + path\n\t}\n\treturn path\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/config.pb.go",
    "content": "package httpupgrade\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Header struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tKey           string                 `protobuf:\"bytes,1,opt,name=key,proto3\" json:\"key,omitempty\"`\n\tValue         string                 `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Header) Reset() {\n\t*x = Header{}\n\tmi := &file_transport_internet_httpupgrade_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\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_transport_internet_httpupgrade_config_proto_msgTypes[0]\n\tif 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_transport_internet_httpupgrade_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Header) GetKey() string {\n\tif x != nil {\n\t\treturn x.Key\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate               protoimpl.MessageState `protogen:\"open.v1\"`\n\tPath                string                 `protobuf:\"bytes,1,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tHost                string                 `protobuf:\"bytes,2,opt,name=host,proto3\" json:\"host,omitempty\"`\n\tMaxEarlyData        int32                  `protobuf:\"varint,3,opt,name=max_early_data,json=maxEarlyData,proto3\" json:\"max_early_data,omitempty\"`\n\tEarlyDataHeaderName string                 `protobuf:\"bytes,4,opt,name=early_data_header_name,json=earlyDataHeaderName,proto3\" json:\"early_data_header_name,omitempty\"`\n\tHeader              []*Header              `protobuf:\"bytes,5,rep,name=header,proto3\" json:\"header,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_httpupgrade_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_httpupgrade_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_httpupgrade_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetHost() string {\n\tif x != nil {\n\t\treturn x.Host\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetMaxEarlyData() int32 {\n\tif x != nil {\n\t\treturn x.MaxEarlyData\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetEarlyDataHeaderName() string {\n\tif x != nil {\n\t\treturn x.EarlyDataHeaderName\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetHeader() []*Header {\n\tif x != nil {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_httpupgrade_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_httpupgrade_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"+transport/internet/httpupgrade/config.proto\\x121v2ray.core.transport.internet.request.httpupgrade\\x1a common/protoext/extensions.proto\\\"0\\n\" +\n\t\"\\x06Header\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value\\\"\\x80\\x02\\n\" +\n\t\"\\x06Config\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x01 \\x01(\\tR\\x04path\\x12\\x12\\n\" +\n\t\"\\x04host\\x18\\x02 \\x01(\\tR\\x04host\\x12$\\n\" +\n\t\"\\x0emax_early_data\\x18\\x03 \\x01(\\x05R\\fmaxEarlyData\\x123\\n\" +\n\t\"\\x16early_data_header_name\\x18\\x04 \\x01(\\tR\\x13earlyDataHeaderName\\x12Q\\n\" +\n\t\"\\x06header\\x18\\x05 \\x03(\\v29.v2ray.core.transport.internet.request.httpupgrade.HeaderR\\x06header: \\x82\\xb5\\x18\\x1c\\n\" +\n\t\"\\ttransport\\x12\\vhttpupgrade\\x90\\xff)\\x01B\\x9c\\x01\\n\" +\n\t\"-com.v2ray.core.transport.internet.httpupgradeP\\x01Z=github.com/v2fly/v2ray-core/v5/transport/internet/httpupgrade\\xaa\\x02)V2Ray.Core.Transport.Internet.HttpUpgradeb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_httpupgrade_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_httpupgrade_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_httpupgrade_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_httpupgrade_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_httpupgrade_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_httpupgrade_config_proto_rawDesc), len(file_transport_internet_httpupgrade_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_httpupgrade_config_proto_rawDescData\n}\n\nvar file_transport_internet_httpupgrade_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_httpupgrade_config_proto_goTypes = []any{\n\t(*Header)(nil), // 0: v2ray.core.transport.internet.request.httpupgrade.Header\n\t(*Config)(nil), // 1: v2ray.core.transport.internet.request.httpupgrade.Config\n}\nvar file_transport_internet_httpupgrade_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.request.httpupgrade.Config.header:type_name -> v2ray.core.transport.internet.request.httpupgrade.Header\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_httpupgrade_config_proto_init() }\nfunc file_transport_internet_httpupgrade_config_proto_init() {\n\tif File_transport_internet_httpupgrade_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_httpupgrade_config_proto_rawDesc), len(file_transport_internet_httpupgrade_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_httpupgrade_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_httpupgrade_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_httpupgrade_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_httpupgrade_config_proto = out.File\n\tfile_transport_internet_httpupgrade_config_proto_goTypes = nil\n\tfile_transport_internet_httpupgrade_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.httpupgrade;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.HttpUpgrade\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/httpupgrade\";\noption java_package = \"com.v2ray.core.transport.internet.httpupgrade\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Header {\n  string key = 1;\n  string value = 2;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"httpupgrade\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  string path = 1;\n  string host = 2;\n  int32 max_early_data = 3;\n  string early_data_header_name = 4;\n  repeated Header header = 5;\n}"
  },
  {
    "path": "transport/internet/httpupgrade/connection.go",
    "content": "package httpupgrade\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\ntype connection struct {\n\tconn       net.Conn\n\treader     io.Reader\n\tremoteAddr net.Addr\n\n\tshouldWait        bool\n\tdelayedDialFinish context.Context\n\tfinishedDial      context.CancelFunc\n\tdialer            delayedDialer\n}\n\ntype delayedDialer func(earlyData []byte) (conn net.Conn, earlyReply io.Reader, err error)\n\nfunc newConnectionWithPendingRead(conn net.Conn, remoteAddr net.Addr, earlyReplyReader io.Reader) *connection {\n\treturn &connection{\n\t\tconn:       conn,\n\t\tremoteAddr: remoteAddr,\n\t\treader:     earlyReplyReader,\n\t}\n}\n\nfunc newConnectionWithDelayedDial(dialer delayedDialer) *connection {\n\tctx, cancel := context.WithCancel(context.Background())\n\treturn &connection{\n\t\tshouldWait:        true,\n\t\tdelayedDialFinish: ctx,\n\t\tfinishedDial:      cancel,\n\t\tdialer:            dialer,\n\t}\n}\n\n// Read implements net.Conn.Read()\nfunc (c *connection) Read(b []byte) (int, error) {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\treturn 0, newError(\"unable to read delayed dial websocket connection as it do not exist\")\n\t\t}\n\t}\n\n\tif c.reader != nil {\n\t\tn, err := c.reader.Read(b)\n\t\tif err == io.EOF {\n\t\t\tc.reader = nil\n\t\t\treturn c.conn.Read(b)\n\t\t}\n\t\treturn n, err\n\t}\n\treturn c.conn.Read(b)\n}\n\n// Write implements io.Writer.\nfunc (c *connection) Write(b []byte) (int, error) {\n\tif c.shouldWait {\n\t\tvar err error\n\t\tvar earlyReply io.Reader\n\t\tc.conn, earlyReply, err = c.dialer(b)\n\t\tif earlyReply != nil {\n\t\t\tc.reader = earlyReply\n\t\t}\n\t\tc.finishedDial()\n\t\tif err != nil {\n\t\t\treturn 0, newError(\"Unable to proceed with delayed write\").Base(err)\n\t\t}\n\t\tc.remoteAddr = c.conn.RemoteAddr()\n\t\tc.shouldWait = false\n\t\treturn len(b), nil\n\t}\n\treturn c.conn.Write(b)\n}\n\nfunc (c *connection) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tmb = buf.Compact(mb)\n\tmb, err := buf.WriteMultiBuffer(c, mb)\n\tbuf.ReleaseMulti(mb)\n\treturn err\n}\n\nfunc (c *connection) Close() error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\treturn newError(\"unable to close delayed dial websocket connection as it do not exist\")\n\t\t}\n\t}\n\tvar closeErrors []interface{}\n\tif err := c.conn.Close(); err != nil {\n\t\tcloseErrors = append(closeErrors, err)\n\t}\n\tif len(closeErrors) > 0 {\n\t\treturn newError(\"failed to close connection\").Base(newError(serial.Concat(closeErrors...)))\n\t}\n\treturn nil\n}\n\nfunc (c *connection) LocalAddr() net.Addr {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\tnewError(\"websocket transport is not materialized when LocalAddr() is called\").AtWarning().WriteToLog()\n\t\t\treturn &net.UnixAddr{\n\t\t\t\tName: \"@placeholder\",\n\t\t\t\tNet:  \"unix\",\n\t\t\t}\n\t\t}\n\t}\n\treturn c.conn.LocalAddr()\n}\n\nfunc (c *connection) RemoteAddr() net.Addr {\n\treturn c.remoteAddr\n}\n\nfunc (c *connection) SetDeadline(t time.Time) error {\n\tif err := c.SetReadDeadline(t); err != nil {\n\t\treturn err\n\t}\n\treturn c.SetWriteDeadline(t)\n}\n\nfunc (c *connection) SetReadDeadline(t time.Time) error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\tnewError(\"httpupgrade transport is not materialized when SetReadDeadline() is called\").AtWarning().WriteToLog()\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn c.conn.SetReadDeadline(t)\n}\n\nfunc (c *connection) SetWriteDeadline(t time.Time) error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\tnewError(\"httpupgrade transport is not materialized when SetWriteDeadline() is called\").AtWarning().WriteToLog()\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn c.conn.SetWriteDeadline(t)\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/dialer.go",
    "content": "package httpupgrade\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon\"\n)\n\nfunc dialhttpUpgrade(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {\n\ttransportConfiguration := streamSettings.ProtocolSettings.(*Config)\n\n\tdialer := func(earlyData []byte) (net.Conn, io.Reader, error) {\n\t\tconn, err := transportcommon.DialWithSecuritySettings(ctx, dest, streamSettings)\n\t\tif err != nil {\n\t\t\treturn nil, nil, newError(\"failed to dial request to \", dest).Base(err)\n\t\t}\n\t\treq, err := http.NewRequest(\"GET\", transportConfiguration.GetNormalizedPath(), nil)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\treq.Header.Set(\"Connection\", \"upgrade\")\n\t\treq.Header.Set(\"Upgrade\", \"websocket\")\n\t\treq.Host = transportConfiguration.Host\n\n\t\tif transportConfiguration.Header != nil {\n\t\t\tfor _, value := range transportConfiguration.Header {\n\t\t\t\treq.Header.Set(value.Key, value.Value)\n\t\t\t}\n\t\t}\n\n\t\tearlyDataSize := len(earlyData)\n\t\tif earlyDataSize > int(transportConfiguration.MaxEarlyData) {\n\t\t\tearlyDataSize = int(transportConfiguration.MaxEarlyData)\n\t\t}\n\n\t\tif len(earlyData) > 0 {\n\t\t\tif transportConfiguration.EarlyDataHeaderName == \"\" {\n\t\t\t\treturn nil, nil, newError(\"EarlyDataHeaderName is not set\")\n\t\t\t}\n\t\t\treq.Header.Set(transportConfiguration.EarlyDataHeaderName, base64.URLEncoding.EncodeToString(earlyData))\n\t\t}\n\n\t\terr = req.Write(conn)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tif earlyData != nil && len(earlyData[earlyDataSize:]) > 0 {\n\t\t\t_, err = conn.Write(earlyData[earlyDataSize:])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, newError(\"failed to finish write early data\").Base(err)\n\t\t\t}\n\t\t}\n\n\t\tbufferedConn := bufio.NewReader(conn)\n\t\tresp, err := http.ReadResponse(bufferedConn, req) // nolint:bodyclose\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tif resp.Status == \"101 Switching Protocols\" &&\n\t\t\tstrings.ToLower(resp.Header.Get(\"Upgrade\")) == \"websocket\" &&\n\t\t\tstrings.ToLower(resp.Header.Get(\"Connection\")) == \"upgrade\" {\n\t\t\tearlyReplyReader := io.LimitReader(bufferedConn, int64(bufferedConn.Buffered()))\n\t\t\treturn conn, earlyReplyReader, nil\n\t\t}\n\n\t\treturn nil, nil, newError(\"unrecognized reply\")\n\t}\n\n\tif transportConfiguration.MaxEarlyData == 0 {\n\t\tconn, earlyReplyReader, err := dialer(nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tremoteAddr := conn.RemoteAddr()\n\n\t\treturn newConnectionWithPendingRead(conn, remoteAddr, earlyReplyReader), nil\n\t}\n\n\treturn newConnectionWithDelayedDial(dialer), nil\n}\n\nfunc dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tnewError(\"creating connection to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tconn, err := dialhttpUpgrade(ctx, dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial request to \", dest).Base(err)\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, dial))\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/errors.generated.go",
    "content": "package httpupgrade\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/httpupgrade.go",
    "content": "package httpupgrade\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst protocolName = \"httpupgrade\"\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn nil, newError(\"httpupgrade is a transport protocol.\")\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/httpupgrade/hub.go",
    "content": "package httpupgrade\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon\"\n)\n\ntype server struct {\n\tconfig *Config\n\n\taddConn        internet.ConnHandler\n\tinnnerListener net.Listener\n}\n\nfunc (s *server) Close() error {\n\treturn s.innnerListener.Close()\n}\n\nfunc (s *server) Addr() net.Addr {\n\treturn nil\n}\n\nfunc (s *server) Handle(conn net.Conn) {\n\tupgradedConn, err := s.upgrade(conn)\n\tif err != nil {\n\t\tconn.Close()\n\t\tnewError(\"failed to handle request\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\ts.addConn(upgradedConn)\n}\n\n// upgrade execute a fake websocket upgrade process and return the available connection\nfunc (s *server) upgrade(conn net.Conn) (internet.Connection, error) {\n\tconnReader := bufio.NewReader(conn)\n\treq, err := http.ReadRequest(connReader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconnection := strings.ToLower(req.Header.Get(\"Connection\"))\n\tupgrade := strings.ToLower(req.Header.Get(\"Upgrade\"))\n\tif connection != \"upgrade\" || upgrade != \"websocket\" {\n\t\t_ = conn.Close()\n\t\treturn nil, newError(\"unrecognized request\")\n\t}\n\tresp := &http.Response{\n\t\tStatus:     \"101 Switching Protocols\",\n\t\tStatusCode: 101,\n\t\tProto:      \"HTTP/1.1\",\n\t\tProtoMajor: 1,\n\t\tProtoMinor: 1,\n\t\tHeader:     http.Header{},\n\t}\n\tresp.Header.Set(\"Connection\", \"upgrade\")\n\tresp.Header.Set(\"Upgrade\", \"websocket\")\n\terr = resp.Write(conn)\n\tif err != nil {\n\t\t_ = conn.Close()\n\t\treturn nil, err\n\t}\n\tif s.config.MaxEarlyData != 0 {\n\t\tif s.config.EarlyDataHeaderName == \"\" {\n\t\t\treturn nil, newError(\"EarlyDataHeaderName is not set\")\n\t\t}\n\t\tearlyData := req.Header.Get(s.config.EarlyDataHeaderName)\n\t\tif earlyData != \"\" {\n\t\t\tearlyDataBytes, err := base64.URLEncoding.DecodeString(earlyData)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn newConnectionWithPendingRead(conn, conn.RemoteAddr(), bytes.NewReader(earlyDataBytes)), nil\n\t\t}\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc (s *server) keepAccepting() {\n\tfor {\n\t\tconn, err := s.innnerListener.Accept()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tgo s.Handle(conn)\n\t}\n}\n\nfunc listenHTTPUpgrade(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {\n\ttransportConfiguration := streamSettings.ProtocolSettings.(*Config)\n\tserverInstance := &server{config: transportConfiguration, addConn: addConn}\n\n\tlistener, err := transportcommon.ListenWithSecuritySettings(ctx, address, port, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to listen on \", address, \":\", port).Base(err)\n\t}\n\tserverInstance.innnerListener = listener\n\tgo serverInstance.keepAccepting()\n\treturn serverInstance, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, listenHTTPUpgrade))\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/config.pb.go",
    "content": "package hysteria2\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Congestion struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tType          string                 `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tUpMbps        uint64                 `protobuf:\"varint,2,opt,name=up_mbps,json=upMbps,proto3\" json:\"up_mbps,omitempty\"`\n\tDownMbps      uint64                 `protobuf:\"varint,3,opt,name=down_mbps,json=downMbps,proto3\" json:\"down_mbps,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Congestion) Reset() {\n\t*x = Congestion{}\n\tmi := &file_transport_internet_hysteria2_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Congestion) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Congestion) ProtoMessage() {}\n\nfunc (x *Congestion) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_hysteria2_config_proto_msgTypes[0]\n\tif 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 Congestion.ProtoReflect.Descriptor instead.\nfunc (*Congestion) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_hysteria2_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Congestion) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Congestion) GetUpMbps() uint64 {\n\tif x != nil {\n\t\treturn x.UpMbps\n\t}\n\treturn 0\n}\n\nfunc (x *Congestion) GetDownMbps() uint64 {\n\tif x != nil {\n\t\treturn x.DownMbps\n\t}\n\treturn 0\n}\n\ntype Config struct {\n\tstate                 protoimpl.MessageState `protogen:\"open.v1\"`\n\tPassword              string                 `protobuf:\"bytes,3,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tCongestion            *Congestion            `protobuf:\"bytes,4,opt,name=congestion,proto3\" json:\"congestion,omitempty\"`\n\tIgnoreClientBandwidth bool                   `protobuf:\"varint,5,opt,name=ignore_client_bandwidth,json=ignoreClientBandwidth,proto3\" json:\"ignore_client_bandwidth,omitempty\"`\n\tUseUdpExtension       bool                   `protobuf:\"varint,6,opt,name=use_udp_extension,json=useUdpExtension,proto3\" json:\"use_udp_extension,omitempty\"`\n\tunknownFields         protoimpl.UnknownFields\n\tsizeCache             protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_hysteria2_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_hysteria2_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_hysteria2_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetPassword() string {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetCongestion() *Congestion {\n\tif x != nil {\n\t\treturn x.Congestion\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetIgnoreClientBandwidth() bool {\n\tif x != nil {\n\t\treturn x.IgnoreClientBandwidth\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetUseUdpExtension() bool {\n\tif x != nil {\n\t\treturn x.UseUdpExtension\n\t}\n\treturn false\n}\n\nvar File_transport_internet_hysteria2_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_hysteria2_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\")transport/internet/hysteria2/config.proto\\x12'v2ray.core.transport.internet.hysteria2\\x1a common/protoext/extensions.proto\\\"V\\n\" +\n\t\"\\n\" +\n\t\"Congestion\\x12\\x12\\n\" +\n\t\"\\x04type\\x18\\x01 \\x01(\\tR\\x04type\\x12\\x17\\n\" +\n\t\"\\aup_mbps\\x18\\x02 \\x01(\\x04R\\x06upMbps\\x12\\x1b\\n\" +\n\t\"\\tdown_mbps\\x18\\x03 \\x01(\\x04R\\bdownMbps\\\"\\xf9\\x01\\n\" +\n\t\"\\x06Config\\x12\\x1a\\n\" +\n\t\"\\bpassword\\x18\\x03 \\x01(\\tR\\bpassword\\x12S\\n\" +\n\t\"\\n\" +\n\t\"congestion\\x18\\x04 \\x01(\\v23.v2ray.core.transport.internet.hysteria2.CongestionR\\n\" +\n\t\"congestion\\x126\\n\" +\n\t\"\\x17ignore_client_bandwidth\\x18\\x05 \\x01(\\bR\\x15ignoreClientBandwidth\\x12*\\n\" +\n\t\"\\x11use_udp_extension\\x18\\x06 \\x01(\\bR\\x0fuseUdpExtension:\\x1a\\x82\\xb5\\x18\\x16\\n\" +\n\t\"\\ttransport\\x12\\thysteria2B\\x96\\x01\\n\" +\n\t\"+com.v2ray.core.transport.internet.hysteria2P\\x01Z;github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\\xaa\\x02'V2Ray.Core.Transport.Internet.Hysteria2b\\x06proto3\"\n\nvar (\n\tfile_transport_internet_hysteria2_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_hysteria2_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_hysteria2_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_hysteria2_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_hysteria2_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_hysteria2_config_proto_rawDesc), len(file_transport_internet_hysteria2_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_hysteria2_config_proto_rawDescData\n}\n\nvar file_transport_internet_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_hysteria2_config_proto_goTypes = []any{\n\t(*Congestion)(nil), // 0: v2ray.core.transport.internet.hysteria2.Congestion\n\t(*Config)(nil),     // 1: v2ray.core.transport.internet.hysteria2.Config\n}\nvar file_transport_internet_hysteria2_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.hysteria2.Config.congestion:type_name -> v2ray.core.transport.internet.hysteria2.Congestion\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_hysteria2_config_proto_init() }\nfunc file_transport_internet_hysteria2_config_proto_init() {\n\tif File_transport_internet_hysteria2_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_hysteria2_config_proto_rawDesc), len(file_transport_internet_hysteria2_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_hysteria2_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_hysteria2_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_hysteria2_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_hysteria2_config_proto = out.File\n\tfile_transport_internet_hysteria2_config_proto_goTypes = nil\n\tfile_transport_internet_hysteria2_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.hysteria2;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Hysteria2\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\";\noption java_package = \"com.v2ray.core.transport.internet.hysteria2\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Congestion{\n  string type = 1;\n\n  uint64 up_mbps = 2;\n  uint64 down_mbps = 3;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"hysteria2\";\n\n  string password = 3;\n  Congestion congestion = 4;\n  bool ignore_client_bandwidth = 5;\n  bool use_udp_extension = 6;\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/conn.go",
    "content": "package hysteria2\n\nimport (\n\t\"time\"\n\n\thyClient \"github.com/v2fly/hysteria/core/v2/client\"\n\t\"github.com/v2fly/hysteria/core/v2/international/protocol\"\n\t\"github.com/v2fly/hysteria/core/v2/international/utils\"\n\thyServer \"github.com/v2fly/hysteria/core/v2/server\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nconst (\n\tCanNotUseUDPExtension = \"Only hysteria2 proxy protocol can use udpExtension.\"\n\tHy2MustNeedTLS        = \"Hysteria2 based on QUIC that requires TLS.\"\n)\n\ntype HyConn struct {\n\tIsUDPExtension   bool\n\tIsServer         bool\n\tClientUDPSession hyClient.HyUDPConn\n\tServerUDPSession *hyServer.UdpSessionEntry\n\n\tstream *utils.QStream\n\tlocal  net.Addr\n\tremote net.Addr\n}\n\nfunc (c *HyConn) Read(b []byte) (int, error) {\n\tif c.IsUDPExtension {\n\t\tn, data, _, err := c.ReadPacket()\n\t\tcopy(b, data)\n\t\treturn n, err\n\t}\n\treturn c.stream.Read(b)\n}\n\nfunc (c *HyConn) Write(b []byte) (int, error) {\n\tif c.IsUDPExtension {\n\t\tdest, _ := net.ParseDestination(\"udp:v2fly.org:6666\")\n\t\treturn c.WritePacket(b, dest)\n\t}\n\treturn c.stream.Write(b)\n}\n\nfunc (c *HyConn) WritePacket(b []byte, dest net.Destination) (int, error) {\n\tif !c.IsUDPExtension {\n\t\treturn 0, newError(CanNotUseUDPExtension)\n\t}\n\n\tif c.IsServer {\n\t\tmsg := &protocol.UDPMessage{\n\t\t\tSessionID: c.ServerUDPSession.ID,\n\t\t\tPacketID:  0,\n\t\t\tFragID:    0,\n\t\t\tFragCount: 1,\n\t\t\tAddr:      dest.NetAddr(),\n\t\t\tData:      b,\n\t\t}\n\t\tc.ServerUDPSession.SendCh <- msg\n\t\treturn len(b), nil\n\t}\n\treturn len(b), c.ClientUDPSession.Send(b, dest.NetAddr())\n}\n\nfunc (c *HyConn) ReadPacket() (int, []byte, *net.Destination, error) {\n\tif !c.IsUDPExtension {\n\t\treturn 0, nil, nil, newError(CanNotUseUDPExtension)\n\t}\n\n\tif c.IsServer {\n\t\tmsg, ok := <-c.ServerUDPSession.ReceiveCh\n\t\tif !ok {\n\t\t\treturn 0, nil, nil, newError(\"UDP session receive channel closed\")\n\t\t}\n\t\tdest, err := net.ParseDestination(\"udp:\" + msg.Addr)\n\t\treturn len(msg.Data), msg.Data, &dest, err\n\t}\n\tdata, address, err := c.ClientUDPSession.Receive()\n\tif err != nil {\n\t\treturn 0, nil, nil, err\n\t}\n\tdest, err := net.ParseDestination(\"udp:\" + address)\n\tif err != nil {\n\t\treturn 0, nil, nil, err\n\t}\n\treturn len(data), data, &dest, nil\n}\n\nfunc (c *HyConn) Close() error {\n\tif c.IsUDPExtension {\n\t\tif !c.IsServer && c.ClientUDPSession == nil || (c.IsServer && c.ServerUDPSession == nil) {\n\t\t\treturn newError(CanNotUseUDPExtension)\n\t\t}\n\t\tif c.IsServer {\n\t\t\tc.ServerUDPSession.CloseWithErr(nil)\n\t\t\treturn nil\n\t\t}\n\t\treturn c.ClientUDPSession.Close()\n\t}\n\treturn c.stream.Close()\n}\n\nfunc (c *HyConn) LocalAddr() net.Addr {\n\treturn c.local\n}\n\nfunc (c *HyConn) RemoteAddr() net.Addr {\n\treturn c.remote\n}\n\nfunc (c *HyConn) SetDeadline(t time.Time) error {\n\tif c.IsUDPExtension {\n\t\treturn nil\n\t}\n\treturn c.stream.SetDeadline(t)\n}\n\nfunc (c *HyConn) SetReadDeadline(t time.Time) error {\n\tif c.IsUDPExtension {\n\t\treturn nil\n\t}\n\treturn c.stream.SetReadDeadline(t)\n}\n\nfunc (c *HyConn) SetWriteDeadline(t time.Time) error {\n\tif c.IsUDPExtension {\n\t\treturn nil\n\t}\n\treturn c.stream.SetWriteDeadline(t)\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/dialer.go",
    "content": "package hysteria2\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/apernet/quic-go/quicvarint\"\n\thyClient \"github.com/v2fly/hysteria/core/v2/client\"\n\thyProtocol \"github.com/v2fly/hysteria/core/v2/international/protocol\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\ntype dialerConf struct {\n\tnet.Destination\n\t*internet.MemoryStreamConfig\n}\n\nvar (\n\tRunningClient map[dialerConf](hyClient.Client)\n\tClientMutex   sync.Mutex\n\tMBps          uint64 = 1000000 / 8 // MByte\n)\n\nfunc GetClientTLSConfig(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) {\n\tconfig := tls.ConfigFromStreamSettings(streamSettings)\n\tif config == nil {\n\t\treturn nil, newError(Hy2MustNeedTLS)\n\t}\n\ttlsConfig := config.GetTLSConfig(tls.WithDestination(dest))\n\n\treturn &hyClient.TLSConfig{\n\t\tRootCAs:               tlsConfig.RootCAs,\n\t\tServerName:            tlsConfig.ServerName,\n\t\tInsecureSkipVerify:    tlsConfig.InsecureSkipVerify,\n\t\tVerifyPeerCertificate: tlsConfig.VerifyPeerCertificate,\n\t}, nil\n}\n\nfunc ResolveAddress(dest net.Destination) (net.Addr, error) {\n\tvar destAddr *net.UDPAddr\n\tif dest.Address.Family().IsIP() {\n\t\tdestAddr = &net.UDPAddr{\n\t\t\tIP:   dest.Address.IP(),\n\t\t\tPort: int(dest.Port),\n\t\t}\n\t} else {\n\t\taddr, err := net.ResolveUDPAddr(\"udp\", dest.NetAddr())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdestAddr = addr\n\t}\n\treturn destAddr, nil\n}\n\ntype connFactory struct {\n\thyClient.ConnFactory\n\n\tNewFunc func(addr net.Addr) (net.PacketConn, error)\n}\n\nfunc (f *connFactory) New(addr net.Addr) (net.PacketConn, error) {\n\treturn f.NewFunc(addr)\n}\n\nfunc NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) {\n\ttlsConfig, err := GetClientTLSConfig(dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tserverAddr, err := ResolveAddress(dest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfig := streamSettings.ProtocolSettings.(*Config)\n\tclient, _, err := hyClient.NewClient(&hyClient.Config{\n\t\tAuth:       config.GetPassword(),\n\t\tTLSConfig:  *tlsConfig,\n\t\tServerAddr: serverAddr,\n\t\tConnFactory: &connFactory{\n\t\t\tNewFunc: func(addr net.Addr) (net.PacketConn, error) {\n\t\t\t\trawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{\n\t\t\t\t\tIP:   []byte{0, 0, 0, 0},\n\t\t\t\t\tPort: 0,\n\t\t\t\t}, streamSettings.SocketSettings)\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 rawConn.(*net.UDPConn), nil\n\t\t\t},\n\t\t},\n\t\tBandwidthConfig: hyClient.BandwidthConfig{MaxTx: config.Congestion.GetUpMbps() * MBps, MaxRx: config.GetCongestion().GetDownMbps() * MBps},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn client, nil\n}\n\nfunc CloseHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) error {\n\tClientMutex.Lock()\n\tdefer ClientMutex.Unlock()\n\n\tclient, found := RunningClient[dialerConf{dest, streamSettings}]\n\tif found {\n\t\tdelete(RunningClient, dialerConf{dest, streamSettings})\n\t\treturn client.Close()\n\t}\n\treturn nil\n}\n\nfunc GetHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) {\n\tvar err error\n\tvar client hyClient.Client\n\n\tClientMutex.Lock()\n\tclient, found := RunningClient[dialerConf{dest, streamSettings}]\n\tClientMutex.Unlock()\n\tif !found || !CheckHyClientHealthy(client) {\n\t\tif found {\n\t\t\t// retry\n\t\t\tCloseHyClient(dest, streamSettings)\n\t\t}\n\t\tclient, err = NewHyClient(dest, streamSettings)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tClientMutex.Lock()\n\t\tRunningClient[dialerConf{dest, streamSettings}] = client\n\t\tClientMutex.Unlock()\n\t}\n\treturn client, nil\n}\n\nfunc CheckHyClientHealthy(client hyClient.Client) bool {\n\tquicConn := client.GetQuicConn()\n\tif quicConn == nil {\n\t\treturn false\n\t}\n\tselect {\n\tcase <-quicConn.Context().Done():\n\t\treturn false\n\tdefault:\n\t}\n\treturn true\n}\n\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tconfig := streamSettings.ProtocolSettings.(*Config)\n\n\tclient, err := GetHyClient(dest, streamSettings)\n\tif err != nil {\n\t\tCloseHyClient(dest, streamSettings)\n\t\treturn nil, err\n\t}\n\n\tquicConn := client.GetQuicConn()\n\tconn := &HyConn{\n\t\tlocal:  quicConn.LocalAddr(),\n\t\tremote: quicConn.RemoteAddr(),\n\t}\n\n\toutbound := session.OutboundFromContext(ctx)\n\tnetwork := net.Network_TCP\n\tif outbound != nil {\n\t\tnetwork = outbound.Target.Network\n\t}\n\n\tif network == net.Network_UDP && config.GetUseUdpExtension() { // only hysteria2 can use udpExtension\n\t\tconn.IsUDPExtension = true\n\t\tconn.IsServer = false\n\t\tconn.ClientUDPSession, err = client.UDP()\n\t\tif err != nil {\n\t\t\tCloseHyClient(dest, streamSettings)\n\t\t\treturn nil, err\n\t\t}\n\t\treturn conn, nil\n\t}\n\n\tconn.stream, err = client.OpenStream()\n\tif err != nil {\n\t\tCloseHyClient(dest, streamSettings)\n\t\treturn nil, err\n\t}\n\n\t// write TCP frame type\n\tframeSize := quicvarint.Len(hyProtocol.FrameTypeTCPRequest)\n\tbuf := make([]byte, frameSize)\n\thyProtocol.VarintPut(buf, hyProtocol.FrameTypeTCPRequest)\n\t_, err = conn.stream.Write(buf)\n\tif err != nil {\n\t\tCloseHyClient(dest, streamSettings)\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\nfunc init() {\n\tRunningClient = make(map[dialerConf]hyClient.Client)\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/errors.generated.go",
    "content": "package hysteria2\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/hub.go",
    "content": "package hysteria2\n\nimport (\n\t\"context\"\n\n\t\"github.com/apernet/quic-go\"\n\t\"github.com/apernet/quic-go/http3\"\n\t\"github.com/v2fly/hysteria/core/v2/international/utils\"\n\thyServer \"github.com/v2fly/hysteria/core/v2/server\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n// Listener is an internet.Listener that listens for TCP connections.\ntype Listener struct {\n\thyServer hyServer.Server\n\trawConn  net.PacketConn\n\taddConn  internet.ConnHandler\n}\n\n// Addr implements internet.Listener.Addr.\nfunc (l *Listener) Addr() net.Addr {\n\treturn l.rawConn.LocalAddr()\n}\n\n// Close implements internet.Listener.Close.\nfunc (l *Listener) Close() error {\n\treturn l.hyServer.Close()\n}\n\nfunc (l *Listener) StreamHijacker(ft http3.FrameType, conn *quic.Conn, stream *utils.QStream, err error) (bool, error) {\n\t// err always == nil\n\n\ttcpConn := &HyConn{\n\t\tstream: stream,\n\t\tlocal:  conn.LocalAddr(),\n\t\tremote: conn.RemoteAddr(),\n\t}\n\tl.addConn(tcpConn)\n\treturn true, nil\n}\n\nfunc (l *Listener) UDPHijacker(entry *hyServer.UdpSessionEntry, originalAddr string) {\n\taddr, err := net.ResolveUDPAddr(\"udp\", originalAddr)\n\tif err != nil {\n\t\treturn\n\t}\n\tudpConn := &HyConn{\n\t\tIsUDPExtension:   true,\n\t\tIsServer:         true,\n\t\tServerUDPSession: entry,\n\t\tremote:           addr,\n\t\tlocal:            l.rawConn.LocalAddr(),\n\t}\n\tl.addConn(udpConn)\n}\n\n// Listen creates a new Listener based on configurations.\nfunc Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {\n\ttlsConfig, err := GetServerTLSConfig(streamSettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif address.Family().IsDomain() {\n\t\treturn nil, nil\n\t}\n\n\tconfig := streamSettings.ProtocolSettings.(*Config)\n\trawConn, err := internet.ListenSystemPacket(context.Background(),\n\t\t&net.UDPAddr{\n\t\t\tIP:   address.IP(),\n\t\t\tPort: int(port),\n\t\t}, streamSettings.SocketSettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlistener := &Listener{\n\t\trawConn: rawConn,\n\t\taddConn: handler,\n\t}\n\n\thyServer, err := hyServer.NewServer(&hyServer.Config{\n\t\tConn:                  rawConn,\n\t\tTLSConfig:             *tlsConfig,\n\t\tDisableUDP:            !config.GetUseUdpExtension(),\n\t\tAuthenticator:         &Authenticator{Password: config.GetPassword()},\n\t\tStreamHijacker:        listener.StreamHijacker, // acceptStreams\n\t\tBandwidthConfig:       hyServer.BandwidthConfig{MaxTx: config.Congestion.GetUpMbps() * MBps, MaxRx: config.GetCongestion().GetDownMbps() * MBps},\n\t\tUdpSessionHijacker:    listener.UDPHijacker, // acceptUDPSession\n\t\tIgnoreClientBandwidth: config.GetIgnoreClientBandwidth(),\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlistener.hyServer = hyServer\n\tgo hyServer.Serve()\n\treturn listener, nil\n}\n\nfunc GetServerTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyServer.TLSConfig, error) {\n\tconfig := tls.ConfigFromStreamSettings(streamSettings)\n\tif config == nil {\n\t\treturn nil, newError(Hy2MustNeedTLS)\n\t}\n\ttlsConfig := config.GetTLSConfig()\n\n\treturn &hyServer.TLSConfig{Certificates: tlsConfig.Certificates, GetCertificate: tlsConfig.GetCertificate}, nil\n}\n\ntype Authenticator struct {\n\tPassword string\n}\n\nfunc (a *Authenticator) Authenticate(addr net.Addr, auth string, tx uint64) (ok bool, id string) {\n\tif auth == a.Password || a.Password == \"\" {\n\t\treturn true, \"user\"\n\t}\n\treturn false, \"\"\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, Listen))\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/hy2_transport_test.go",
    "content": "package hysteria2_test\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc TestTCP(t *testing.T) {\n\tport := udp.PickPort()\n\n\tlistener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"hysteria2\",\n\t\tProtocolSettings: &hysteria2.Config{Password: \"123\"},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tCertificate: []*tls.Certificate{\n\t\t\t\ttls.ParseCertificate(\n\t\t\t\t\tcert.MustGenerate(nil,\n\t\t\t\t\t\tcert.DNSNames(\"www.v2fly.org\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tb := buf.New()\n\t\t\tdefer b.Release()\n\n\t\t\tfor {\n\t\t\t\tb.Clear()\n\t\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\t\tfmt.Println(err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t\t\t}\n\t\t}()\n\t})\n\tcommon.Must(err)\n\n\tdefer listener.Close()\n\n\ttime.Sleep(time.Second)\n\n\tdctx := context.Background()\n\tconn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"hysteria2\",\n\t\tProtocolSettings: &hysteria2.Config{Password: \"123\"},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\tAllowInsecure: true,\n\t\t},\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst N = 1000\n\tb1 := make([]byte, N)\n\tcommon.Must2(rand.Read(b1))\n\tb2 := buf.New()\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestUDP(t *testing.T) {\n\tport := udp.PickPort()\n\n\tlistener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"hysteria2\",\n\t\tProtocolSettings: &hysteria2.Config{Password: \"123\", UseUdpExtension: true},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tCertificate: []*tls.Certificate{\n\t\t\t\ttls.ParseCertificate(\n\t\t\t\t\tcert.MustGenerate(nil,\n\t\t\t\t\t\tcert.DNSNames(\"www.v2fly.org\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tfmt.Println(\"incoming\")\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tb := buf.New()\n\t\t\tdefer b.Release()\n\n\t\t\tfor {\n\t\t\t\tb.Clear()\n\t\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\t\tfmt.Println(err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t\t\t}\n\t\t}()\n\t})\n\tcommon.Must(err)\n\n\tdefer listener.Close()\n\n\ttime.Sleep(time.Second)\n\n\taddress, err := net.ParseDestination(\"udp:127.0.0.1:1180\")\n\tcommon.Must(err)\n\tdctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: address})\n\n\tconn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"hysteria2\",\n\t\tProtocolSettings: &hysteria2.Config{Password: \"123\", UseUdpExtension: true},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\tAllowInsecure: true,\n\t\t},\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst N = 1000\n\tb1 := make([]byte, N)\n\tcommon.Must2(rand.Read(b1))\n\tcommon.Must2(conn.Write(b1))\n\n\tb2 := buf.New()\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/hysteria2/hysteria2.go",
    "content": "package hysteria2\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst (\n\tprotocolName = \"hysteria2\"\n)\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/internet.go",
    "content": "package internet\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/kcp/config.go",
    "content": "package kcp\n\nimport (\n\t\"crypto/cipher\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst protocolName = \"mkcp\"\n\n// GetMTUValue returns the value of MTU settings.\nfunc (c *Config) GetMTUValue() uint32 {\n\tif c == nil || c.Mtu == nil {\n\t\treturn 1350\n\t}\n\treturn c.Mtu.Value\n}\n\n// GetTTIValue returns the value of TTI settings.\nfunc (c *Config) GetTTIValue() uint32 {\n\tif c == nil || c.Tti == nil {\n\t\treturn 50\n\t}\n\treturn c.Tti.Value\n}\n\n// GetUplinkCapacityValue returns the value of UplinkCapacity settings.\nfunc (c *Config) GetUplinkCapacityValue() uint32 {\n\tif c == nil || c.UplinkCapacity == nil {\n\t\treturn 5\n\t}\n\treturn c.UplinkCapacity.Value\n}\n\n// GetDownlinkCapacityValue returns the value of DownlinkCapacity settings.\nfunc (c *Config) GetDownlinkCapacityValue() uint32 {\n\tif c == nil || c.DownlinkCapacity == nil {\n\t\treturn 20\n\t}\n\treturn c.DownlinkCapacity.Value\n}\n\n// GetWriteBufferSize returns the size of WriterBuffer in bytes.\nfunc (c *Config) GetWriteBufferSize() uint32 {\n\tif c == nil || c.WriteBuffer == nil {\n\t\treturn 2 * 1024 * 1024\n\t}\n\treturn c.WriteBuffer.Size\n}\n\n// GetReadBufferSize returns the size of ReadBuffer in bytes.\nfunc (c *Config) GetReadBufferSize() uint32 {\n\tif c == nil || c.ReadBuffer == nil {\n\t\treturn 2 * 1024 * 1024\n\t}\n\treturn c.ReadBuffer.Size\n}\n\n// GetSecurity returns the security settings.\nfunc (c *Config) GetSecurity() (cipher.AEAD, error) {\n\tif c.Seed != nil {\n\t\treturn NewAEADAESGCMBasedOnSeed(c.Seed.Seed), nil\n\t}\n\treturn NewSimpleAuthenticator(), nil\n}\n\nfunc (c *Config) GetPackerHeader() (internet.PacketHeader, error) {\n\tif c.HeaderConfig != nil {\n\t\trawConfig, err := serial.GetInstanceOf(c.HeaderConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn internet.CreatePacketHeader(rawConfig)\n\t}\n\treturn nil, nil\n}\n\nfunc (c *Config) GetSendingInFlightSize() uint32 {\n\tsize := c.GetUplinkCapacityValue() * 1024 * 1024 / c.GetMTUValue() / (1000 / c.GetTTIValue())\n\tif size < 8 {\n\t\tsize = 8\n\t}\n\treturn size\n}\n\nfunc (c *Config) GetSendingBufferSize() uint32 {\n\treturn c.GetWriteBufferSize() / c.GetMTUValue()\n}\n\nfunc (c *Config) GetReceivingInFlightSize() uint32 {\n\tsize := c.GetDownlinkCapacityValue() * 1024 * 1024 / c.GetMTUValue() / (1000 / c.GetTTIValue())\n\tif size < 8 {\n\t\tsize = 8\n\t}\n\treturn size\n}\n\nfunc (c *Config) GetReceivingBufferSize() uint32 {\n\treturn c.GetReadBufferSize() / c.GetMTUValue()\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/kcp/config.pb.go",
    "content": "package kcp\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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// Maximum Transmission Unit, in bytes.\ntype MTU struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *MTU) Reset() {\n\t*x = MTU{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *MTU) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*MTU) ProtoMessage() {}\n\nfunc (x *MTU) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[0]\n\tif 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 MTU.ProtoReflect.Descriptor instead.\nfunc (*MTU) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *MTU) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\n// Transmission Time Interview, in milli-sec.\ntype TTI struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *TTI) Reset() {\n\t*x = TTI{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TTI) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TTI) ProtoMessage() {}\n\nfunc (x *TTI) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[1]\n\tif 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 TTI.ProtoReflect.Descriptor instead.\nfunc (*TTI) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *TTI) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\n// Uplink capacity, in MB.\ntype UplinkCapacity struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *UplinkCapacity) Reset() {\n\t*x = UplinkCapacity{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *UplinkCapacity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*UplinkCapacity) ProtoMessage() {}\n\nfunc (x *UplinkCapacity) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[2]\n\tif 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 UplinkCapacity.ProtoReflect.Descriptor instead.\nfunc (*UplinkCapacity) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *UplinkCapacity) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\n// Downlink capacity, in MB.\ntype DownlinkCapacity struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tValue         uint32                 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *DownlinkCapacity) Reset() {\n\t*x = DownlinkCapacity{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *DownlinkCapacity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DownlinkCapacity) ProtoMessage() {}\n\nfunc (x *DownlinkCapacity) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[3]\n\tif 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 DownlinkCapacity.ProtoReflect.Descriptor instead.\nfunc (*DownlinkCapacity) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *DownlinkCapacity) GetValue() uint32 {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn 0\n}\n\ntype WriteBuffer struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Buffer size in bytes.\n\tSize          uint32 `protobuf:\"varint,1,opt,name=size,proto3\" json:\"size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *WriteBuffer) Reset() {\n\t*x = WriteBuffer{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *WriteBuffer) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*WriteBuffer) ProtoMessage() {}\n\nfunc (x *WriteBuffer) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[4]\n\tif 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 WriteBuffer.ProtoReflect.Descriptor instead.\nfunc (*WriteBuffer) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *WriteBuffer) GetSize() uint32 {\n\tif x != nil {\n\t\treturn x.Size\n\t}\n\treturn 0\n}\n\ntype ReadBuffer struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Buffer size in bytes.\n\tSize          uint32 `protobuf:\"varint,1,opt,name=size,proto3\" json:\"size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ReadBuffer) Reset() {\n\t*x = ReadBuffer{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[5]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ReadBuffer) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ReadBuffer) ProtoMessage() {}\n\nfunc (x *ReadBuffer) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[5]\n\tif 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 ReadBuffer.ProtoReflect.Descriptor instead.\nfunc (*ReadBuffer) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *ReadBuffer) GetSize() uint32 {\n\tif x != nil {\n\t\treturn x.Size\n\t}\n\treturn 0\n}\n\ntype ConnectionReuse struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tEnable        bool                   `protobuf:\"varint,1,opt,name=enable,proto3\" json:\"enable,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ConnectionReuse) Reset() {\n\t*x = ConnectionReuse{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[6]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ConnectionReuse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ConnectionReuse) ProtoMessage() {}\n\nfunc (x *ConnectionReuse) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[6]\n\tif 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 ConnectionReuse.ProtoReflect.Descriptor instead.\nfunc (*ConnectionReuse) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *ConnectionReuse) GetEnable() bool {\n\tif x != nil {\n\t\treturn x.Enable\n\t}\n\treturn false\n}\n\n// Maximum Transmission Unit, in bytes.\ntype EncryptionSeed struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tSeed          string                 `protobuf:\"bytes,1,opt,name=seed,proto3\" json:\"seed,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *EncryptionSeed) Reset() {\n\t*x = EncryptionSeed{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[7]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *EncryptionSeed) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*EncryptionSeed) ProtoMessage() {}\n\nfunc (x *EncryptionSeed) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[7]\n\tif 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 EncryptionSeed.ProtoReflect.Descriptor instead.\nfunc (*EncryptionSeed) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *EncryptionSeed) GetSeed() string {\n\tif x != nil {\n\t\treturn x.Seed\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tMtu              *MTU                   `protobuf:\"bytes,1,opt,name=mtu,proto3\" json:\"mtu,omitempty\"`\n\tTti              *TTI                   `protobuf:\"bytes,2,opt,name=tti,proto3\" json:\"tti,omitempty\"`\n\tUplinkCapacity   *UplinkCapacity        `protobuf:\"bytes,3,opt,name=uplink_capacity,json=uplinkCapacity,proto3\" json:\"uplink_capacity,omitempty\"`\n\tDownlinkCapacity *DownlinkCapacity      `protobuf:\"bytes,4,opt,name=downlink_capacity,json=downlinkCapacity,proto3\" json:\"downlink_capacity,omitempty\"`\n\tCongestion       bool                   `protobuf:\"varint,5,opt,name=congestion,proto3\" json:\"congestion,omitempty\"`\n\tWriteBuffer      *WriteBuffer           `protobuf:\"bytes,6,opt,name=write_buffer,json=writeBuffer,proto3\" json:\"write_buffer,omitempty\"`\n\tReadBuffer       *ReadBuffer            `protobuf:\"bytes,7,opt,name=read_buffer,json=readBuffer,proto3\" json:\"read_buffer,omitempty\"`\n\tHeaderConfig     *anypb.Any             `protobuf:\"bytes,8,opt,name=header_config,json=headerConfig,proto3\" json:\"header_config,omitempty\"`\n\tSeed             *EncryptionSeed        `protobuf:\"bytes,10,opt,name=seed,proto3\" json:\"seed,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[8]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_kcp_config_proto_msgTypes[8]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_kcp_config_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *Config) GetMtu() *MTU {\n\tif x != nil {\n\t\treturn x.Mtu\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetTti() *TTI {\n\tif x != nil {\n\t\treturn x.Tti\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetUplinkCapacity() *UplinkCapacity {\n\tif x != nil {\n\t\treturn x.UplinkCapacity\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetDownlinkCapacity() *DownlinkCapacity {\n\tif x != nil {\n\t\treturn x.DownlinkCapacity\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetCongestion() bool {\n\tif x != nil {\n\t\treturn x.Congestion\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetWriteBuffer() *WriteBuffer {\n\tif x != nil {\n\t\treturn x.WriteBuffer\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetReadBuffer() *ReadBuffer {\n\tif x != nil {\n\t\treturn x.ReadBuffer\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetHeaderConfig() *anypb.Any {\n\tif x != nil {\n\t\treturn x.HeaderConfig\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetSeed() *EncryptionSeed {\n\tif x != nil {\n\t\treturn x.Seed\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_kcp_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_kcp_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"#transport/internet/kcp/config.proto\\x12!v2ray.core.transport.internet.kcp\\x1a\\x19google/protobuf/any.proto\\x1a common/protoext/extensions.proto\\\"\\x1b\\n\" +\n\t\"\\x03MTU\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\\"\\x1b\\n\" +\n\t\"\\x03TTI\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\\"&\\n\" +\n\t\"\\x0eUplinkCapacity\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\\"(\\n\" +\n\t\"\\x10DownlinkCapacity\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x01 \\x01(\\rR\\x05value\\\"!\\n\" +\n\t\"\\vWriteBuffer\\x12\\x12\\n\" +\n\t\"\\x04size\\x18\\x01 \\x01(\\rR\\x04size\\\" \\n\" +\n\t\"\\n\" +\n\t\"ReadBuffer\\x12\\x12\\n\" +\n\t\"\\x04size\\x18\\x01 \\x01(\\rR\\x04size\\\")\\n\" +\n\t\"\\x0fConnectionReuse\\x12\\x16\\n\" +\n\t\"\\x06enable\\x18\\x01 \\x01(\\bR\\x06enable\\\"$\\n\" +\n\t\"\\x0eEncryptionSeed\\x12\\x12\\n\" +\n\t\"\\x04seed\\x18\\x01 \\x01(\\tR\\x04seed\\\"\\xa7\\x05\\n\" +\n\t\"\\x06Config\\x128\\n\" +\n\t\"\\x03mtu\\x18\\x01 \\x01(\\v2&.v2ray.core.transport.internet.kcp.MTUR\\x03mtu\\x128\\n\" +\n\t\"\\x03tti\\x18\\x02 \\x01(\\v2&.v2ray.core.transport.internet.kcp.TTIR\\x03tti\\x12Z\\n\" +\n\t\"\\x0fuplink_capacity\\x18\\x03 \\x01(\\v21.v2ray.core.transport.internet.kcp.UplinkCapacityR\\x0euplinkCapacity\\x12`\\n\" +\n\t\"\\x11downlink_capacity\\x18\\x04 \\x01(\\v23.v2ray.core.transport.internet.kcp.DownlinkCapacityR\\x10downlinkCapacity\\x12\\x1e\\n\" +\n\t\"\\n\" +\n\t\"congestion\\x18\\x05 \\x01(\\bR\\n\" +\n\t\"congestion\\x12Q\\n\" +\n\t\"\\fwrite_buffer\\x18\\x06 \\x01(\\v2..v2ray.core.transport.internet.kcp.WriteBufferR\\vwriteBuffer\\x12N\\n\" +\n\t\"\\vread_buffer\\x18\\a \\x01(\\v2-.v2ray.core.transport.internet.kcp.ReadBufferR\\n\" +\n\t\"readBuffer\\x129\\n\" +\n\t\"\\rheader_config\\x18\\b \\x01(\\v2\\x14.google.protobuf.AnyR\\fheaderConfig\\x12E\\n\" +\n\t\"\\x04seed\\x18\\n\" +\n\t\" \\x01(\\v21.v2ray.core.transport.internet.kcp.EncryptionSeedR\\x04seed: \\x82\\xb5\\x18\\x1c\\n\" +\n\t\"\\ttransport\\x12\\x03kcp\\x8a\\xff)\\x04mkcp\\x90\\xff)\\x01J\\x04\\b\\t\\x10\\n\" +\n\t\"B\\x84\\x01\\n\" +\n\t\"%com.v2ray.core.transport.internet.kcpP\\x01Z5github.com/v2fly/v2ray-core/v5/transport/internet/kcp\\xaa\\x02!V2Ray.Core.Transport.Internet.Kcpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_kcp_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_kcp_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_kcp_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_kcp_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_kcp_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_kcp_config_proto_rawDesc), len(file_transport_internet_kcp_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_kcp_config_proto_rawDescData\n}\n\nvar file_transport_internet_kcp_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9)\nvar file_transport_internet_kcp_config_proto_goTypes = []any{\n\t(*MTU)(nil),              // 0: v2ray.core.transport.internet.kcp.MTU\n\t(*TTI)(nil),              // 1: v2ray.core.transport.internet.kcp.TTI\n\t(*UplinkCapacity)(nil),   // 2: v2ray.core.transport.internet.kcp.UplinkCapacity\n\t(*DownlinkCapacity)(nil), // 3: v2ray.core.transport.internet.kcp.DownlinkCapacity\n\t(*WriteBuffer)(nil),      // 4: v2ray.core.transport.internet.kcp.WriteBuffer\n\t(*ReadBuffer)(nil),       // 5: v2ray.core.transport.internet.kcp.ReadBuffer\n\t(*ConnectionReuse)(nil),  // 6: v2ray.core.transport.internet.kcp.ConnectionReuse\n\t(*EncryptionSeed)(nil),   // 7: v2ray.core.transport.internet.kcp.EncryptionSeed\n\t(*Config)(nil),           // 8: v2ray.core.transport.internet.kcp.Config\n\t(*anypb.Any)(nil),        // 9: google.protobuf.Any\n}\nvar file_transport_internet_kcp_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.kcp.Config.mtu:type_name -> v2ray.core.transport.internet.kcp.MTU\n\t1, // 1: v2ray.core.transport.internet.kcp.Config.tti:type_name -> v2ray.core.transport.internet.kcp.TTI\n\t2, // 2: v2ray.core.transport.internet.kcp.Config.uplink_capacity:type_name -> v2ray.core.transport.internet.kcp.UplinkCapacity\n\t3, // 3: v2ray.core.transport.internet.kcp.Config.downlink_capacity:type_name -> v2ray.core.transport.internet.kcp.DownlinkCapacity\n\t4, // 4: v2ray.core.transport.internet.kcp.Config.write_buffer:type_name -> v2ray.core.transport.internet.kcp.WriteBuffer\n\t5, // 5: v2ray.core.transport.internet.kcp.Config.read_buffer:type_name -> v2ray.core.transport.internet.kcp.ReadBuffer\n\t9, // 6: v2ray.core.transport.internet.kcp.Config.header_config:type_name -> google.protobuf.Any\n\t7, // 7: v2ray.core.transport.internet.kcp.Config.seed:type_name -> v2ray.core.transport.internet.kcp.EncryptionSeed\n\t8, // [8:8] is the sub-list for method output_type\n\t8, // [8:8] is the sub-list for method input_type\n\t8, // [8:8] is the sub-list for extension type_name\n\t8, // [8:8] is the sub-list for extension extendee\n\t0, // [0:8] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_kcp_config_proto_init() }\nfunc file_transport_internet_kcp_config_proto_init() {\n\tif File_transport_internet_kcp_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_kcp_config_proto_rawDesc), len(file_transport_internet_kcp_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   9,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_kcp_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_kcp_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_kcp_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_kcp_config_proto = out.File\n\tfile_transport_internet_kcp_config_proto_goTypes = nil\n\tfile_transport_internet_kcp_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/kcp/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.kcp;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Kcp\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\";\noption java_package = \"com.v2ray.core.transport.internet.kcp\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\n\nimport \"common/protoext/extensions.proto\";\n\n// Maximum Transmission Unit, in bytes.\nmessage MTU {\n  uint32 value = 1;\n}\n\n// Transmission Time Interview, in milli-sec.\nmessage TTI {\n  uint32 value = 1;\n}\n\n// Uplink capacity, in MB.\nmessage UplinkCapacity {\n  uint32 value = 1;\n}\n\n// Downlink capacity, in MB.\nmessage DownlinkCapacity {\n  uint32 value = 1;\n}\n\nmessage WriteBuffer {\n  // Buffer size in bytes.\n  uint32 size = 1;\n}\n\nmessage ReadBuffer {\n  // Buffer size in bytes.\n  uint32 size = 1;\n}\n\nmessage ConnectionReuse {\n  bool enable = 1;\n}\n\n// Maximum Transmission Unit, in bytes.\nmessage EncryptionSeed {\n  string seed = 1;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"kcp\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  option (v2ray.core.common.protoext.message_opt).transport_original_name = \"mkcp\";\n\n  MTU mtu = 1;\n  TTI tti = 2;\n  UplinkCapacity uplink_capacity = 3;\n  DownlinkCapacity downlink_capacity = 4;\n  bool congestion = 5;\n  WriteBuffer write_buffer = 6;\n  ReadBuffer read_buffer = 7;\n  google.protobuf.Any header_config = 8;\n  reserved 9;\n  EncryptionSeed seed = 10;\n}\n"
  },
  {
    "path": "transport/internet/kcp/connection.go",
    "content": "package kcp\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net\"\n\t\"runtime\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/semaphore\"\n)\n\nvar (\n\tErrIOTimeout        = newError(\"Read/Write timeout\")\n\tErrClosedListener   = newError(\"Listener closed.\")\n\tErrClosedConnection = newError(\"Connection closed.\")\n)\n\n// State of the connection\ntype State int32\n\n// Is returns true if current State is one of the candidates.\nfunc (s State) Is(states ...State) bool {\n\tfor _, state := range states {\n\t\tif s == state {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nconst (\n\tStateActive          State = 0 // Connection is active\n\tStateReadyToClose    State = 1 // Connection is closed locally\n\tStatePeerClosed      State = 2 // Connection is closed on remote\n\tStateTerminating     State = 3 // Connection is ready to be destroyed locally\n\tStatePeerTerminating State = 4 // Connection is ready to be destroyed on remote\n\tStateTerminated      State = 5 // Connection is destroyed.\n)\n\nfunc nowMillisec() int64 {\n\tnow := time.Now()\n\treturn now.Unix()*1000 + int64(now.Nanosecond()/1000000)\n}\n\ntype RoundTripInfo struct {\n\tsync.RWMutex\n\tvariation        uint32\n\tsrtt             uint32\n\trto              uint32\n\tminRtt           uint32\n\tupdatedTimestamp uint32\n}\n\nfunc (info *RoundTripInfo) UpdatePeerRTO(rto uint32, current uint32) {\n\tinfo.Lock()\n\tdefer info.Unlock()\n\n\tif current-info.updatedTimestamp < 3000 {\n\t\treturn\n\t}\n\n\tinfo.updatedTimestamp = current\n\tinfo.rto = rto\n}\n\nfunc (info *RoundTripInfo) Update(rtt uint32, current uint32) {\n\tif rtt > 0x7FFFFFFF {\n\t\treturn\n\t}\n\tinfo.Lock()\n\tdefer info.Unlock()\n\n\t// https://tools.ietf.org/html/rfc6298\n\tif info.srtt == 0 {\n\t\tinfo.srtt = rtt\n\t\tinfo.variation = rtt / 2\n\t} else {\n\t\tdelta := rtt - info.srtt\n\t\tif info.srtt > rtt {\n\t\t\tdelta = info.srtt - rtt\n\t\t}\n\t\tinfo.variation = (3*info.variation + delta) / 4\n\t\tinfo.srtt = (7*info.srtt + rtt) / 8\n\t\tif info.srtt < info.minRtt {\n\t\t\tinfo.srtt = info.minRtt\n\t\t}\n\t}\n\tvar rto uint32\n\tif info.minRtt < 4*info.variation {\n\t\trto = info.srtt + 4*info.variation\n\t} else {\n\t\trto = info.srtt + info.variation\n\t}\n\n\tif rto > 10000 {\n\t\trto = 10000\n\t}\n\tinfo.rto = rto * 5 / 4\n\tinfo.updatedTimestamp = current\n}\n\nfunc (info *RoundTripInfo) Timeout() uint32 {\n\tinfo.RLock()\n\tdefer info.RUnlock()\n\n\treturn info.rto\n}\n\nfunc (info *RoundTripInfo) SmoothedTime() uint32 {\n\tinfo.RLock()\n\tdefer info.RUnlock()\n\n\treturn info.srtt\n}\n\ntype Updater struct {\n\tinterval        int64\n\tshouldContinue  func() bool\n\tshouldTerminate func() bool\n\tupdateFunc      func()\n\tnotifier        *semaphore.Instance\n}\n\nfunc NewUpdater(interval uint32, shouldContinue func() bool, shouldTerminate func() bool, updateFunc func()) *Updater {\n\tu := &Updater{\n\t\tinterval:        int64(time.Duration(interval) * time.Millisecond),\n\t\tshouldContinue:  shouldContinue,\n\t\tshouldTerminate: shouldTerminate,\n\t\tupdateFunc:      updateFunc,\n\t\tnotifier:        semaphore.New(1),\n\t}\n\treturn u\n}\n\nfunc (u *Updater) WakeUp() {\n\tselect {\n\tcase <-u.notifier.Wait():\n\t\tgo u.run()\n\tdefault:\n\t}\n}\n\nfunc (u *Updater) run() {\n\tdefer u.notifier.Signal()\n\n\tif u.shouldTerminate() {\n\t\treturn\n\t}\n\tticker := time.NewTicker(u.Interval())\n\tfor u.shouldContinue() {\n\t\tu.updateFunc()\n\t\t<-ticker.C\n\t}\n\tticker.Stop()\n}\n\nfunc (u *Updater) Interval() time.Duration {\n\treturn time.Duration(atomic.LoadInt64(&u.interval))\n}\n\nfunc (u *Updater) SetInterval(d time.Duration) {\n\tatomic.StoreInt64(&u.interval, int64(d))\n}\n\ntype ConnMetadata struct {\n\tLocalAddr    net.Addr\n\tRemoteAddr   net.Addr\n\tConversation uint16\n}\n\n// Connection is a KCP connection over UDP.\ntype Connection struct {\n\tmeta       ConnMetadata\n\tcloser     io.Closer\n\trd         time.Time\n\twd         time.Time // write deadline\n\tsince      int64\n\tdataInput  *signal.Notifier\n\tdataOutput *signal.Notifier\n\tConfig     *Config\n\n\tstate            State\n\tstateBeginTime   uint32\n\tlastIncomingTime uint32\n\tlastPingTime     uint32\n\n\tmss       uint32\n\troundTrip *RoundTripInfo\n\n\treceivingWorker *ReceivingWorker\n\tsendingWorker   *SendingWorker\n\n\toutput SegmentWriter\n\n\tdataUpdater *Updater\n\tpingUpdater *Updater\n}\n\n// NewConnection create a new KCP connection between local and remote.\nfunc NewConnection(meta ConnMetadata, writer PacketWriter, closer io.Closer, config *Config) *Connection {\n\tnewError(\"#\", meta.Conversation, \" creating connection to \", meta.RemoteAddr).WriteToLog()\n\n\tconn := &Connection{\n\t\tmeta:       meta,\n\t\tcloser:     closer,\n\t\tsince:      nowMillisec(),\n\t\tdataInput:  signal.NewNotifier(),\n\t\tdataOutput: signal.NewNotifier(),\n\t\tConfig:     config,\n\t\toutput:     NewRetryableWriter(NewSegmentWriter(writer)),\n\t\tmss:        config.GetMTUValue() - uint32(writer.Overhead()) - DataSegmentOverhead,\n\t\troundTrip: &RoundTripInfo{\n\t\t\trto:    100,\n\t\t\tminRtt: config.GetTTIValue(),\n\t\t},\n\t}\n\n\tconn.receivingWorker = NewReceivingWorker(conn)\n\tconn.sendingWorker = NewSendingWorker(conn)\n\n\tisTerminating := func() bool {\n\t\treturn conn.State().Is(StateTerminating, StateTerminated)\n\t}\n\tisTerminated := func() bool {\n\t\treturn conn.State() == StateTerminated\n\t}\n\tconn.dataUpdater = NewUpdater(\n\t\tconfig.GetTTIValue(),\n\t\tfunc() bool {\n\t\t\treturn !isTerminating() && (conn.sendingWorker.UpdateNecessary() || conn.receivingWorker.UpdateNecessary())\n\t\t},\n\t\tisTerminating,\n\t\tconn.updateTask)\n\tconn.pingUpdater = NewUpdater(\n\t\t5000, // 5 seconds\n\t\tfunc() bool { return !isTerminated() },\n\t\tisTerminated,\n\t\tconn.updateTask)\n\tconn.pingUpdater.WakeUp()\n\n\treturn conn\n}\n\nfunc (c *Connection) Elapsed() uint32 {\n\treturn uint32(nowMillisec() - c.since)\n}\n\n// ReadMultiBuffer implements buf.Reader.\nfunc (c *Connection) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tif c == nil {\n\t\treturn nil, io.EOF\n\t}\n\n\tfor {\n\t\tif c.State().Is(StateReadyToClose, StateTerminating, StateTerminated) {\n\t\t\treturn nil, io.EOF\n\t\t}\n\t\tmb := c.receivingWorker.ReadMultiBuffer()\n\t\tif !mb.IsEmpty() {\n\t\t\tc.dataUpdater.WakeUp()\n\t\t\treturn mb, nil\n\t\t}\n\n\t\tif c.State() == StatePeerTerminating {\n\t\t\treturn nil, io.EOF\n\t\t}\n\n\t\tif err := c.waitForDataInput(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n}\n\nfunc (c *Connection) waitForDataInput() error {\n\tfor i := 0; i < 16; i++ {\n\t\tselect {\n\t\tcase <-c.dataInput.Wait():\n\t\t\treturn nil\n\t\tdefault:\n\t\t\truntime.Gosched()\n\t\t}\n\t}\n\n\tduration := time.Second * 16\n\tif !c.rd.IsZero() {\n\t\tduration = time.Until(c.rd)\n\t\tif duration < 0 {\n\t\t\treturn ErrIOTimeout\n\t\t}\n\t}\n\n\ttimeout := time.NewTimer(duration)\n\tdefer timeout.Stop()\n\n\tselect {\n\tcase <-c.dataInput.Wait():\n\tcase <-timeout.C:\n\t\tif !c.rd.IsZero() && c.rd.Before(time.Now()) {\n\t\t\treturn ErrIOTimeout\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Read implements the Conn Read method.\nfunc (c *Connection) Read(b []byte) (int, error) {\n\tif c == nil {\n\t\treturn 0, io.EOF\n\t}\n\n\tfor {\n\t\tif c.State().Is(StateReadyToClose, StateTerminating, StateTerminated) {\n\t\t\treturn 0, io.EOF\n\t\t}\n\t\tnBytes := c.receivingWorker.Read(b)\n\t\tif nBytes > 0 {\n\t\t\tc.dataUpdater.WakeUp()\n\t\t\treturn nBytes, nil\n\t\t}\n\n\t\tif err := c.waitForDataInput(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n}\n\nfunc (c *Connection) waitForDataOutput() error {\n\tfor i := 0; i < 16; i++ {\n\t\tselect {\n\t\tcase <-c.dataOutput.Wait():\n\t\t\treturn nil\n\t\tdefault:\n\t\t\truntime.Gosched()\n\t\t}\n\t}\n\n\tduration := time.Second * 16\n\tif !c.wd.IsZero() {\n\t\tduration = time.Until(c.wd)\n\t\tif duration < 0 {\n\t\t\treturn ErrIOTimeout\n\t\t}\n\t}\n\n\ttimeout := time.NewTimer(duration)\n\tdefer timeout.Stop()\n\n\tselect {\n\tcase <-c.dataOutput.Wait():\n\tcase <-timeout.C:\n\t\tif !c.wd.IsZero() && c.wd.Before(time.Now()) {\n\t\t\treturn ErrIOTimeout\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Write implements io.Writer.\nfunc (c *Connection) Write(b []byte) (int, error) {\n\treader := bytes.NewReader(b)\n\tif err := c.writeMultiBufferInternal(reader); err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(b), nil\n}\n\n// WriteMultiBuffer implements buf.Writer.\nfunc (c *Connection) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\treader := &buf.MultiBufferContainer{\n\t\tMultiBuffer: mb,\n\t}\n\tdefer reader.Close()\n\n\treturn c.writeMultiBufferInternal(reader)\n}\n\nfunc (c *Connection) writeMultiBufferInternal(reader io.Reader) error {\n\tupdatePending := false\n\tdefer func() {\n\t\tif updatePending {\n\t\t\tc.dataUpdater.WakeUp()\n\t\t}\n\t}()\n\n\tvar b *buf.Buffer\n\tdefer func() {\n\t\tb.Release()\n\t}()\n\n\tfor {\n\t\tfor {\n\t\t\tif c == nil || c.State() != StateActive {\n\t\t\t\treturn io.ErrClosedPipe\n\t\t\t}\n\n\t\t\tif b == nil {\n\t\t\t\tb = buf.New()\n\t\t\t\t_, err := b.ReadFrom(io.LimitReader(reader, int64(c.mss)))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !c.sendingWorker.Push(b) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tupdatePending = true\n\t\t\tb = nil\n\t\t}\n\n\t\tif updatePending {\n\t\t\tc.dataUpdater.WakeUp()\n\t\t\tupdatePending = false\n\t\t}\n\n\t\tif err := c.waitForDataOutput(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (c *Connection) SetState(state State) {\n\tcurrent := c.Elapsed()\n\tatomic.StoreInt32((*int32)(&c.state), int32(state))\n\tatomic.StoreUint32(&c.stateBeginTime, current)\n\tnewError(\"#\", c.meta.Conversation, \" entering state \", state, \" at \", current).AtDebug().WriteToLog()\n\n\tswitch state {\n\tcase StateReadyToClose:\n\t\tc.receivingWorker.CloseRead()\n\tcase StatePeerClosed:\n\t\tc.sendingWorker.CloseWrite()\n\tcase StateTerminating:\n\t\tc.receivingWorker.CloseRead()\n\t\tc.sendingWorker.CloseWrite()\n\t\tc.pingUpdater.SetInterval(time.Second)\n\tcase StatePeerTerminating:\n\t\tc.sendingWorker.CloseWrite()\n\t\tc.pingUpdater.SetInterval(time.Second)\n\tcase StateTerminated:\n\t\tc.receivingWorker.CloseRead()\n\t\tc.sendingWorker.CloseWrite()\n\t\tc.pingUpdater.SetInterval(time.Second)\n\t\tc.dataUpdater.WakeUp()\n\t\tc.pingUpdater.WakeUp()\n\t\tgo c.Terminate()\n\t}\n}\n\n// Close closes the connection.\nfunc (c *Connection) Close() error {\n\tif c == nil {\n\t\treturn ErrClosedConnection\n\t}\n\n\tc.dataInput.Signal()\n\tc.dataOutput.Signal()\n\n\tswitch c.State() {\n\tcase StateReadyToClose, StateTerminating, StateTerminated:\n\t\treturn ErrClosedConnection\n\tcase StateActive:\n\t\tc.SetState(StateReadyToClose)\n\tcase StatePeerClosed:\n\t\tc.SetState(StateTerminating)\n\tcase StatePeerTerminating:\n\t\tc.SetState(StateTerminated)\n\t}\n\n\tnewError(\"#\", c.meta.Conversation, \" closing connection to \", c.meta.RemoteAddr).WriteToLog()\n\n\treturn nil\n}\n\n// LocalAddr returns the local network address. The Addr returned is shared by all invocations of LocalAddr, so do not modify it.\nfunc (c *Connection) LocalAddr() net.Addr {\n\tif c == nil {\n\t\treturn nil\n\t}\n\treturn c.meta.LocalAddr\n}\n\n// RemoteAddr returns the remote network address. The Addr returned is shared by all invocations of RemoteAddr, so do not modify it.\nfunc (c *Connection) RemoteAddr() net.Addr {\n\tif c == nil {\n\t\treturn nil\n\t}\n\treturn c.meta.RemoteAddr\n}\n\n// SetDeadline sets the deadline associated with the listener. A zero time value disables the deadline.\nfunc (c *Connection) SetDeadline(t time.Time) error {\n\tif err := c.SetReadDeadline(t); err != nil {\n\t\treturn err\n\t}\n\treturn c.SetWriteDeadline(t)\n}\n\n// SetReadDeadline implements the Conn SetReadDeadline method.\nfunc (c *Connection) SetReadDeadline(t time.Time) error {\n\tif c == nil || c.State() != StateActive {\n\t\treturn ErrClosedConnection\n\t}\n\tc.rd = t\n\treturn nil\n}\n\n// SetWriteDeadline implements the Conn SetWriteDeadline method.\nfunc (c *Connection) SetWriteDeadline(t time.Time) error {\n\tif c == nil || c.State() != StateActive {\n\t\treturn ErrClosedConnection\n\t}\n\tc.wd = t\n\treturn nil\n}\n\n// kcp update, input loop\nfunc (c *Connection) updateTask() {\n\tc.flush()\n}\n\nfunc (c *Connection) Terminate() {\n\tif c == nil {\n\t\treturn\n\t}\n\tnewError(\"#\", c.meta.Conversation, \" terminating connection to \", c.RemoteAddr()).WriteToLog()\n\n\t// v.SetState(StateTerminated)\n\tc.dataInput.Signal()\n\tc.dataOutput.Signal()\n\n\tc.closer.Close()\n\tc.sendingWorker.Release()\n\tc.receivingWorker.Release()\n\tc.output.Release()\n}\n\nfunc (c *Connection) HandleOption(opt SegmentOption) {\n\tif (opt & SegmentOptionClose) == SegmentOptionClose {\n\t\tc.OnPeerClosed()\n\t}\n}\n\nfunc (c *Connection) OnPeerClosed() {\n\tswitch c.State() {\n\tcase StateReadyToClose:\n\t\tc.SetState(StateTerminating)\n\tcase StateActive:\n\t\tc.SetState(StatePeerClosed)\n\t}\n}\n\n// Input when you received a low level packet (eg. UDP packet), call it\nfunc (c *Connection) Input(segments []Segment) {\n\tcurrent := c.Elapsed()\n\tatomic.StoreUint32(&c.lastIncomingTime, current)\n\n\tfor _, seg := range segments {\n\t\tif seg.Conversation() != c.meta.Conversation {\n\t\t\tbreak\n\t\t}\n\n\t\tswitch seg := seg.(type) {\n\t\tcase *DataSegment:\n\t\t\tc.HandleOption(seg.Option)\n\t\t\tc.receivingWorker.ProcessSegment(seg)\n\t\t\tif c.receivingWorker.IsDataAvailable() {\n\t\t\t\tc.dataInput.Signal()\n\t\t\t}\n\t\t\tc.dataUpdater.WakeUp()\n\t\tcase *AckSegment:\n\t\t\tc.HandleOption(seg.Option)\n\t\t\tc.sendingWorker.ProcessSegment(current, seg, c.roundTrip.Timeout())\n\t\t\tc.dataOutput.Signal()\n\t\t\tc.dataUpdater.WakeUp()\n\t\tcase *CmdOnlySegment:\n\t\t\tc.HandleOption(seg.Option)\n\t\t\tif seg.Command() == CommandTerminate {\n\t\t\t\tswitch c.State() {\n\t\t\t\tcase StateActive, StatePeerClosed:\n\t\t\t\t\tc.SetState(StatePeerTerminating)\n\t\t\t\tcase StateReadyToClose:\n\t\t\t\t\tc.SetState(StateTerminating)\n\t\t\t\tcase StateTerminating:\n\t\t\t\t\tc.SetState(StateTerminated)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif seg.Option == SegmentOptionClose || seg.Command() == CommandTerminate {\n\t\t\t\tc.dataInput.Signal()\n\t\t\t\tc.dataOutput.Signal()\n\t\t\t}\n\t\t\tc.sendingWorker.ProcessReceivingNext(seg.ReceivingNext)\n\t\t\tc.receivingWorker.ProcessSendingNext(seg.SendingNext)\n\t\t\tc.roundTrip.UpdatePeerRTO(seg.PeerRTO, current)\n\t\t\tseg.Release()\n\t\tdefault:\n\t\t}\n\t}\n}\n\nfunc (c *Connection) flush() {\n\tcurrent := c.Elapsed()\n\n\tif c.State() == StateTerminated {\n\t\treturn\n\t}\n\tif c.State() == StateActive && current-atomic.LoadUint32(&c.lastIncomingTime) >= 30000 {\n\t\tc.Close()\n\t}\n\tif c.State() == StateReadyToClose && c.sendingWorker.IsEmpty() {\n\t\tc.SetState(StateTerminating)\n\t}\n\n\tif c.State() == StateTerminating {\n\t\tnewError(\"#\", c.meta.Conversation, \" sending terminating cmd.\").AtDebug().WriteToLog()\n\t\tc.Ping(current, CommandTerminate)\n\n\t\tif current-atomic.LoadUint32(&c.stateBeginTime) > 8000 {\n\t\t\tc.SetState(StateTerminated)\n\t\t}\n\t\treturn\n\t}\n\tif c.State() == StatePeerTerminating && current-atomic.LoadUint32(&c.stateBeginTime) > 4000 {\n\t\tc.SetState(StateTerminating)\n\t}\n\n\tif c.State() == StateReadyToClose && current-atomic.LoadUint32(&c.stateBeginTime) > 15000 {\n\t\tc.SetState(StateTerminating)\n\t}\n\n\t// flush acknowledges\n\tc.receivingWorker.Flush(current)\n\tc.sendingWorker.Flush(current)\n\n\tif current-atomic.LoadUint32(&c.lastPingTime) >= 3000 {\n\t\tc.Ping(current, CommandPing)\n\t}\n}\n\nfunc (c *Connection) State() State {\n\treturn State(atomic.LoadInt32((*int32)(&c.state)))\n}\n\nfunc (c *Connection) Ping(current uint32, cmd Command) {\n\tseg := NewCmdOnlySegment()\n\tseg.Conv = c.meta.Conversation\n\tseg.Cmd = cmd\n\tseg.ReceivingNext = c.receivingWorker.NextNumber()\n\tseg.SendingNext = c.sendingWorker.FirstUnacknowledged()\n\tseg.PeerRTO = c.roundTrip.Timeout()\n\tif c.State() == StateReadyToClose {\n\t\tseg.Option = SegmentOptionClose\n\t}\n\tc.output.Write(seg)\n\tatomic.StoreUint32(&c.lastPingTime, current)\n\tseg.Release()\n}\n"
  },
  {
    "path": "transport/internet/kcp/connection_test.go",
    "content": "package kcp_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n)\n\ntype NoOpCloser int\n\nfunc (NoOpCloser) Close() error {\n\treturn nil\n}\n\nfunc TestConnectionReadTimeout(t *testing.T) {\n\tconn := NewConnection(ConnMetadata{Conversation: 1}, &KCPPacketWriter{\n\t\tWriter: buf.DiscardBytes,\n\t}, NoOpCloser(0), &Config{})\n\tconn.SetReadDeadline(time.Now().Add(time.Second))\n\n\tb := make([]byte, 1024)\n\tnBytes, err := conn.Read(b)\n\tif nBytes != 0 || err == nil {\n\t\tt.Error(\"unexpected read: \", nBytes, err)\n\t}\n\n\tconn.Terminate()\n}\n\nfunc TestConnectionInterface(t *testing.T) {\n\t_ = (io.Writer)(new(Connection))\n\t_ = (io.Reader)(new(Connection))\n\t_ = (buf.Reader)(new(Connection))\n\t_ = (buf.Writer)(new(Connection))\n}\n"
  },
  {
    "path": "transport/internet/kcp/crypt.go",
    "content": "package kcp\n\nimport (\n\t\"crypto/cipher\"\n\t\"encoding/binary\"\n\t\"hash/fnv\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n// SimpleAuthenticator is a legacy AEAD used for KCP encryption.\ntype SimpleAuthenticator struct{}\n\n// NewSimpleAuthenticator creates a new SimpleAuthenticator\nfunc NewSimpleAuthenticator() cipher.AEAD {\n\treturn &SimpleAuthenticator{}\n}\n\n// NonceSize implements cipher.AEAD.NonceSize().\nfunc (*SimpleAuthenticator) NonceSize() int {\n\treturn 0\n}\n\n// Overhead implements cipher.AEAD.NonceSize().\nfunc (*SimpleAuthenticator) Overhead() int {\n\treturn 6\n}\n\n// Seal implements cipher.AEAD.Seal().\nfunc (a *SimpleAuthenticator) Seal(dst, nonce, plain, extra []byte) []byte {\n\tdst = append(dst, 0, 0, 0, 0, 0, 0) // 4 bytes for hash, and then 2 bytes for length\n\tbinary.BigEndian.PutUint16(dst[4:], uint16(len(plain)))\n\tdst = append(dst, plain...)\n\n\tfnvHash := fnv.New32a()\n\tcommon.Must2(fnvHash.Write(dst[4:]))\n\tfnvHash.Sum(dst[:0])\n\n\tdstLen := len(dst)\n\txtra := 4 - dstLen%4\n\tif xtra != 4 {\n\t\tdst = append(dst, make([]byte, xtra)...)\n\t}\n\txorfwd(dst)\n\tif xtra != 4 {\n\t\tdst = dst[:dstLen]\n\t}\n\treturn dst\n}\n\n// Open implements cipher.AEAD.Open().\nfunc (a *SimpleAuthenticator) Open(dst, nonce, cipherText, extra []byte) ([]byte, error) {\n\tdst = append(dst, cipherText...)\n\tdstLen := len(dst)\n\txtra := 4 - dstLen%4\n\tif xtra != 4 {\n\t\tdst = append(dst, make([]byte, xtra)...)\n\t}\n\txorbkd(dst)\n\tif xtra != 4 {\n\t\tdst = dst[:dstLen]\n\t}\n\n\tfnvHash := fnv.New32a()\n\tcommon.Must2(fnvHash.Write(dst[4:]))\n\tif binary.BigEndian.Uint32(dst[:4]) != fnvHash.Sum32() {\n\t\treturn nil, newError(\"invalid auth\")\n\t}\n\n\tlength := binary.BigEndian.Uint16(dst[4:6])\n\tif len(dst)-6 != int(length) {\n\t\treturn nil, newError(\"invalid auth\")\n\t}\n\n\treturn dst[6:], nil\n}\n"
  },
  {
    "path": "transport/internet/kcp/crypt_test.go",
    "content": "package kcp_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n)\n\nfunc TestSimpleAuthenticator(t *testing.T) {\n\tcache := make([]byte, 512)\n\n\tpayload := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'}\n\n\tauth := NewSimpleAuthenticator()\n\tb := auth.Seal(cache[:0], nil, payload, nil)\n\tc, err := auth.Open(cache[:0], nil, b, nil)\n\tcommon.Must(err)\n\tif r := cmp.Diff(c, payload); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestSimpleAuthenticator2(t *testing.T) {\n\tcache := make([]byte, 512)\n\n\tpayload := []byte{'a', 'b'}\n\n\tauth := NewSimpleAuthenticator()\n\tb := auth.Seal(cache[:0], nil, payload, nil)\n\tc, err := auth.Open(cache[:0], nil, b, nil)\n\tcommon.Must(err)\n\tif r := cmp.Diff(c, payload); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/kcp/cryptreal.go",
    "content": "package kcp\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/sha256\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\nfunc NewAEADAESGCMBasedOnSeed(seed string) cipher.AEAD {\n\thashedSeed := sha256.Sum256([]byte(seed))\n\taesBlock := common.Must2(aes.NewCipher(hashedSeed[:16])).(cipher.Block)\n\treturn common.Must2(cipher.NewGCM(aesBlock)).(cipher.AEAD)\n}\n"
  },
  {
    "path": "transport/internet/kcp/dialer.go",
    "content": "package kcp\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync/atomic\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/dice\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nvar globalConv = uint32(dice.RollUint16())\n\nfunc fetchInput(_ context.Context, input io.Reader, reader PacketReader, conn *Connection) {\n\tcache := make(chan *buf.Buffer, 1024)\n\tgo func() {\n\t\tfor {\n\t\t\tpayload := buf.New()\n\t\t\tif _, err := payload.ReadFrom(input); err != nil {\n\t\t\t\tpayload.Release()\n\t\t\t\tclose(cache)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tselect {\n\t\t\tcase cache <- payload:\n\t\t\tdefault:\n\t\t\t\tpayload.Release()\n\t\t\t}\n\t\t}\n\t}()\n\n\tfor payload := range cache {\n\t\tsegments := reader.Read(payload.Bytes())\n\t\tpayload.Release()\n\t\tif len(segments) > 0 {\n\t\t\tconn.Input(segments)\n\t\t}\n\t}\n}\n\n// DialKCP dials a new KCP connections to the specific destination.\nfunc DialKCP(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tdest.Network = net.Network_UDP\n\tnewError(\"dialing mKCP to \", dest).WriteToLog()\n\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.Dialer()\n\n\trawConn, err := dialer.Dial(ctx, nil, dest, streamSettings.SocketSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial to dest: \", err).AtWarning().Base(err)\n\t}\n\n\tkcpSettings := streamSettings.ProtocolSettings.(*Config)\n\n\theader, err := kcpSettings.GetPackerHeader()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create packet header\").Base(err)\n\t}\n\tsecurity, err := kcpSettings.GetSecurity()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create security\").Base(err)\n\t}\n\treader := &KCPPacketReader{\n\t\tHeader:   header,\n\t\tSecurity: security,\n\t}\n\twriter := &KCPPacketWriter{\n\t\tHeader:   header,\n\t\tSecurity: security,\n\t\tWriter:   rawConn,\n\t}\n\n\tconv := uint16(atomic.AddUint32(&globalConv, 1))\n\tsession := NewConnection(ConnMetadata{\n\t\tLocalAddr:    rawConn.LocalAddr(),\n\t\tRemoteAddr:   rawConn.RemoteAddr(),\n\t\tConversation: conv,\n\t}, writer, rawConn, kcpSettings)\n\n\tgo fetchInput(ctx, rawConn, reader, session)\n\n\tvar iConn internet.Connection = session\n\n\tif config := tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\tiConn = tls.Client(iConn, config.GetTLSConfig(tls.WithDestination(dest)))\n\t}\n\n\treturn iConn, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, DialKCP))\n}\n"
  },
  {
    "path": "transport/internet/kcp/errors.generated.go",
    "content": "package kcp\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/kcp/io.go",
    "content": "package kcp\n\nimport (\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype PacketReader interface {\n\tRead([]byte) []Segment\n}\n\ntype PacketWriter interface {\n\tOverhead() int\n\tio.Writer\n}\n\ntype KCPPacketReader struct { // nolint: revive\n\tSecurity cipher.AEAD\n\tHeader   internet.PacketHeader\n}\n\nfunc (r *KCPPacketReader) Read(b []byte) []Segment {\n\tif r.Header != nil {\n\t\tif int32(len(b)) <= r.Header.Size() {\n\t\t\treturn nil\n\t\t}\n\t\tb = b[r.Header.Size():]\n\t}\n\tif r.Security != nil {\n\t\tnonceSize := r.Security.NonceSize()\n\t\toverhead := r.Security.Overhead()\n\t\tif len(b) <= nonceSize+overhead {\n\t\t\treturn nil\n\t\t}\n\t\tout, err := r.Security.Open(b[nonceSize:nonceSize], b[:nonceSize], b[nonceSize:], nil)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tb = out\n\t}\n\tvar result []Segment\n\tfor len(b) > 0 {\n\t\tseg, x := ReadSegment(b)\n\t\tif seg == nil {\n\t\t\tbreak\n\t\t}\n\t\tresult = append(result, seg)\n\t\tb = x\n\t}\n\treturn result\n}\n\ntype KCPPacketWriter struct { // nolint: revive\n\tHeader   internet.PacketHeader\n\tSecurity cipher.AEAD\n\tWriter   io.Writer\n}\n\nfunc (w *KCPPacketWriter) Overhead() int {\n\toverhead := 0\n\tif w.Header != nil {\n\t\toverhead += int(w.Header.Size())\n\t}\n\tif w.Security != nil {\n\t\toverhead += w.Security.Overhead()\n\t}\n\treturn overhead\n}\n\nfunc (w *KCPPacketWriter) Write(b []byte) (int, error) {\n\tbb := buf.StackNew()\n\tdefer bb.Release()\n\n\tif w.Header != nil {\n\t\tw.Header.Serialize(bb.Extend(w.Header.Size()))\n\t}\n\tif w.Security != nil {\n\t\tnonceSize := w.Security.NonceSize()\n\t\tcommon.Must2(bb.ReadFullFrom(rand.Reader, int32(nonceSize)))\n\t\tnonce := bb.BytesFrom(int32(-nonceSize))\n\n\t\tencrypted := bb.Extend(int32(w.Security.Overhead() + len(b)))\n\t\tw.Security.Seal(encrypted[:0], nonce, b, nil)\n\t} else {\n\t\tbb.Write(b)\n\t}\n\n\t_, err := w.Writer.Write(bb.Bytes())\n\treturn len(b), err\n}\n"
  },
  {
    "path": "transport/internet/kcp/io_test.go",
    "content": "package kcp_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n)\n\nfunc TestKCPPacketReader(t *testing.T) {\n\treader := KCPPacketReader{\n\t\tSecurity: &SimpleAuthenticator{},\n\t}\n\n\ttestCases := []struct {\n\t\tInput  []byte\n\t\tOutput []Segment\n\t}{\n\t\t{\n\t\t\tInput:  []byte{},\n\t\t\tOutput: nil,\n\t\t},\n\t\t{\n\t\t\tInput:  []byte{1},\n\t\t\tOutput: nil,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tseg := reader.Read(testCase.Input)\n\t\tif testCase.Output == nil && seg != nil {\n\t\t\tt.Errorf(\"Expect nothing returned, but actually %v\", seg)\n\t\t} else if testCase.Output != nil && seg == nil {\n\t\t\tt.Errorf(\"Expect some output, but got nil\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "transport/internet/kcp/kcp.go",
    "content": "// Package kcp - A Fast and Reliable ARQ Protocol\n//\n// Acknowledgement:\n//\n//\tskywind3000@github for inventing the KCP protocol\n//\txtaci@github for translating to Golang\npackage kcp\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/kcp/kcp_test.go",
    "content": "package kcp_test\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/deferredpersistentstorage\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/filesystemimpl\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/systemnetworkimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/transientstorageimpl\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n)\n\nfunc TestDialAndListen(t *testing.T) {\n\tctx := context.Background()\n\tdefaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()\n\tdefaultFilesystemImpl := filesystemimpl.NewDefaultFileSystemDefaultImpl()\n\tdeferredPersistentStorageImpl := deferredpersistentstorage.NewDeferredPersistentStorage(ctx)\n\trootEnv := environment.NewRootEnvImpl(ctx,\n\t\ttransientstorageimpl.NewScopedTransientStorageImpl(), defaultNetworkImpl.Dialer(), defaultNetworkImpl.Listener(),\n\t\tdefaultFilesystemImpl, deferredPersistentStorageImpl)\n\tproxyEnvironment := rootEnv.ProxyEnvironment(\"o\")\n\ttransportEnvironment, err := proxyEnvironment.NarrowScopeToTransport(\"kcp\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tctx = envctx.ContextWithEnvironment(ctx, transportEnvironment)\n\n\tlistener, err := NewListener(ctx, net.LocalHostIP, net.Port(0), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"mkcp\",\n\t\tProtocolSettings: &Config{},\n\t}, func(conn internet.Connection) {\n\t\tgo func(c internet.Connection) {\n\t\t\tpayload := make([]byte, 4096)\n\t\t\tfor {\n\t\t\t\tnBytes, err := c.Read(payload)\n\t\t\t\tif err != nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tfor idx, b := range payload[:nBytes] {\n\t\t\t\t\tpayload[idx] = b ^ 'c'\n\t\t\t\t}\n\t\t\t\tc.Write(payload[:nBytes])\n\t\t\t}\n\t\t\tc.Close()\n\t\t}(conn)\n\t})\n\tcommon.Must(err)\n\tdefer listener.Close()\n\n\tport := net.Port(listener.Addr().(*net.UDPAddr).Port)\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(func() error {\n\t\t\tclientConn, err := DialKCP(ctx, net.UDPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\t\t\tProtocolName:     \"mkcp\",\n\t\t\t\tProtocolSettings: &Config{},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer clientConn.Close()\n\n\t\t\tclientSend := make([]byte, 1024*1024)\n\t\t\trand.Read(clientSend)\n\t\t\tgo clientConn.Write(clientSend)\n\n\t\t\tclientReceived := make([]byte, 1024*1024)\n\t\t\tcommon.Must2(io.ReadFull(clientConn, clientReceived))\n\n\t\t\tclientExpected := make([]byte, 1024*1024)\n\t\t\tfor idx, b := range clientSend {\n\t\t\t\tclientExpected[idx] = b ^ 'c'\n\t\t\t}\n\t\t\tif r := cmp.Diff(clientReceived, clientExpected); r != \"\" {\n\t\t\t\treturn errors.New(r)\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t}\n\n\tif err := errg.Wait(); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tfor i := 0; i < 60 && listener.ActiveConnections() > 0; i++ {\n\t\ttime.Sleep(500 * time.Millisecond)\n\t}\n\tif v := listener.ActiveConnections(); v != 0 {\n\t\tt.Error(\"active connections: \", v)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/kcp/listener.go",
    "content": "package kcp\n\nimport (\n\t\"context\"\n\t\"crypto/cipher\"\n\tgotls \"crypto/tls\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n)\n\ntype ConnectionID struct {\n\tRemote net.Address\n\tPort   net.Port\n\tConv   uint16\n}\n\n// Listener defines a server listening for connections\ntype Listener struct {\n\tsync.Mutex\n\tsessions  map[ConnectionID]*Connection\n\thub       *udp.Hub\n\ttlsConfig *gotls.Config\n\tconfig    *Config\n\treader    PacketReader\n\theader    internet.PacketHeader\n\tsecurity  cipher.AEAD\n\taddConn   internet.ConnHandler\n}\n\nfunc NewListener(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (*Listener, error) {\n\tkcpSettings := streamSettings.ProtocolSettings.(*Config)\n\theader, err := kcpSettings.GetPackerHeader()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create packet header\").Base(err).AtError()\n\t}\n\tsecurity, err := kcpSettings.GetSecurity()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create security\").Base(err).AtError()\n\t}\n\tl := &Listener{\n\t\theader:   header,\n\t\tsecurity: security,\n\t\treader: &KCPPacketReader{\n\t\t\tHeader:   header,\n\t\t\tSecurity: security,\n\t\t},\n\t\tsessions: make(map[ConnectionID]*Connection),\n\t\tconfig:   kcpSettings,\n\t\taddConn:  addConn,\n\t}\n\n\tif config := tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\tl.tlsConfig = config.GetTLSConfig()\n\t}\n\n\thub, err := udp.ListenUDP(ctx, address, port, streamSettings, udp.HubCapacity(1024))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tl.Lock()\n\tl.hub = hub\n\tl.Unlock()\n\tnewError(\"listening on \", address, \":\", port).WriteToLog()\n\n\tgo l.handlePackets()\n\n\treturn l, nil\n}\n\nfunc (l *Listener) handlePackets() {\n\treceive := l.hub.Receive()\n\tfor payload := range receive {\n\t\tl.OnReceive(payload.Payload, payload.Source)\n\t}\n}\n\nfunc (l *Listener) OnReceive(payload *buf.Buffer, src net.Destination) {\n\tsegments := l.reader.Read(payload.Bytes())\n\tpayload.Release()\n\n\tif len(segments) == 0 {\n\t\tnewError(\"discarding invalid payload from \", src).WriteToLog()\n\t\treturn\n\t}\n\n\tconv := segments[0].Conversation()\n\tcmd := segments[0].Command()\n\n\tid := ConnectionID{\n\t\tRemote: src.Address,\n\t\tPort:   src.Port,\n\t\tConv:   conv,\n\t}\n\n\tl.Lock()\n\tdefer l.Unlock()\n\n\tconn, found := l.sessions[id]\n\n\tif !found {\n\t\tif cmd == CommandTerminate {\n\t\t\treturn\n\t\t}\n\t\twriter := &Writer{\n\t\t\tid:       id,\n\t\t\thub:      l.hub,\n\t\t\tdest:     src,\n\t\t\tlistener: l,\n\t\t}\n\t\tremoteAddr := &net.UDPAddr{\n\t\t\tIP:   src.Address.IP(),\n\t\t\tPort: int(src.Port),\n\t\t}\n\t\tlocalAddr := l.hub.Addr()\n\t\tconn = NewConnection(ConnMetadata{\n\t\t\tLocalAddr:    localAddr,\n\t\t\tRemoteAddr:   remoteAddr,\n\t\t\tConversation: conv,\n\t\t}, &KCPPacketWriter{\n\t\t\tHeader:   l.header,\n\t\t\tSecurity: l.security,\n\t\t\tWriter:   writer,\n\t\t}, writer, l.config)\n\t\tvar netConn internet.Connection = conn\n\t\tif l.tlsConfig != nil {\n\t\t\tnetConn = tls.Server(conn, l.tlsConfig)\n\t\t}\n\n\t\tl.addConn(netConn)\n\t\tl.sessions[id] = conn\n\t}\n\tconn.Input(segments)\n}\n\nfunc (l *Listener) Remove(id ConnectionID) {\n\tl.Lock()\n\tdelete(l.sessions, id)\n\tl.Unlock()\n}\n\n// Close stops listening on the UDP address. Already Accepted connections are not closed.\nfunc (l *Listener) Close() error {\n\tl.hub.Close()\n\n\tl.Lock()\n\tdefer l.Unlock()\n\n\tfor _, conn := range l.sessions {\n\t\tgo conn.Terminate()\n\t}\n\n\treturn nil\n}\n\nfunc (l *Listener) ActiveConnections() int {\n\tl.Lock()\n\tdefer l.Unlock()\n\n\treturn len(l.sessions)\n}\n\n// Addr returns the listener's network address, The Addr returned is shared by all invocations of Addr, so do not modify it.\nfunc (l *Listener) Addr() net.Addr {\n\treturn l.hub.Addr()\n}\n\ntype Writer struct {\n\tid       ConnectionID\n\tdest     net.Destination\n\thub      *udp.Hub\n\tlistener *Listener\n}\n\nfunc (w *Writer) Write(payload []byte) (int, error) {\n\treturn w.hub.WriteTo(payload, w.dest)\n}\n\nfunc (w *Writer) Close() error {\n\tw.listener.Remove(w.id)\n\treturn nil\n}\n\nfunc ListenKCP(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {\n\treturn NewListener(ctx, address, port, streamSettings, addConn)\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, ListenKCP))\n}\n"
  },
  {
    "path": "transport/internet/kcp/output.go",
    "content": "package kcp\n\nimport (\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/retry\"\n)\n\ntype SegmentWriter interface {\n\tWrite(seg Segment) error\n\tRelease()\n}\n\ntype SimpleSegmentWriter struct {\n\tsync.Mutex\n\tbuffer *buf.Buffer\n\twriter io.Writer\n\tclosed bool\n}\n\nfunc NewSegmentWriter(writer io.Writer) SegmentWriter {\n\treturn &SimpleSegmentWriter{\n\t\twriter: writer,\n\t\tbuffer: buf.New(),\n\t}\n}\n\nfunc (w *SimpleSegmentWriter) Write(seg Segment) error {\n\tw.Lock()\n\tdefer w.Unlock()\n\tif w.closed {\n\t\treturn io.ErrClosedPipe\n\t}\n\n\tw.buffer.Clear()\n\trawBytes := w.buffer.Extend(seg.ByteSize())\n\tseg.Serialize(rawBytes)\n\t_, err := w.writer.Write(w.buffer.Bytes())\n\treturn err\n}\n\nfunc (w *SimpleSegmentWriter) Release() {\n\tw.Lock()\n\tdefer w.Unlock()\n\tw.buffer.Release()\n\tw.closed = true\n}\n\ntype RetryableWriter struct {\n\twriter SegmentWriter\n}\n\nfunc NewRetryableWriter(writer SegmentWriter) SegmentWriter {\n\treturn &RetryableWriter{\n\t\twriter: writer,\n\t}\n}\n\nfunc (w *RetryableWriter) Write(seg Segment) error {\n\treturn retry.Timed(5, 100).On(func() error {\n\t\treturn w.writer.Write(seg)\n\t})\n}\n\nfunc (w *RetryableWriter) Release() {\n\tw.writer.Release()\n}\n"
  },
  {
    "path": "transport/internet/kcp/receiving.go",
    "content": "package kcp\n\nimport (\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\ntype ReceivingWindow struct {\n\tcache map[uint32]*DataSegment\n}\n\nfunc NewReceivingWindow() *ReceivingWindow {\n\treturn &ReceivingWindow{\n\t\tcache: make(map[uint32]*DataSegment),\n\t}\n}\n\nfunc (w *ReceivingWindow) Set(id uint32, value *DataSegment) bool {\n\t_, f := w.cache[id]\n\tif f {\n\t\treturn false\n\t}\n\tw.cache[id] = value\n\treturn true\n}\n\nfunc (w *ReceivingWindow) Has(id uint32) bool {\n\t_, f := w.cache[id]\n\treturn f\n}\n\nfunc (w *ReceivingWindow) Remove(id uint32) *DataSegment {\n\tv, f := w.cache[id]\n\tif !f {\n\t\treturn nil\n\t}\n\tdelete(w.cache, id)\n\treturn v\n}\n\ntype AckList struct {\n\twriter     SegmentWriter\n\ttimestamps []uint32\n\tnumbers    []uint32\n\tnextFlush  []uint32\n\n\tflushCandidates []uint32\n\tdirty           bool\n}\n\nfunc NewAckList(writer SegmentWriter) *AckList {\n\treturn &AckList{\n\t\twriter:          writer,\n\t\ttimestamps:      make([]uint32, 0, 128),\n\t\tnumbers:         make([]uint32, 0, 128),\n\t\tnextFlush:       make([]uint32, 0, 128),\n\t\tflushCandidates: make([]uint32, 0, 128),\n\t}\n}\n\nfunc (l *AckList) Add(number uint32, timestamp uint32) {\n\tl.timestamps = append(l.timestamps, timestamp)\n\tl.numbers = append(l.numbers, number)\n\tl.nextFlush = append(l.nextFlush, 0)\n\tl.dirty = true\n}\n\nfunc (l *AckList) Clear(una uint32) {\n\tcount := 0\n\tfor i := 0; i < len(l.numbers); i++ {\n\t\tif l.numbers[i] < una {\n\t\t\tcontinue\n\t\t}\n\t\tif i != count {\n\t\t\tl.numbers[count] = l.numbers[i]\n\t\t\tl.timestamps[count] = l.timestamps[i]\n\t\t\tl.nextFlush[count] = l.nextFlush[i]\n\t\t}\n\t\tcount++\n\t}\n\tif count < len(l.numbers) {\n\t\tl.numbers = l.numbers[:count]\n\t\tl.timestamps = l.timestamps[:count]\n\t\tl.nextFlush = l.nextFlush[:count]\n\t\tl.dirty = true\n\t}\n}\n\nfunc (l *AckList) Flush(current uint32, rto uint32) {\n\tl.flushCandidates = l.flushCandidates[:0]\n\n\tseg := NewAckSegment()\n\tfor i := 0; i < len(l.numbers); i++ {\n\t\tif l.nextFlush[i] > current {\n\t\t\tif len(l.flushCandidates) < cap(l.flushCandidates) {\n\t\t\t\tl.flushCandidates = append(l.flushCandidates, l.numbers[i])\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tseg.PutNumber(l.numbers[i])\n\t\tseg.PutTimestamp(l.timestamps[i])\n\t\ttimeout := rto / 2\n\t\tif timeout < 20 {\n\t\t\ttimeout = 20\n\t\t}\n\t\tl.nextFlush[i] = current + timeout\n\n\t\tif seg.IsFull() {\n\t\t\tl.writer.Write(seg)\n\t\t\tseg.Release()\n\t\t\tseg = NewAckSegment()\n\t\t\tl.dirty = false\n\t\t}\n\t}\n\n\tif l.dirty || !seg.IsEmpty() {\n\t\tfor _, number := range l.flushCandidates {\n\t\t\tif seg.IsFull() {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tseg.PutNumber(number)\n\t\t}\n\t\tl.writer.Write(seg)\n\t\tl.dirty = false\n\t}\n\n\tseg.Release()\n}\n\ntype ReceivingWorker struct {\n\tsync.RWMutex\n\tconn       *Connection\n\tleftOver   buf.MultiBuffer\n\twindow     *ReceivingWindow\n\tacklist    *AckList\n\tnextNumber uint32\n\twindowSize uint32\n}\n\nfunc NewReceivingWorker(kcp *Connection) *ReceivingWorker {\n\tworker := &ReceivingWorker{\n\t\tconn:       kcp,\n\t\twindow:     NewReceivingWindow(),\n\t\twindowSize: kcp.Config.GetReceivingInFlightSize(),\n\t}\n\tworker.acklist = NewAckList(worker)\n\treturn worker\n}\n\nfunc (w *ReceivingWorker) Release() {\n\tw.Lock()\n\tbuf.ReleaseMulti(w.leftOver)\n\tw.leftOver = nil\n\tw.Unlock()\n}\n\nfunc (w *ReceivingWorker) ProcessSendingNext(number uint32) {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tw.acklist.Clear(number)\n}\n\nfunc (w *ReceivingWorker) ProcessSegment(seg *DataSegment) {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tnumber := seg.Number\n\tidx := number - w.nextNumber\n\tif idx >= w.windowSize {\n\t\treturn\n\t}\n\tw.acklist.Clear(seg.SendingNext)\n\tw.acklist.Add(number, seg.Timestamp)\n\n\tif !w.window.Set(seg.Number, seg) {\n\t\tseg.Release()\n\t}\n}\n\nfunc (w *ReceivingWorker) ReadMultiBuffer() buf.MultiBuffer {\n\tif w.leftOver != nil {\n\t\tmb := w.leftOver\n\t\tw.leftOver = nil\n\t\treturn mb\n\t}\n\n\tmb := make(buf.MultiBuffer, 0, 32)\n\n\tw.Lock()\n\tdefer w.Unlock()\n\tfor {\n\t\tseg := w.window.Remove(w.nextNumber)\n\t\tif seg == nil {\n\t\t\tbreak\n\t\t}\n\t\tw.nextNumber++\n\t\tmb = append(mb, seg.Detach())\n\t\tseg.Release()\n\t}\n\n\treturn mb\n}\n\nfunc (w *ReceivingWorker) Read(b []byte) int {\n\tmb := w.ReadMultiBuffer()\n\tif mb.IsEmpty() {\n\t\treturn 0\n\t}\n\tmb, nBytes := buf.SplitBytes(mb, b)\n\tif !mb.IsEmpty() {\n\t\tw.leftOver = mb\n\t}\n\treturn nBytes\n}\n\nfunc (w *ReceivingWorker) IsDataAvailable() bool {\n\tw.RLock()\n\tdefer w.RUnlock()\n\treturn w.window.Has(w.nextNumber)\n}\n\nfunc (w *ReceivingWorker) NextNumber() uint32 {\n\tw.RLock()\n\tdefer w.RUnlock()\n\n\treturn w.nextNumber\n}\n\nfunc (w *ReceivingWorker) Flush(current uint32) {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tw.acklist.Flush(current, w.conn.roundTrip.Timeout())\n}\n\nfunc (w *ReceivingWorker) Write(seg Segment) error {\n\tackSeg := seg.(*AckSegment)\n\tackSeg.Conv = w.conn.meta.Conversation\n\tackSeg.ReceivingNext = w.nextNumber\n\tackSeg.ReceivingWindow = w.nextNumber + w.windowSize\n\tackSeg.Option = 0\n\tif w.conn.State() == StateReadyToClose {\n\t\tackSeg.Option = SegmentOptionClose\n\t}\n\treturn w.conn.output.Write(ackSeg)\n}\n\nfunc (*ReceivingWorker) CloseRead() {\n}\n\nfunc (w *ReceivingWorker) UpdateNecessary() bool {\n\tw.RLock()\n\tdefer w.RUnlock()\n\n\treturn len(w.acklist.numbers) > 0\n}\n"
  },
  {
    "path": "transport/internet/kcp/segment.go",
    "content": "package kcp\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\n// Command is a KCP command that indicate the purpose of a Segment.\ntype Command byte\n\nconst (\n\t// CommandACK indicates an AckSegment.\n\tCommandACK Command = 0\n\t// CommandData indicates a DataSegment.\n\tCommandData Command = 1\n\t// CommandTerminate indicates that peer terminates the connection.\n\tCommandTerminate Command = 2\n\t// CommandPing indicates a ping.\n\tCommandPing Command = 3\n)\n\ntype SegmentOption byte\n\nconst (\n\tSegmentOptionClose SegmentOption = 1\n)\n\ntype Segment interface {\n\tRelease()\n\tConversation() uint16\n\tCommand() Command\n\tByteSize() int32\n\tSerialize([]byte)\n\tparse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte)\n}\n\nconst (\n\tDataSegmentOverhead = 18\n)\n\ntype DataSegment struct {\n\tConv        uint16\n\tOption      SegmentOption\n\tTimestamp   uint32\n\tNumber      uint32\n\tSendingNext uint32\n\n\tpayload  *buf.Buffer\n\ttimeout  uint32\n\ttransmit uint32\n}\n\nfunc NewDataSegment() *DataSegment {\n\treturn new(DataSegment)\n}\n\nfunc (s *DataSegment) parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte) {\n\ts.Conv = conv\n\ts.Option = opt\n\tif len(buf) < 15 {\n\t\treturn false, nil\n\t}\n\ts.Timestamp = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\ts.Number = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\ts.SendingNext = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\tdataLen := int(binary.BigEndian.Uint16(buf))\n\tbuf = buf[2:]\n\n\tif len(buf) < dataLen {\n\t\treturn false, nil\n\t}\n\ts.Data().Clear()\n\ts.Data().Write(buf[:dataLen])\n\tbuf = buf[dataLen:]\n\n\treturn true, buf\n}\n\nfunc (s *DataSegment) Conversation() uint16 {\n\treturn s.Conv\n}\n\nfunc (*DataSegment) Command() Command {\n\treturn CommandData\n}\n\nfunc (s *DataSegment) Detach() *buf.Buffer {\n\tr := s.payload\n\ts.payload = nil\n\treturn r\n}\n\nfunc (s *DataSegment) Data() *buf.Buffer {\n\tif s.payload == nil {\n\t\ts.payload = buf.New()\n\t}\n\treturn s.payload\n}\n\nfunc (s *DataSegment) Serialize(b []byte) {\n\tbinary.BigEndian.PutUint16(b, s.Conv)\n\tb[2] = byte(CommandData)\n\tb[3] = byte(s.Option)\n\tbinary.BigEndian.PutUint32(b[4:], s.Timestamp)\n\tbinary.BigEndian.PutUint32(b[8:], s.Number)\n\tbinary.BigEndian.PutUint32(b[12:], s.SendingNext)\n\tbinary.BigEndian.PutUint16(b[16:], uint16(s.payload.Len()))\n\tcopy(b[18:], s.payload.Bytes())\n}\n\nfunc (s *DataSegment) ByteSize() int32 {\n\treturn 2 + 1 + 1 + 4 + 4 + 4 + 2 + s.payload.Len()\n}\n\nfunc (s *DataSegment) Release() {\n\ts.payload.Release()\n\ts.payload = nil\n}\n\ntype AckSegment struct {\n\tConv            uint16\n\tOption          SegmentOption\n\tReceivingWindow uint32\n\tReceivingNext   uint32\n\tTimestamp       uint32\n\tNumberList      []uint32\n}\n\nconst ackNumberLimit = 128\n\nfunc NewAckSegment() *AckSegment {\n\treturn new(AckSegment)\n}\n\nfunc (s *AckSegment) parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte) {\n\ts.Conv = conv\n\ts.Option = opt\n\tif len(buf) < 13 {\n\t\treturn false, nil\n\t}\n\n\ts.ReceivingWindow = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\ts.ReceivingNext = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\ts.Timestamp = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\tcount := int(buf[0])\n\tbuf = buf[1:]\n\n\tif len(buf) < count*4 {\n\t\treturn false, nil\n\t}\n\tfor i := 0; i < count; i++ {\n\t\ts.PutNumber(binary.BigEndian.Uint32(buf))\n\t\tbuf = buf[4:]\n\t}\n\n\treturn true, buf\n}\n\nfunc (s *AckSegment) Conversation() uint16 {\n\treturn s.Conv\n}\n\nfunc (*AckSegment) Command() Command {\n\treturn CommandACK\n}\n\nfunc (s *AckSegment) PutTimestamp(timestamp uint32) {\n\tif timestamp-s.Timestamp < 0x7FFFFFFF {\n\t\ts.Timestamp = timestamp\n\t}\n}\n\nfunc (s *AckSegment) PutNumber(number uint32) {\n\ts.NumberList = append(s.NumberList, number)\n}\n\nfunc (s *AckSegment) IsFull() bool {\n\treturn len(s.NumberList) == ackNumberLimit\n}\n\nfunc (s *AckSegment) IsEmpty() bool {\n\treturn len(s.NumberList) == 0\n}\n\nfunc (s *AckSegment) ByteSize() int32 {\n\treturn 2 + 1 + 1 + 4 + 4 + 4 + 1 + int32(len(s.NumberList)*4)\n}\n\nfunc (s *AckSegment) Serialize(b []byte) {\n\tbinary.BigEndian.PutUint16(b, s.Conv)\n\tb[2] = byte(CommandACK)\n\tb[3] = byte(s.Option)\n\tbinary.BigEndian.PutUint32(b[4:], s.ReceivingWindow)\n\tbinary.BigEndian.PutUint32(b[8:], s.ReceivingNext)\n\tbinary.BigEndian.PutUint32(b[12:], s.Timestamp)\n\tb[16] = byte(len(s.NumberList))\n\tn := 17\n\tfor _, number := range s.NumberList {\n\t\tbinary.BigEndian.PutUint32(b[n:], number)\n\t\tn += 4\n\t}\n}\n\nfunc (s *AckSegment) Release() {}\n\ntype CmdOnlySegment struct {\n\tConv          uint16\n\tCmd           Command\n\tOption        SegmentOption\n\tSendingNext   uint32\n\tReceivingNext uint32\n\tPeerRTO       uint32\n}\n\nfunc NewCmdOnlySegment() *CmdOnlySegment {\n\treturn new(CmdOnlySegment)\n}\n\nfunc (s *CmdOnlySegment) parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte) {\n\ts.Conv = conv\n\ts.Cmd = cmd\n\ts.Option = opt\n\n\tif len(buf) < 12 {\n\t\treturn false, nil\n\t}\n\n\ts.SendingNext = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\ts.ReceivingNext = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\ts.PeerRTO = binary.BigEndian.Uint32(buf)\n\tbuf = buf[4:]\n\n\treturn true, buf\n}\n\nfunc (s *CmdOnlySegment) Conversation() uint16 {\n\treturn s.Conv\n}\n\nfunc (s *CmdOnlySegment) Command() Command {\n\treturn s.Cmd\n}\n\nfunc (*CmdOnlySegment) ByteSize() int32 {\n\treturn 2 + 1 + 1 + 4 + 4 + 4\n}\n\nfunc (s *CmdOnlySegment) Serialize(b []byte) {\n\tbinary.BigEndian.PutUint16(b, s.Conv)\n\tb[2] = byte(s.Cmd)\n\tb[3] = byte(s.Option)\n\tbinary.BigEndian.PutUint32(b[4:], s.SendingNext)\n\tbinary.BigEndian.PutUint32(b[8:], s.ReceivingNext)\n\tbinary.BigEndian.PutUint32(b[12:], s.PeerRTO)\n}\n\nfunc (*CmdOnlySegment) Release() {}\n\nfunc ReadSegment(buf []byte) (Segment, []byte) {\n\tif len(buf) < 4 {\n\t\treturn nil, nil\n\t}\n\n\tconv := binary.BigEndian.Uint16(buf)\n\tbuf = buf[2:]\n\n\tcmd := Command(buf[0])\n\topt := SegmentOption(buf[1])\n\tbuf = buf[2:]\n\n\tvar seg Segment\n\tswitch cmd {\n\tcase CommandData:\n\t\tseg = NewDataSegment()\n\tcase CommandACK:\n\t\tseg = NewAckSegment()\n\tdefault:\n\t\tseg = NewCmdOnlySegment()\n\t}\n\n\tvalid, extra := seg.parse(conv, cmd, opt, buf)\n\tif !valid {\n\t\treturn nil, nil\n\t}\n\treturn seg, extra\n}\n"
  },
  {
    "path": "transport/internet/kcp/segment_test.go",
    "content": "package kcp_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n)\n\nfunc TestBadSegment(t *testing.T) {\n\tseg, buf := ReadSegment(nil)\n\tif seg != nil {\n\t\tt.Error(\"non-nil seg\")\n\t}\n\tif len(buf) != 0 {\n\t\tt.Error(\"buf len: \", len(buf))\n\t}\n}\n\nfunc TestDataSegment(t *testing.T) {\n\tseg := &DataSegment{\n\t\tConv:        1,\n\t\tTimestamp:   3,\n\t\tNumber:      4,\n\t\tSendingNext: 5,\n\t}\n\tseg.Data().Write([]byte{'a', 'b', 'c', 'd'})\n\n\tnBytes := seg.ByteSize()\n\tbytes := make([]byte, nBytes)\n\tseg.Serialize(bytes)\n\n\tiseg, _ := ReadSegment(bytes)\n\tseg2 := iseg.(*DataSegment)\n\tif r := cmp.Diff(seg2, seg, cmpopts.IgnoreUnexported(DataSegment{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\tif r := cmp.Diff(seg2.Data().Bytes(), seg.Data().Bytes()); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc Test1ByteDataSegment(t *testing.T) {\n\tseg := &DataSegment{\n\t\tConv:        1,\n\t\tTimestamp:   3,\n\t\tNumber:      4,\n\t\tSendingNext: 5,\n\t}\n\tseg.Data().WriteByte('a')\n\n\tnBytes := seg.ByteSize()\n\tbytes := make([]byte, nBytes)\n\tseg.Serialize(bytes)\n\n\tiseg, _ := ReadSegment(bytes)\n\tseg2 := iseg.(*DataSegment)\n\tif r := cmp.Diff(seg2, seg, cmpopts.IgnoreUnexported(DataSegment{})); r != \"\" {\n\t\tt.Error(r)\n\t}\n\tif r := cmp.Diff(seg2.Data().Bytes(), seg.Data().Bytes()); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestACKSegment(t *testing.T) {\n\tseg := &AckSegment{\n\t\tConv:            1,\n\t\tReceivingWindow: 2,\n\t\tReceivingNext:   3,\n\t\tTimestamp:       10,\n\t\tNumberList:      []uint32{1, 3, 5, 7, 9},\n\t}\n\n\tnBytes := seg.ByteSize()\n\tbytes := make([]byte, nBytes)\n\tseg.Serialize(bytes)\n\n\tiseg, _ := ReadSegment(bytes)\n\tseg2 := iseg.(*AckSegment)\n\tif r := cmp.Diff(seg2, seg); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestCmdSegment(t *testing.T) {\n\tseg := &CmdOnlySegment{\n\t\tConv:          1,\n\t\tCmd:           CommandPing,\n\t\tOption:        SegmentOptionClose,\n\t\tSendingNext:   11,\n\t\tReceivingNext: 13,\n\t\tPeerRTO:       15,\n\t}\n\n\tnBytes := seg.ByteSize()\n\tbytes := make([]byte, nBytes)\n\tseg.Serialize(bytes)\n\n\tiseg, _ := ReadSegment(bytes)\n\tseg2 := iseg.(*CmdOnlySegment)\n\tif r := cmp.Diff(seg2, seg); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/kcp/sending.go",
    "content": "package kcp\n\nimport (\n\t\"container/list\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\ntype SendingWindow struct {\n\tcache             *list.List\n\ttotalInFlightSize uint32\n\twriter            SegmentWriter\n\tonPacketLoss      func(uint32)\n}\n\nfunc NewSendingWindow(writer SegmentWriter, onPacketLoss func(uint32)) *SendingWindow {\n\twindow := &SendingWindow{\n\t\tcache:        list.New(),\n\t\twriter:       writer,\n\t\tonPacketLoss: onPacketLoss,\n\t}\n\treturn window\n}\n\nfunc (sw *SendingWindow) Release() {\n\tif sw == nil {\n\t\treturn\n\t}\n\tfor sw.cache.Len() > 0 {\n\t\tseg := sw.cache.Front().Value.(*DataSegment)\n\t\tseg.Release()\n\t\tsw.cache.Remove(sw.cache.Front())\n\t}\n}\n\nfunc (sw *SendingWindow) Len() uint32 {\n\treturn uint32(sw.cache.Len())\n}\n\nfunc (sw *SendingWindow) IsEmpty() bool {\n\treturn sw.cache.Len() == 0\n}\n\nfunc (sw *SendingWindow) Push(number uint32, b *buf.Buffer) {\n\tseg := NewDataSegment()\n\tseg.Number = number\n\tseg.payload = b\n\n\tsw.cache.PushBack(seg)\n}\n\nfunc (sw *SendingWindow) FirstNumber() uint32 {\n\treturn sw.cache.Front().Value.(*DataSegment).Number\n}\n\nfunc (sw *SendingWindow) Clear(una uint32) {\n\tfor !sw.IsEmpty() {\n\t\tseg := sw.cache.Front().Value.(*DataSegment)\n\t\tif seg.Number >= una {\n\t\t\tbreak\n\t\t}\n\t\tseg.Release()\n\t\tsw.cache.Remove(sw.cache.Front())\n\t}\n}\n\nfunc (sw *SendingWindow) HandleFastAck(number uint32, rto uint32) {\n\tif sw.IsEmpty() {\n\t\treturn\n\t}\n\n\tsw.Visit(func(seg *DataSegment) bool {\n\t\tif number == seg.Number || number-seg.Number > 0x7FFFFFFF {\n\t\t\treturn false\n\t\t}\n\n\t\tif seg.transmit > 0 && seg.timeout > rto/3 {\n\t\t\tseg.timeout -= rto / 3\n\t\t}\n\t\treturn true\n\t})\n}\n\nfunc (sw *SendingWindow) Visit(visitor func(seg *DataSegment) bool) {\n\tif sw.IsEmpty() {\n\t\treturn\n\t}\n\n\tfor e := sw.cache.Front(); e != nil; e = e.Next() {\n\t\tseg := e.Value.(*DataSegment)\n\t\tif !visitor(seg) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (sw *SendingWindow) Flush(current uint32, rto uint32, maxInFlightSize uint32) {\n\tif sw.IsEmpty() {\n\t\treturn\n\t}\n\n\tvar lost uint32\n\tvar inFlightSize uint32\n\n\tsw.Visit(func(segment *DataSegment) bool {\n\t\tif current-segment.timeout >= 0x7FFFFFFF {\n\t\t\treturn true\n\t\t}\n\t\tif segment.transmit == 0 {\n\t\t\t// First time\n\t\t\tsw.totalInFlightSize++\n\t\t} else {\n\t\t\tlost++\n\t\t}\n\t\tsegment.timeout = current + rto\n\n\t\tsegment.Timestamp = current\n\t\tsegment.transmit++\n\t\tsw.writer.Write(segment)\n\t\tinFlightSize++\n\t\treturn inFlightSize < maxInFlightSize\n\t})\n\n\tif sw.onPacketLoss != nil && inFlightSize > 0 && sw.totalInFlightSize != 0 {\n\t\trate := lost * 100 / sw.totalInFlightSize\n\t\tsw.onPacketLoss(rate)\n\t}\n}\n\nfunc (sw *SendingWindow) Remove(number uint32) bool {\n\tif sw.IsEmpty() {\n\t\treturn false\n\t}\n\n\tfor e := sw.cache.Front(); e != nil; e = e.Next() {\n\t\tseg := e.Value.(*DataSegment)\n\t\tif seg.Number > number {\n\t\t\treturn false\n\t\t} else if seg.Number == number {\n\t\t\tif sw.totalInFlightSize > 0 {\n\t\t\t\tsw.totalInFlightSize--\n\t\t\t}\n\t\t\tseg.Release()\n\t\t\tsw.cache.Remove(e)\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype SendingWorker struct {\n\tsync.RWMutex\n\tconn                       *Connection\n\twindow                     *SendingWindow\n\tfirstUnacknowledged        uint32\n\tnextNumber                 uint32\n\tremoteNextNumber           uint32\n\tcontrolWindow              uint32\n\tfastResend                 uint32\n\twindowSize                 uint32\n\tfirstUnacknowledgedUpdated bool\n\tclosed                     bool\n}\n\nfunc NewSendingWorker(kcp *Connection) *SendingWorker {\n\tworker := &SendingWorker{\n\t\tconn:             kcp,\n\t\tfastResend:       2,\n\t\tremoteNextNumber: 32,\n\t\tcontrolWindow:    kcp.Config.GetSendingInFlightSize(),\n\t\twindowSize:       kcp.Config.GetSendingBufferSize(),\n\t}\n\tworker.window = NewSendingWindow(worker, worker.OnPacketLoss)\n\treturn worker\n}\n\nfunc (w *SendingWorker) Release() {\n\tw.Lock()\n\tw.window.Release()\n\tw.closed = true\n\tw.Unlock()\n}\n\nfunc (w *SendingWorker) ProcessReceivingNext(nextNumber uint32) {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tw.ProcessReceivingNextWithoutLock(nextNumber)\n}\n\nfunc (w *SendingWorker) ProcessReceivingNextWithoutLock(nextNumber uint32) {\n\tw.window.Clear(nextNumber)\n\tw.FindFirstUnacknowledged()\n}\n\nfunc (w *SendingWorker) FindFirstUnacknowledged() {\n\tfirst := w.firstUnacknowledged\n\tif !w.window.IsEmpty() {\n\t\tw.firstUnacknowledged = w.window.FirstNumber()\n\t} else {\n\t\tw.firstUnacknowledged = w.nextNumber\n\t}\n\tif first != w.firstUnacknowledged {\n\t\tw.firstUnacknowledgedUpdated = true\n\t}\n}\n\nfunc (w *SendingWorker) processAck(number uint32) bool {\n\t// number < v.firstUnacknowledged || number >= v.nextNumber\n\tif number-w.firstUnacknowledged > 0x7FFFFFFF || number-w.nextNumber < 0x7FFFFFFF {\n\t\treturn false\n\t}\n\n\tremoved := w.window.Remove(number)\n\tif removed {\n\t\tw.FindFirstUnacknowledged()\n\t}\n\treturn removed\n}\n\nfunc (w *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint32) {\n\tdefer seg.Release()\n\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif w.closed {\n\t\treturn\n\t}\n\n\tif w.remoteNextNumber < seg.ReceivingWindow {\n\t\tw.remoteNextNumber = seg.ReceivingWindow\n\t}\n\tw.ProcessReceivingNextWithoutLock(seg.ReceivingNext)\n\n\tif seg.IsEmpty() {\n\t\treturn\n\t}\n\n\tvar maxack uint32\n\tvar maxackRemoved bool\n\tfor _, number := range seg.NumberList {\n\t\tremoved := w.processAck(number)\n\t\tif maxack < number {\n\t\t\tmaxack = number\n\t\t\tmaxackRemoved = removed\n\t\t}\n\t}\n\n\tif maxackRemoved {\n\t\tw.window.HandleFastAck(maxack, rto)\n\t\tif current-seg.Timestamp < 10000 {\n\t\t\tw.conn.roundTrip.Update(current-seg.Timestamp, current)\n\t\t}\n\t}\n}\n\nfunc (w *SendingWorker) Push(b *buf.Buffer) bool {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tif w.closed {\n\t\treturn false\n\t}\n\n\tif w.window.Len() > w.windowSize {\n\t\treturn false\n\t}\n\n\tw.window.Push(w.nextNumber, b)\n\tw.nextNumber++\n\treturn true\n}\n\nfunc (w *SendingWorker) Write(seg Segment) error {\n\tdataSeg := seg.(*DataSegment)\n\n\tdataSeg.Conv = w.conn.meta.Conversation\n\tdataSeg.SendingNext = w.firstUnacknowledged\n\tdataSeg.Option = 0\n\tif w.conn.State() == StateReadyToClose {\n\t\tdataSeg.Option = SegmentOptionClose\n\t}\n\n\treturn w.conn.output.Write(dataSeg)\n}\n\nfunc (w *SendingWorker) OnPacketLoss(lossRate uint32) {\n\tif !w.conn.Config.Congestion || w.conn.roundTrip.Timeout() == 0 {\n\t\treturn\n\t}\n\n\tif lossRate >= 15 {\n\t\tw.controlWindow = 3 * w.controlWindow / 4\n\t} else if lossRate <= 5 {\n\t\tw.controlWindow += w.controlWindow / 4\n\t}\n\tif w.controlWindow < 16 {\n\t\tw.controlWindow = 16\n\t}\n\tif w.controlWindow > 2*w.conn.Config.GetSendingInFlightSize() {\n\t\tw.controlWindow = 2 * w.conn.Config.GetSendingInFlightSize()\n\t}\n}\n\nfunc (w *SendingWorker) Flush(current uint32) {\n\tw.Lock()\n\n\tif w.closed {\n\t\tw.Unlock()\n\t\treturn\n\t}\n\n\tcwnd := w.conn.Config.GetSendingInFlightSize()\n\tif cwnd > w.remoteNextNumber-w.firstUnacknowledged {\n\t\tcwnd = w.remoteNextNumber - w.firstUnacknowledged\n\t}\n\tif w.conn.Config.Congestion && cwnd > w.controlWindow {\n\t\tcwnd = w.controlWindow\n\t}\n\n\tcwnd *= 20 // magic\n\n\tif !w.window.IsEmpty() {\n\t\tw.window.Flush(current, w.conn.roundTrip.Timeout(), cwnd)\n\t\tw.firstUnacknowledgedUpdated = false\n\t}\n\n\tupdated := w.firstUnacknowledgedUpdated\n\tw.firstUnacknowledgedUpdated = false\n\n\tw.Unlock()\n\n\tif updated {\n\t\tw.conn.Ping(current, CommandPing)\n\t}\n}\n\nfunc (w *SendingWorker) CloseWrite() {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tw.window.Clear(0xFFFFFFFF)\n}\n\nfunc (w *SendingWorker) IsEmpty() bool {\n\tw.RLock()\n\tdefer w.RUnlock()\n\n\treturn w.window.IsEmpty()\n}\n\nfunc (w *SendingWorker) UpdateNecessary() bool {\n\treturn !w.IsEmpty()\n}\n\nfunc (w *SendingWorker) FirstUnacknowledged() uint32 {\n\tw.RLock()\n\tdefer w.RUnlock()\n\n\treturn w.firstUnacknowledged\n}\n"
  },
  {
    "path": "transport/internet/kcp/xor.go",
    "content": "//go:build !amd64\n// +build !amd64\n\npackage kcp\n\n// xorfwd performs XOR forwards in words, x[i] ^= x[i-4], i from 0 to len\nfunc xorfwd(x []byte) {\n\tfor i := 4; i < len(x); i++ {\n\t\tx[i] ^= x[i-4]\n\t}\n}\n\n// xorbkd performs XOR backwords in words, x[i] ^= x[i-4], i from len to 0\nfunc xorbkd(x []byte) {\n\tfor i := len(x) - 1; i >= 4; i-- {\n\t\tx[i] ^= x[i-4]\n\t}\n}\n"
  },
  {
    "path": "transport/internet/kcp/xor_amd64.go",
    "content": "package kcp\n\n//go:noescape\nfunc xorfwd(x []byte)\n\n//go:noescape\nfunc xorbkd(x []byte)\n"
  },
  {
    "path": "transport/internet/kcp/xor_amd64.s",
    "content": "#include \"textflag.h\"\n\n// func xorfwd(x []byte)\nTEXT ·xorfwd(SB),NOSPLIT,$0\n  MOVQ x+0(FP), SI  // x[i]\n  MOVQ x_len+8(FP), CX  // x.len\n  MOVQ x+0(FP), DI\n  ADDQ $4, DI       // x[i+4]\n  SUBQ $4, CX\nxorfwdloop:\n  MOVL (SI), AX\n  XORL AX, (DI)\n  ADDQ $4, SI\n  ADDQ $4, DI\n  SUBQ $4, CX\n\n  CMPL CX, $0\n  JE xorfwddone\n\n  JMP xorfwdloop\nxorfwddone:        \n  RET\n\n// func xorbkd(x []byte)\nTEXT ·xorbkd(SB),NOSPLIT,$0\n  MOVQ x+0(FP), SI\n  MOVQ x_len+8(FP), CX  // x.len\n  MOVQ x+0(FP), DI\n  ADDQ CX, SI       // x[-8]\n  SUBQ $8, SI\n  ADDQ CX, DI       // x[-4]\n  SUBQ $4, DI\n  SUBQ $4, CX\nxorbkdloop:\n  MOVL (SI), AX\n  XORL AX, (DI)\n  SUBQ $4, SI\n  SUBQ $4, DI\n  SUBQ $4, CX\n\n  CMPL CX, $0\n  JE xorbkddone\n  \n  JMP xorbkdloop\n\nxorbkddone:        \n  RET\n"
  },
  {
    "path": "transport/internet/memory_settings.go",
    "content": "package internet\n\n// MemoryStreamConfig is a parsed form of StreamConfig. This is used to reduce number of Protobuf parsing.\ntype MemoryStreamConfig struct {\n\tProtocolName     string\n\tProtocolSettings interface{}\n\tSecurityType     string\n\tSecuritySettings interface{}\n\tSocketSettings   *SocketConfig\n}\n\n// ToMemoryStreamConfig converts a StreamConfig to MemoryStreamConfig. It returns a default non-nil MemoryStreamConfig for nil input.\nfunc ToMemoryStreamConfig(s *StreamConfig) (*MemoryStreamConfig, error) {\n\tets, err := s.GetEffectiveTransportSettings()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmss := &MemoryStreamConfig{\n\t\tProtocolName:     s.GetEffectiveProtocol(),\n\t\tProtocolSettings: ets,\n\t}\n\n\tif s != nil {\n\t\tmss.SocketSettings = s.SocketSettings\n\t}\n\n\tif s != nil && s.HasSecuritySettings() {\n\t\tess, err := s.GetEffectiveSecuritySettings()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmss.SecurityType = s.SecurityType\n\t\tmss.SecuritySettings = ess\n\t}\n\n\treturn mss, nil\n}\n"
  },
  {
    "path": "transport/internet/quic/config.go",
    "content": "package quic\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/sha256\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc getAuth(config *Config) (cipher.AEAD, error) {\n\tsecurity := config.Security.GetSecurityType()\n\tif security == protocol.SecurityType_NONE {\n\t\treturn nil, nil\n\t}\n\n\tsalted := []byte(config.Key + \"v2ray-quic-salt\")\n\tkey := sha256.Sum256(salted)\n\n\tif security == protocol.SecurityType_AES128_GCM {\n\t\tblock, err := aes.NewCipher(key[:16])\n\t\tcommon.Must(err)\n\t\treturn cipher.NewGCM(block)\n\t}\n\n\tif security == protocol.SecurityType_CHACHA20_POLY1305 {\n\t\treturn chacha20poly1305.New(key[:])\n\t}\n\n\treturn nil, newError(\"unsupported security type\")\n}\n\nfunc getHeader(config *Config) (internet.PacketHeader, error) {\n\tif config.Header == nil {\n\t\treturn nil, nil\n\t}\n\n\tmsg, err := serial.GetInstanceOf(config.Header)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn internet.CreatePacketHeader(msg)\n}\n"
  },
  {
    "path": "transport/internet/quic/config.pb.go",
    "content": "package quic\n\nimport (\n\tprotocol \"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState   `protogen:\"open.v1\"`\n\tKey           string                   `protobuf:\"bytes,1,opt,name=key,proto3\" json:\"key,omitempty\"`\n\tSecurity      *protocol.SecurityConfig `protobuf:\"bytes,2,opt,name=security,proto3\" json:\"security,omitempty\"`\n\tHeader        *anypb.Any               `protobuf:\"bytes,3,opt,name=header,proto3\" json:\"header,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_quic_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_quic_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_quic_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetKey() string {\n\tif x != nil {\n\t\treturn x.Key\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetSecurity() *protocol.SecurityConfig {\n\tif x != nil {\n\t\treturn x.Security\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetHeader() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_quic_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_quic_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"$transport/internet/quic/config.proto\\x12\\\"v2ray.core.transport.internet.quic\\x1a\\x19google/protobuf/any.proto\\x1a\\x1dcommon/protocol/headers.proto\\x1a common/protoext/extensions.proto\\\"\\xa7\\x01\\n\" +\n\t\"\\x06Config\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12F\\n\" +\n\t\"\\bsecurity\\x18\\x02 \\x01(\\v2*.v2ray.core.common.protocol.SecurityConfigR\\bsecurity\\x12,\\n\" +\n\t\"\\x06header\\x18\\x03 \\x01(\\v2\\x14.google.protobuf.AnyR\\x06header:\\x15\\x82\\xb5\\x18\\x11\\n\" +\n\t\"\\ttransport\\x12\\x04quicB\\x87\\x01\\n\" +\n\t\"&com.v2ray.core.transport.internet.quicP\\x01Z6github.com/v2fly/v2ray-core/v5/transport/internet/quic\\xaa\\x02\\\"V2Ray.Core.Transport.Internet.Quicb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_quic_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_quic_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_quic_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_quic_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_quic_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_quic_config_proto_rawDesc), len(file_transport_internet_quic_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_quic_config_proto_rawDescData\n}\n\nvar file_transport_internet_quic_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_quic_config_proto_goTypes = []any{\n\t(*Config)(nil),                  // 0: v2ray.core.transport.internet.quic.Config\n\t(*protocol.SecurityConfig)(nil), // 1: v2ray.core.common.protocol.SecurityConfig\n\t(*anypb.Any)(nil),               // 2: google.protobuf.Any\n}\nvar file_transport_internet_quic_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.quic.Config.security:type_name -> v2ray.core.common.protocol.SecurityConfig\n\t2, // 1: v2ray.core.transport.internet.quic.Config.header:type_name -> google.protobuf.Any\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_quic_config_proto_init() }\nfunc file_transport_internet_quic_config_proto_init() {\n\tif File_transport_internet_quic_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_quic_config_proto_rawDesc), len(file_transport_internet_quic_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_quic_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_quic_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_quic_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_quic_config_proto = out.File\n\tfile_transport_internet_quic_config_proto_goTypes = nil\n\tfile_transport_internet_quic_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/quic/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.quic;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Quic\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/quic\";\noption java_package = \"com.v2ray.core.transport.internet.quic\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\nimport \"common/protocol/headers.proto\";\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"quic\";\n\n  string key = 1;\n  v2ray.core.common.protocol.SecurityConfig security = 2;\n  google.protobuf.Any header = 3;\n}\n"
  },
  {
    "path": "transport/internet/quic/conn.go",
    "content": "package quic\n\nimport (\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype sysConn struct {\n\tconn   *net.UDPConn\n\theader internet.PacketHeader\n\tauth   cipher.AEAD\n}\n\nfunc wrapSysConn(rawConn *net.UDPConn, config *Config) (*sysConn, error) {\n\theader, err := getHeader(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tauth, err := getAuth(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &sysConn{\n\t\tconn:   rawConn,\n\t\theader: header,\n\t\tauth:   auth,\n\t}, nil\n}\n\nvar errInvalidPacket = errors.New(\"invalid packet\")\n\nfunc (c *sysConn) readFromInternal(p []byte) (int, net.Addr, error) {\n\tbuffer := getBuffer()\n\tdefer putBuffer(buffer)\n\n\tnBytes, addr, err := c.conn.ReadFrom(buffer)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\n\tpayload := buffer[:nBytes]\n\tif c.header != nil {\n\t\tif len(payload) <= int(c.header.Size()) {\n\t\t\treturn 0, nil, errInvalidPacket\n\t\t}\n\t\tpayload = payload[c.header.Size():]\n\t}\n\n\tif c.auth == nil {\n\t\tn := copy(p, payload)\n\t\treturn n, addr, nil\n\t}\n\n\tif len(payload) <= c.auth.NonceSize() {\n\t\treturn 0, nil, errInvalidPacket\n\t}\n\n\tnonce := payload[:c.auth.NonceSize()]\n\tpayload = payload[c.auth.NonceSize():]\n\n\tp, err = c.auth.Open(p[:0], nonce, payload, nil)\n\tif err != nil {\n\t\treturn 0, nil, errInvalidPacket\n\t}\n\n\treturn len(p), addr, nil\n}\n\nfunc (c *sysConn) ReadFrom(p []byte) (int, net.Addr, error) {\n\tif c.header == nil && c.auth == nil {\n\t\treturn c.conn.ReadFrom(p)\n\t}\n\n\tfor {\n\t\tn, addr, err := c.readFromInternal(p)\n\t\tif err != nil && err != errInvalidPacket {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tif err == nil {\n\t\t\treturn n, addr, nil\n\t\t}\n\t}\n}\n\nfunc (c *sysConn) WriteTo(p []byte, addr net.Addr) (int, error) {\n\tif c.header == nil && c.auth == nil {\n\t\treturn c.conn.WriteTo(p, addr)\n\t}\n\n\tbuffer := getBuffer()\n\tdefer putBuffer(buffer)\n\n\tpayload := buffer\n\tn := 0\n\tif c.header != nil {\n\t\tc.header.Serialize(payload)\n\t\tn = int(c.header.Size())\n\t}\n\n\tif c.auth == nil {\n\t\tnBytes := copy(payload[n:], p)\n\t\tn += nBytes\n\t} else {\n\t\tnounce := payload[n : n+c.auth.NonceSize()]\n\t\tcommon.Must2(rand.Read(nounce))\n\t\tn += c.auth.NonceSize()\n\t\tpp := c.auth.Seal(payload[:n], nounce, p, nil)\n\t\tn = len(pp)\n\t}\n\n\treturn c.conn.WriteTo(payload[:n], addr)\n}\n\nfunc (c *sysConn) Close() error {\n\treturn c.conn.Close()\n}\n\nfunc (c *sysConn) LocalAddr() net.Addr {\n\treturn c.conn.LocalAddr()\n}\n\nfunc (c *sysConn) SetReadBuffer(bytes int) error {\n\treturn c.conn.SetReadBuffer(bytes)\n}\n\nfunc (c *sysConn) SetWriteBuffer(bytes int) error {\n\treturn c.conn.SetWriteBuffer(bytes)\n}\n\nfunc (c *sysConn) SetDeadline(t time.Time) error {\n\treturn c.conn.SetDeadline(t)\n}\n\nfunc (c *sysConn) SetReadDeadline(t time.Time) error {\n\treturn c.conn.SetReadDeadline(t)\n}\n\nfunc (c *sysConn) SetWriteDeadline(t time.Time) error {\n\treturn c.conn.SetWriteDeadline(t)\n}\n\nfunc (c *sysConn) SyscallConn() (syscall.RawConn, error) {\n\treturn c.conn.SyscallConn()\n}\n\ntype interConn struct {\n\tstream *quic.Stream\n\tlocal  net.Addr\n\tremote net.Addr\n}\n\nfunc (c *interConn) Read(b []byte) (int, error) {\n\treturn c.stream.Read(b)\n}\n\nfunc (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tmb = buf.Compact(mb)\n\tmb, err := buf.WriteMultiBuffer(c, mb)\n\tbuf.ReleaseMulti(mb)\n\treturn err\n}\n\nfunc (c *interConn) Write(b []byte) (int, error) {\n\treturn c.stream.Write(b)\n}\n\nfunc (c *interConn) Close() error {\n\treturn c.stream.Close()\n}\n\nfunc (c *interConn) LocalAddr() net.Addr {\n\treturn c.local\n}\n\nfunc (c *interConn) RemoteAddr() net.Addr {\n\treturn c.remote\n}\n\nfunc (c *interConn) SetDeadline(t time.Time) error {\n\treturn c.stream.SetDeadline(t)\n}\n\nfunc (c *interConn) SetReadDeadline(t time.Time) error {\n\treturn c.stream.SetReadDeadline(t)\n}\n\nfunc (c *interConn) SetWriteDeadline(t time.Time) error {\n\treturn c.stream.SetWriteDeadline(t)\n}\n"
  },
  {
    "path": "transport/internet/quic/dialer.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\ntype connectionContext struct {\n\trawConn *sysConn\n\tconn    *quic.Conn\n}\n\nvar errConnectionClosed = newError(\"connection closed\")\n\nfunc (c *connectionContext) openStream(destAddr net.Addr) (*interConn, error) {\n\tif !isActive(c.conn) {\n\t\treturn nil, errConnectionClosed\n\t}\n\n\tstream, err := c.conn.OpenStream()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconn := &interConn{\n\t\tstream: stream,\n\t\tlocal:  c.conn.LocalAddr(),\n\t\tremote: destAddr,\n\t}\n\n\treturn conn, nil\n}\n\ntype clientConnections struct {\n\taccess  sync.Mutex\n\tconns   map[net.Destination][]*connectionContext\n\tcleanup *task.Periodic\n}\n\nfunc isActive(s *quic.Conn) bool {\n\tselect {\n\tcase <-s.Context().Done():\n\t\treturn false\n\tdefault:\n\t\treturn true\n\t}\n}\n\nfunc removeInactiveConnections(conns []*connectionContext) []*connectionContext {\n\tactiveConnections := make([]*connectionContext, 0, len(conns))\n\tfor _, s := range conns {\n\t\tif isActive(s.conn) {\n\t\t\tactiveConnections = append(activeConnections, s)\n\t\t\tcontinue\n\t\t}\n\t\tif err := s.conn.CloseWithError(0, \"\"); err != nil {\n\t\t\tnewError(\"failed to close connection\").Base(err).WriteToLog()\n\t\t}\n\t\tif err := s.rawConn.Close(); err != nil {\n\t\t\tnewError(\"failed to close raw connection\").Base(err).WriteToLog()\n\t\t}\n\t}\n\n\tif len(activeConnections) < len(conns) {\n\t\treturn activeConnections\n\t}\n\n\treturn conns\n}\n\nfunc openStream(conns []*connectionContext, destAddr net.Addr) *interConn {\n\tfor _, s := range conns {\n\t\tif !isActive(s.conn) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconn, err := s.openStream(destAddr)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\treturn conn\n\t}\n\n\treturn nil\n}\n\nfunc (s *clientConnections) cleanConnections() error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\n\tif len(s.conns) == 0 {\n\t\treturn nil\n\t}\n\n\tnewConnMap := make(map[net.Destination][]*connectionContext)\n\n\tfor dest, conns := range s.conns {\n\t\tconns = removeInactiveConnections(conns)\n\t\tif len(conns) > 0 {\n\t\t\tnewConnMap[dest] = conns\n\t\t}\n\t}\n\n\ts.conns = newConnMap\n\treturn nil\n}\n\nfunc (s *clientConnections) openConnection(destAddr net.Addr, config *Config, tlsConfig *tls.Config, sockopt *internet.SocketConfig) (internet.Connection, error) {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\n\tif s.conns == nil {\n\t\ts.conns = make(map[net.Destination][]*connectionContext)\n\t}\n\n\tdest := net.DestinationFromAddr(destAddr)\n\n\tvar conns []*connectionContext\n\tif s, found := s.conns[dest]; found {\n\t\tconns = s\n\t}\n\n\t{\n\t\tconn := openStream(conns, destAddr)\n\t\tif conn != nil {\n\t\t\treturn conn, nil\n\t\t}\n\t}\n\n\tconns = removeInactiveConnections(conns)\n\n\tnewError(\"dialing QUIC to \", dest).WriteToLog()\n\n\trawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{\n\t\tIP:   []byte{0, 0, 0, 0},\n\t\tPort: 0,\n\t}, sockopt)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tquicConfig := &quic.Config{\n\t\tHandshakeIdleTimeout: time.Second * 8,\n\t\tMaxIdleTimeout:       time.Second * 30,\n\t\tKeepAlivePeriod:      time.Second * 15,\n\t}\n\n\tsysConn, err := wrapSysConn(rawConn.(*net.UDPConn), config)\n\tif err != nil {\n\t\trawConn.Close()\n\t\treturn nil, err\n\t}\n\n\ttr := quic.Transport{\n\t\tConn:               sysConn,\n\t\tConnectionIDLength: 12,\n\t}\n\n\tconn, err := tr.Dial(context.Background(), destAddr, tlsConfig.GetTLSConfig(tls.WithDestination(dest)), quicConfig)\n\tif err != nil {\n\t\tsysConn.Close()\n\t\treturn nil, err\n\t}\n\n\tcontext := &connectionContext{\n\t\tconn:    conn,\n\t\trawConn: sysConn,\n\t}\n\ts.conns[dest] = append(conns, context)\n\treturn context.openStream(destAddr)\n}\n\nvar client clientConnections\n\nfunc init() {\n\tclient.conns = make(map[net.Destination][]*connectionContext)\n\tclient.cleanup = &task.Periodic{\n\t\tInterval: time.Minute,\n\t\tExecute:  client.cleanConnections,\n\t}\n\tcommon.Must(client.cleanup.Start())\n}\n\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\ttlsConfig := tls.ConfigFromStreamSettings(streamSettings)\n\tif tlsConfig == nil {\n\t\ttlsConfig = &tls.Config{\n\t\t\tServerName:    internalDomain,\n\t\t\tAllowInsecure: true,\n\t\t}\n\t}\n\n\tvar destAddr *net.UDPAddr\n\tif dest.Address.Family().IsIP() {\n\t\tdestAddr = &net.UDPAddr{\n\t\t\tIP:   dest.Address.IP(),\n\t\t\tPort: int(dest.Port),\n\t\t}\n\t} else {\n\t\taddr, err := net.ResolveUDPAddr(\"udp\", dest.NetAddr())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdestAddr = addr\n\t}\n\n\tconfig := streamSettings.ProtocolSettings.(*Config)\n\n\treturn client.openConnection(destAddr, config, tlsConfig, streamSettings.SocketSettings)\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n"
  },
  {
    "path": "transport/internet/quic/errors.generated.go",
    "content": "package quic\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/quic/hub.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n// Listener is an internet.Listener that listens for TCP connections.\ntype Listener struct {\n\trawConn  *sysConn\n\tlistener *quic.Listener\n\tdone     *done.Instance\n\taddConn  internet.ConnHandler\n}\n\nfunc (l *Listener) acceptStreams(conn *quic.Conn) {\n\tfor {\n\t\tstream, err := conn.AcceptStream(context.Background())\n\t\tif err != nil {\n\t\t\tnewError(\"failed to accept stream\").Base(err).WriteToLog()\n\t\t\tselect {\n\t\t\tcase <-conn.Context().Done():\n\t\t\t\treturn\n\t\t\tcase <-l.done.Wait():\n\t\t\t\tif err := conn.CloseWithError(0, \"\"); err != nil {\n\t\t\t\t\tnewError(\"failed to close connection\").Base(err).WriteToLog()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\ttime.Sleep(time.Second)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tconn := &interConn{\n\t\t\tstream: stream,\n\t\t\tlocal:  conn.LocalAddr(),\n\t\t\tremote: conn.RemoteAddr(),\n\t\t}\n\n\t\tl.addConn(conn)\n\t}\n}\n\nfunc (l *Listener) keepAccepting() {\n\tfor {\n\t\tconn, err := l.listener.Accept(context.Background())\n\t\tif err != nil {\n\t\t\tnewError(\"failed to accept QUIC connections\").Base(err).WriteToLog()\n\t\t\tif l.done.Done() {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ttime.Sleep(time.Second)\n\t\t\tcontinue\n\t\t}\n\t\tgo l.acceptStreams(conn)\n\t}\n}\n\n// Addr implements internet.Listener.Addr.\nfunc (l *Listener) Addr() net.Addr {\n\treturn l.listener.Addr()\n}\n\n// Close implements internet.Listener.Close.\nfunc (l *Listener) Close() error {\n\tl.done.Close()\n\tl.listener.Close()\n\tl.rawConn.Close()\n\treturn nil\n}\n\n// Listen creates a new Listener based on configurations.\nfunc Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {\n\tif address.Family().IsDomain() {\n\t\treturn nil, newError(\"domain address is not allows for listening quic\")\n\t}\n\n\ttlsConfig := tls.ConfigFromStreamSettings(streamSettings)\n\tif tlsConfig == nil {\n\t\ttlsConfig = &tls.Config{\n\t\t\tCertificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.DNSNames(internalDomain), cert.CommonName(internalDomain)))},\n\t\t}\n\t}\n\n\tconfig := streamSettings.ProtocolSettings.(*Config)\n\trawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{\n\t\tIP:   address.IP(),\n\t\tPort: int(port),\n\t}, streamSettings.SocketSettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tquicConfig := &quic.Config{\n\t\tHandshakeIdleTimeout:  time.Second * 8,\n\t\tMaxIdleTimeout:        time.Second * 45,\n\t\tMaxIncomingStreams:    32,\n\t\tMaxIncomingUniStreams: -1,\n\t\tKeepAlivePeriod:       time.Second * 15,\n\t}\n\n\tconn, err := wrapSysConn(rawConn.(*net.UDPConn), config)\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\ttr := quic.Transport{\n\t\tConn:               conn,\n\t\tConnectionIDLength: 12,\n\t}\n\n\tqListener, err := tr.Listen(tlsConfig.GetTLSConfig(), quicConfig)\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\tlistener := &Listener{\n\t\tdone:     done.New(),\n\t\trawConn:  conn,\n\t\tlistener: qListener,\n\t\taddConn:  handler,\n\t}\n\n\tgo listener.keepAccepting()\n\n\treturn listener, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, Listen))\n}\n"
  },
  {
    "path": "transport/internet/quic/pool.go",
    "content": "package quic\n\nimport (\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/bytespool\"\n)\n\nvar pool *sync.Pool\n\nfunc init() {\n\tpool = bytespool.GetPool(2048)\n}\n\nfunc getBuffer() []byte {\n\treturn pool.Get().([]byte)\n}\n\nfunc putBuffer(p []byte) {\n\tpool.Put(p) // nolint: staticcheck\n}\n"
  },
  {
    "path": "transport/internet/quic/quic.go",
    "content": "package quic\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\n// Here is some modification needs to be done before update quic vendor.\n// * use bytespool in buffer_pool.go\n// * set MaxReceivePacketSize to 1452 - 32 (16 bytes auth, 16 bytes head)\n//\n//\n\nconst (\n\tprotocolName   = \"quic\"\n\tinternalDomain = \"quic.internal.v2fly.org\"\n)\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/quic/quic_test.go",
    "content": "package quic_test\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/headers/wireguard\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/quic\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc TestQuicConnection(t *testing.T) {\n\tport := udp.PickPort()\n\n\tlistener, err := quic.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"quic\",\n\t\tProtocolSettings: &quic.Config{},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tCertificate: []*tls.Certificate{\n\t\t\t\ttls.ParseCertificate(\n\t\t\t\t\tcert.MustGenerate(nil,\n\t\t\t\t\t\tcert.DNSNames(\"www.v2fly.org\"),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tb := buf.New()\n\t\t\tdefer b.Release()\n\n\t\t\tfor {\n\t\t\t\tb.Clear()\n\t\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t\t\t}\n\t\t}()\n\t})\n\tcommon.Must(err)\n\n\tdefer listener.Close()\n\n\ttime.Sleep(time.Second)\n\n\tdctx := context.Background()\n\tconn, err := quic.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"quic\",\n\t\tProtocolSettings: &quic.Config{},\n\t\tSecurityType:     \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tServerName:    \"www.v2fly.org\",\n\t\t\tAllowInsecure: true,\n\t\t},\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst N = 1024\n\tb1 := make([]byte, N)\n\tcommon.Must2(rand.Read(b1))\n\tb2 := buf.New()\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestQuicConnectionWithoutTLS(t *testing.T) {\n\tport := udp.PickPort()\n\n\tlistener, err := quic.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"quic\",\n\t\tProtocolSettings: &quic.Config{},\n\t}, func(conn internet.Connection) {\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tb := buf.New()\n\t\t\tdefer b.Release()\n\n\t\t\tfor {\n\t\t\t\tb.Clear()\n\t\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t\t\t}\n\t\t}()\n\t})\n\tcommon.Must(err)\n\n\tdefer listener.Close()\n\n\ttime.Sleep(time.Second)\n\n\tdctx := context.Background()\n\tconn, err := quic.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"quic\",\n\t\tProtocolSettings: &quic.Config{},\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst N = 1024\n\tb1 := make([]byte, N)\n\tcommon.Must2(rand.Read(b1))\n\tb2 := buf.New()\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestQuicConnectionAuthHeader(t *testing.T) {\n\tport := udp.PickPort()\n\n\tlistener, err := quic.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{\n\t\tProtocolName: \"quic\",\n\t\tProtocolSettings: &quic.Config{\n\t\t\tHeader: serial.ToTypedMessage(&wireguard.WireguardConfig{}),\n\t\t\tKey:    \"abcd\",\n\t\t\tSecurity: &protocol.SecurityConfig{\n\t\t\t\tType: protocol.SecurityType_AES128_GCM,\n\t\t\t},\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tb := buf.New()\n\t\t\tdefer b.Release()\n\n\t\t\tfor {\n\t\t\t\tb.Clear()\n\t\t\t\tif _, err := b.ReadFrom(conn); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcommon.Must2(conn.Write(b.Bytes()))\n\t\t\t}\n\t\t}()\n\t})\n\tcommon.Must(err)\n\n\tdefer listener.Close()\n\n\ttime.Sleep(time.Second)\n\n\tdctx := context.Background()\n\tconn, err := quic.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{\n\t\tProtocolName: \"quic\",\n\t\tProtocolSettings: &quic.Config{\n\t\t\tHeader: serial.ToTypedMessage(&wireguard.WireguardConfig{}),\n\t\t\tKey:    \"abcd\",\n\t\t\tSecurity: &protocol.SecurityConfig{\n\t\t\t\tType: protocol.SecurityType_AES128_GCM,\n\t\t\t},\n\t\t},\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\tconst N = 1024\n\tb1 := make([]byte, N)\n\tcommon.Must2(rand.Read(b1))\n\tb2 := buf.New()\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n\n\tcommon.Must2(conn.Write(b1))\n\n\tb2.Clear()\n\tcommon.Must2(b2.ReadFullFrom(conn, N))\n\tif r := cmp.Diff(b2.Bytes(), b1); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/errors.generated.go",
    "content": "package packetconn\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/packetConn.pb.go",
    "content": "package packetconn\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 ClientConfig struct {\n\tstate                      protoimpl.MessageState `protogen:\"open.v1\"`\n\tUnderlyingTransportSetting *anypb.Any             `protobuf:\"bytes,1,opt,name=underlying_transport_setting,json=underlyingTransportSetting,proto3\" json:\"underlying_transport_setting,omitempty\"`\n\tUnderlyingTransportName    string                 `protobuf:\"bytes,2,opt,name=underlying_transport_name,json=underlyingTransportName,proto3\" json:\"underlying_transport_name,omitempty\"`\n\tMaxWriteDelay              int32                  `protobuf:\"varint,3,opt,name=max_write_delay,json=maxWriteDelay,proto3\" json:\"max_write_delay,omitempty\"`\n\tMaxRequestSize             int32                  `protobuf:\"varint,4,opt,name=max_request_size,json=maxRequestSize,proto3\" json:\"max_request_size,omitempty\"`\n\tPollingIntervalInitial     int32                  `protobuf:\"varint,5,opt,name=polling_interval_initial,json=pollingIntervalInitial,proto3\" json:\"polling_interval_initial,omitempty\"`\n\tunknownFields              protoimpl.UnknownFields\n\tsizeCache                  protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_transport_internet_request_assembler_packetconn_packetConn_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_assembler_packetconn_packetConn_proto_msgTypes[0]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ClientConfig) GetUnderlyingTransportSetting() *anypb.Any {\n\tif x != nil {\n\t\treturn x.UnderlyingTransportSetting\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetUnderlyingTransportName() string {\n\tif x != nil {\n\t\treturn x.UnderlyingTransportName\n\t}\n\treturn \"\"\n}\n\nfunc (x *ClientConfig) GetMaxWriteDelay() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteDelay\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetMaxRequestSize() int32 {\n\tif x != nil {\n\t\treturn x.MaxRequestSize\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetPollingIntervalInitial() int32 {\n\tif x != nil {\n\t\treturn x.PollingIntervalInitial\n\t}\n\treturn 0\n}\n\ntype ServerConfig struct {\n\tstate                          protoimpl.MessageState `protogen:\"open.v1\"`\n\tUnderlyingTransportSetting     *anypb.Any             `protobuf:\"bytes,1,opt,name=underlying_transport_setting,json=underlyingTransportSetting,proto3\" json:\"underlying_transport_setting,omitempty\"`\n\tUnderlyingTransportName        string                 `protobuf:\"bytes,2,opt,name=underlying_transport_name,json=underlyingTransportName,proto3\" json:\"underlying_transport_name,omitempty\"`\n\tMaxWriteSize                   int32                  `protobuf:\"varint,3,opt,name=max_write_size,json=maxWriteSize,proto3\" json:\"max_write_size,omitempty\"`\n\tMaxWriteDurationMs             int32                  `protobuf:\"varint,4,opt,name=max_write_duration_ms,json=maxWriteDurationMs,proto3\" json:\"max_write_duration_ms,omitempty\"`\n\tMaxSimultaneousWriteConnection int32                  `protobuf:\"varint,5,opt,name=max_simultaneous_write_connection,json=maxSimultaneousWriteConnection,proto3\" json:\"max_simultaneous_write_connection,omitempty\"`\n\tPacketWritingBuffer            int32                  `protobuf:\"varint,6,opt,name=packet_writing_buffer,json=packetWritingBuffer,proto3\" json:\"packet_writing_buffer,omitempty\"`\n\tunknownFields                  protoimpl.UnknownFields\n\tsizeCache                      protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_transport_internet_request_assembler_packetconn_packetConn_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_assembler_packetconn_packetConn_proto_msgTypes[1]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ServerConfig) GetUnderlyingTransportSetting() *anypb.Any {\n\tif x != nil {\n\t\treturn x.UnderlyingTransportSetting\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetUnderlyingTransportName() string {\n\tif x != nil {\n\t\treturn x.UnderlyingTransportName\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerConfig) GetMaxWriteSize() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteSize\n\t}\n\treturn 0\n}\n\nfunc (x *ServerConfig) GetMaxWriteDurationMs() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteDurationMs\n\t}\n\treturn 0\n}\n\nfunc (x *ServerConfig) GetMaxSimultaneousWriteConnection() int32 {\n\tif x != nil {\n\t\treturn x.MaxSimultaneousWriteConnection\n\t}\n\treturn 0\n}\n\nfunc (x *ServerConfig) GetPacketWritingBuffer() int32 {\n\tif x != nil {\n\t\treturn x.PacketWritingBuffer\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_request_assembler_packetconn_packetConn_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"@transport/internet/request/assembler/packetconn/packetConn.proto\\x12:v2ray.core.transport.internet.request.assembler.packetconn\\x1a common/protoext/extensions.proto\\x1a\\x19google/protobuf/any.proto\\\"\\xe4\\x02\\n\" +\n\t\"\\fClientConfig\\x12V\\n\" +\n\t\"\\x1cunderlying_transport_setting\\x18\\x01 \\x01(\\v2\\x14.google.protobuf.AnyR\\x1aunderlyingTransportSetting\\x12:\\n\" +\n\t\"\\x19underlying_transport_name\\x18\\x02 \\x01(\\tR\\x17underlyingTransportName\\x12&\\n\" +\n\t\"\\x0fmax_write_delay\\x18\\x03 \\x01(\\x05R\\rmaxWriteDelay\\x12(\\n\" +\n\t\"\\x10max_request_size\\x18\\x04 \\x01(\\x05R\\x0emaxRequestSize\\x128\\n\" +\n\t\"\\x18polling_interval_initial\\x18\\x05 \\x01(\\x05R\\x16pollingIntervalInitial:4\\x82\\xb5\\x180\\n\" +\n\t\"\\\"transport.request.assembler.client\\x12\\n\" +\n\t\"packetconn\\\"\\xb0\\x03\\n\" +\n\t\"\\fServerConfig\\x12V\\n\" +\n\t\"\\x1cunderlying_transport_setting\\x18\\x01 \\x01(\\v2\\x14.google.protobuf.AnyR\\x1aunderlyingTransportSetting\\x12:\\n\" +\n\t\"\\x19underlying_transport_name\\x18\\x02 \\x01(\\tR\\x17underlyingTransportName\\x12$\\n\" +\n\t\"\\x0emax_write_size\\x18\\x03 \\x01(\\x05R\\fmaxWriteSize\\x121\\n\" +\n\t\"\\x15max_write_duration_ms\\x18\\x04 \\x01(\\x05R\\x12maxWriteDurationMs\\x12I\\n\" +\n\t\"!max_simultaneous_write_connection\\x18\\x05 \\x01(\\x05R\\x1emaxSimultaneousWriteConnection\\x122\\n\" +\n\t\"\\x15packet_writing_buffer\\x18\\x06 \\x01(\\x05R\\x13packetWritingBuffer:4\\x82\\xb5\\x180\\n\" +\n\t\"\\\"transport.request.assembler.server\\x12\\n\" +\n\t\"packetconnB\\xcf\\x01\\n\" +\n\t\">com.v2ray.core.transport.internet.request.assembler.packetconnP\\x01ZNgithub.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/packetconn\\xaa\\x02:V2Ray.Core.Transport.Internet.Request.Assembler.Packetconnb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDesc), len(file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDescData\n}\n\nvar file_transport_internet_request_assembler_packetconn_packetConn_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_request_assembler_packetconn_packetConn_proto_goTypes = []any{\n\t(*ClientConfig)(nil), // 0: v2ray.core.transport.internet.request.assembler.packetconn.ClientConfig\n\t(*ServerConfig)(nil), // 1: v2ray.core.transport.internet.request.assembler.packetconn.ServerConfig\n\t(*anypb.Any)(nil),    // 2: google.protobuf.Any\n}\nvar file_transport_internet_request_assembler_packetconn_packetConn_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.transport.internet.request.assembler.packetconn.ClientConfig.underlying_transport_setting:type_name -> google.protobuf.Any\n\t2, // 1: v2ray.core.transport.internet.request.assembler.packetconn.ServerConfig.underlying_transport_setting:type_name -> google.protobuf.Any\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_request_assembler_packetconn_packetConn_proto_init() }\nfunc file_transport_internet_request_assembler_packetconn_packetConn_proto_init() {\n\tif File_transport_internet_request_assembler_packetconn_packetConn_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDesc), len(file_transport_internet_request_assembler_packetconn_packetConn_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_assembler_packetconn_packetConn_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_assembler_packetconn_packetConn_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_assembler_packetconn_packetConn_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_assembler_packetconn_packetConn_proto = out.File\n\tfile_transport_internet_request_assembler_packetconn_packetConn_proto_goTypes = nil\n\tfile_transport_internet_request_assembler_packetconn_packetConn_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/packetConn.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.assembler.packetconn;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.Assembler.Packetconn\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/packetconn\";\noption java_package = \"com.v2ray.core.transport.internet.request.assembler.packetconn\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"google/protobuf/any.proto\";\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.assembler.client\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"packetconn\";\n\n  google.protobuf.Any underlying_transport_setting = 1;\n  string underlying_transport_name = 2;\n\n  int32 max_write_delay = 3;\n  int32 max_request_size = 4;\n  int32 polling_interval_initial = 5;\n}\n\nmessage ServerConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.assembler.server\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"packetconn\";\n\n  google.protobuf.Any underlying_transport_setting = 1;\n  string underlying_transport_name = 2;\n\n  int32 max_write_size = 3;\n  int32 max_write_duration_ms = 4;\n  int32 max_simultaneous_write_connection = 5;\n  int32 packet_writing_buffer = 6;\n}"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/packetbundle.go",
    "content": "package packetconn\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n)\n\nfunc NewPacketBundle() PacketBundle {\n\treturn &packetBundle{}\n}\n\ntype packetBundle struct{}\n\nfunc (p *packetBundle) Overhead() int {\n\treturn 2\n}\n\nfunc (p *packetBundle) WriteToBundle(b []byte, writer io.Writer) (err error) {\n\terr = binary.Write(writer, binary.BigEndian, uint16(len(b)))\n\tif err != nil {\n\t\treturn\n\t}\n\t_, err = writer.Write(b)\n\treturn\n}\n\nfunc (p *packetBundle) ReadFromBundle(writer io.Reader) (b []byte, err error) {\n\tvar length uint16\n\terr = binary.Read(writer, binary.BigEndian, &length)\n\tif err != nil {\n\t\treturn\n\t}\n\tb = make([]byte, length)\n\tn, err := io.ReadFull(writer, b)\n\tif err != nil {\n\t\treturn\n\t}\n\tif n != int(length) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\treturn\n}\n\ntype PacketBundle interface {\n\tOverhead() int\n\tWriteToBundle(b []byte, writer io.Writer) (err error)\n\tReadFromBundle(writer io.Reader) (b []byte, err error)\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/packetconn.go",
    "content": "package packetconn\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/req2packet.go",
    "content": "package packetconn\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/golang-collections/go-datastructures/queue\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\nfunc newRequestToPacketConnClient(ctx context.Context, config *ClientConfig) (*requestToPacketConnClient, error) { //nolint: unparam\n\treturn &requestToPacketConnClient{ctx: ctx, config: config}, nil\n}\n\ntype requestToPacketConnClient struct {\n\tassembly request.TransportClientAssembly\n\tctx      context.Context\n\tconfig   *ClientConfig\n}\n\nfunc (r *requestToPacketConnClient) OnTransportClientAssemblyReady(assembly request.TransportClientAssembly) {\n\tr.assembly = assembly\n}\n\nfunc (r *requestToPacketConnClient) Dial() (io.ReadWriteCloser, error) {\n\tsessionID := make([]byte, 16)\n\t_, err := rand.Read(sessionID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tctxWithCancel, cancel := context.WithCancel(r.ctx)\n\n\tclientSess := &requestToPacketConnClientSession{\n\t\tsessionID:              sessionID,\n\t\tcurrentPollingInterval: int(r.config.PollingIntervalInitial),\n\t\tmaxRequestSize:         int(r.config.MaxRequestSize),\n\t\tmaxWriteDelay:          int(r.config.MaxWriteDelay),\n\t\tassembly:               r.assembly,\n\t\twriterChan:             make(chan []byte, 256),\n\t\treaderChan:             make(chan []byte, 256),\n\t\tctx:                    ctxWithCancel,\n\t\tfinish:                 cancel,\n\t}\n\tgo clientSess.keepRunning()\n\treturn clientSess, nil\n}\n\ntype requestToPacketConnClientSession struct {\n\tsessionID              []byte\n\tcurrentPollingInterval int\n\n\tmaxRequestSize int\n\tmaxWriteDelay  int\n\n\tassembly   request.TransportClientAssembly\n\twriterChan chan []byte\n\treaderChan chan []byte\n\tctx        context.Context\n\tfinish     func()\n\tnextWrite  []byte\n}\n\nfunc (r *requestToPacketConnClientSession) keepRunning() {\n\tfor r.ctx.Err() == nil {\n\t\tr.runOnce()\n\t}\n}\n\nfunc (r *requestToPacketConnClientSession) runOnce() {\n\trequestBody := bytes.NewBuffer(nil)\n\twaitTimer := time.NewTimer(time.Duration(r.currentPollingInterval) * time.Millisecond)\n\tvar seenPacket bool\n\tpacketBundler := NewPacketBundle()\ncopyFromChan:\n\tfor {\n\t\tselect {\n\t\tcase <-r.ctx.Done():\n\t\t\treturn\n\t\tcase <-waitTimer.C:\n\t\t\tbreak copyFromChan\n\t\tcase packet := <-r.writerChan:\n\t\t\tif !seenPacket {\n\t\t\t\tseenPacket = true\n\t\t\t\twaitTimer.Stop()\n\t\t\t\twaitTimer.Reset(time.Duration(r.maxWriteDelay) * time.Millisecond)\n\t\t\t}\n\t\t\tsizeOffset := packetBundler.Overhead() + len(packet)\n\t\t\tif requestBody.Len()+sizeOffset > r.maxRequestSize {\n\t\t\t\tr.nextWrite = packet\n\t\t\t\tbreak copyFromChan\n\t\t\t}\n\t\t\terr := packetBundler.WriteToBundle(packet, requestBody)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to write to bundle\").Base(err).WriteToLog()\n\t\t\t}\n\t\t}\n\t}\n\twaitTimer.Stop()\n\tgo func() {\n\t\treader, writer := io.Pipe()\n\t\tdefer writer.Close()\n\t\tstreamingRespOpt := &pipedStreamingRespOption{writer}\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tif packet, err := packetBundler.ReadFromBundle(reader); err == nil {\n\t\t\t\t\tr.readerChan <- packet\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t\tresp, err := r.assembly.Tripper().RoundTrip(r.ctx, request.Request{Data: requestBody.Bytes(), ConnectionTag: r.sessionID},\n\t\t\tstreamingRespOpt)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to roundtrip\").Base(err).WriteToLog()\n\t\t\tif r.ctx.Err() != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif len(resp.Data) != 0 {\n\t\t\trespReader := bytes.NewReader(resp.Data)\n\t\t\tfor respReader.Len() != 0 {\n\t\t\t\tpacket, err := packetBundler.ReadFromBundle(respReader)\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to read from bundle\").Base(err).WriteToLog()\n\t\t\t\t\tif r.ctx.Err() != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tr.readerChan <- packet\n\t\t\t}\n\t\t}\n\t}()\n}\n\ntype pipedStreamingRespOption struct {\n\twriter *io.PipeWriter\n}\n\nfunc (p *pipedStreamingRespOption) RoundTripperOption() {\n}\n\nfunc (p *pipedStreamingRespOption) GetResponseWriter() io.Writer {\n\treturn p.writer\n}\n\nfunc (r *requestToPacketConnClientSession) Write(p []byte) (n int, err error) {\n\tbuf := make([]byte, len(p))\n\tcopy(buf, p)\n\tselect {\n\tcase <-r.ctx.Done():\n\t\treturn 0, r.ctx.Err()\n\tcase r.writerChan <- buf:\n\t\treturn len(p), nil\n\t}\n}\n\nfunc (r *requestToPacketConnClientSession) Read(p []byte) (n int, err error) {\n\tselect {\n\tcase <-r.ctx.Done():\n\t\treturn 0, r.ctx.Err()\n\tcase buf := <-r.readerChan:\n\t\tcopy(p, buf)\n\t\treturn len(buf), nil\n\t}\n}\n\nfunc (r *requestToPacketConnClientSession) Close() error {\n\tr.finish()\n\treturn nil\n}\n\nfunc newRequestToPacketConnServer(ctx context.Context, config *ServerConfig) *requestToPacketConnServer {\n\treturn &requestToPacketConnServer{\n\t\tsessionMap: sync.Map{},\n\t\tctx:        ctx,\n\t\tconfig:     config,\n\t}\n}\n\ntype requestToPacketConnServer struct {\n\tpacketSessionReceiver request.SessionReceiver\n\n\tsessionMap sync.Map\n\n\tctx    context.Context\n\tconfig *ServerConfig\n}\n\nfunc (r *requestToPacketConnServer) onSessionReceiverReady(sessrecv request.SessionReceiver) {\n\tr.packetSessionReceiver = sessrecv\n}\n\nfunc (r *requestToPacketConnServer) OnRoundTrip(ctx context.Context, req request.Request,\n\topts ...request.RoundTripperOption,\n) (resp request.Response, err error) {\n\tSessionID := req.ConnectionTag\n\tif SessionID == nil {\n\t\treturn request.Response{}, newError(\"nil session id\")\n\t}\n\tsessionID := string(SessionID)\n\tvar session *requestToPacketConnServerSession\n\tsessionAny, found := r.sessionMap.Load(sessionID)\n\tif found {\n\t\tvar ok bool\n\t\tsession, ok = sessionAny.(*requestToPacketConnServerSession)\n\t\tif !ok {\n\t\t\treturn request.Response{}, newError(\"failed to cast session\")\n\t\t}\n\t}\n\tif !found {\n\t\tctxWithFinish, finish := context.WithCancel(ctx)\n\t\tsession = &requestToPacketConnServerSession{\n\t\t\tSessionID:                      SessionID,\n\t\t\twritingConnectionQueue:         queue.New(64),\n\t\t\twriterChan:                     make(chan []byte, int(r.config.PacketWritingBuffer)),\n\t\t\treaderChan:                     make(chan []byte, 256),\n\t\t\tctx:                            ctxWithFinish,\n\t\t\tfinish:                         finish,\n\t\t\tserver:                         r,\n\t\t\tmaxWriteSize:                   int(r.config.MaxWriteSize),\n\t\t\tmaxWriteDuration:               int(r.config.MaxWriteDurationMs),\n\t\t\tmaxSimultaneousWriteConnection: int(r.config.MaxSimultaneousWriteConnection),\n\t\t}\n\t\t_, loaded := r.sessionMap.LoadOrStore(sessionID, session)\n\t\tif !loaded {\n\t\t\terr = r.packetSessionReceiver.OnNewSession(ctx, session)\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn request.Response{}, err\n\t}\n\treturn session.OnRoundTrip(ctx, req, opts...)\n}\n\nfunc (r *requestToPacketConnServer) removeSessionID(sessionID []byte) {\n\tr.sessionMap.Delete(string(sessionID))\n}\n\ntype requestToPacketConnServerSession struct {\n\tSessionID []byte\n\n\twritingConnectionQueue *queue.Queue\n\n\twriterChan chan []byte\n\treaderChan chan []byte\n\tctx        context.Context\n\tfinish     func()\n\tserver     *requestToPacketConnServer\n\n\tmaxWriteSize                   int\n\tmaxWriteDuration               int\n\tmaxSimultaneousWriteConnection int\n}\n\nfunc (r *requestToPacketConnServerSession) Read(p []byte) (n int, err error) {\n\tselect {\n\tcase <-r.ctx.Done():\n\t\treturn 0, r.ctx.Err()\n\tcase buf := <-r.readerChan:\n\t\tcopy(p, buf)\n\t\treturn len(buf), nil\n\t}\n}\n\nvar debugStats struct {\n\tpacketWritten int\n\tpacketDropped int\n}\n\n/*\nvar _ = func() bool {\n\tgo func() {\n\t\tfor {\n\t\t\ttime.Sleep(time.Second)\n\t\t\tnewError(\"packet written: \", debugStats.packetWritten, \" packet dropped: \", debugStats.packetDropped).WriteToLog()\n\t\t}\n\t}()\n\treturn true\n}()*/\n\nfunc (r *requestToPacketConnServerSession) Write(p []byte) (n int, err error) {\n\tbuf := make([]byte, len(p))\n\tcopy(buf, p)\n\tselect {\n\tcase <-r.ctx.Done():\n\t\treturn 0, r.ctx.Err()\n\tcase r.writerChan <- buf:\n\t\tdebugStats.packetWritten++\n\t\treturn len(p), nil\n\tdefault: // This write will be called from global listener's routine, it must not block\n\t\tdebugStats.packetDropped++\n\t\treturn len(p), nil\n\t}\n}\n\nfunc (r *requestToPacketConnServerSession) Close() error {\n\tr.server.removeSessionID(r.SessionID)\n\tr.finish()\n\treturn nil\n}\n\ntype writingConnection struct {\n\tfocus     func()\n\tfinish    func()\n\tfinishCtx context.Context\n}\n\nfunc (r *requestToPacketConnServerSession) OnRoundTrip(ctx context.Context, req request.Request,\n\topts ...request.RoundTripperOption,\n) (resp request.Response, err error) {\n\t// TODO: fix connection graceful close\n\tvar streamingRespWriter io.Writer\n\tvar streamingRespWriterFlusher request.OptionSupportsStreamingResponseExtensionFlusher\n\tfor _, opt := range opts {\n\t\tif streamingRespOpt, ok := opt.(request.OptionSupportsStreamingResponse); ok {\n\t\t\tstreamingRespWriter = streamingRespOpt.GetResponseWriter()\n\t\t\tif streamingRespWriterFlusherOpt, ok := opt.(request.OptionSupportsStreamingResponseExtensionFlusher); ok {\n\t\t\t\tstreamingRespWriterFlusher = streamingRespWriterFlusherOpt\n\t\t\t}\n\t\t}\n\t}\n\tpacketBundler := NewPacketBundle()\n\treqReader := bytes.NewReader(req.Data)\n\tfor reqReader.Len() != 0 {\n\t\tpacket, err := packetBundler.ReadFromBundle(reqReader)\n\t\tif err != nil {\n\t\t\terr = newError(\"failed to read from bundle\").Base(err)\n\t\t\treturn request.Response{}, err\n\t\t}\n\t\tr.readerChan <- packet\n\t}\n\tonFocusCtx, focus := context.WithCancel(ctx)\n\tonFinishCtx, finish := context.WithCancel(ctx)\n\tr.writingConnectionQueue.Put(&writingConnection{\n\t\tfocus:     focus,\n\t\tfinish:    finish,\n\t\tfinishCtx: onFinishCtx,\n\t})\n\n\tamountToEnd := r.writingConnectionQueue.Len() - int64(r.maxSimultaneousWriteConnection)\n\tfor amountToEnd > 0 {\n\t\t{\n\t\t\t_, _ = r.writingConnectionQueue.TakeUntil(func(i interface{}) bool {\n\t\t\t\ti.(*writingConnection).finish()\n\t\t\t\tamountToEnd--\n\t\t\t\treturn amountToEnd > 0\n\t\t\t})\n\t\t}\n\t}\n\n\t{\n\t\t_, _ = r.writingConnectionQueue.TakeUntil(func(i interface{}) bool {\n\t\t\ti.(*writingConnection).focus()\n\t\t\treturn false\n\t\t})\n\t}\n\n\tbufferedRespWriter := bytes.NewBuffer(nil)\n\tfinishWrite := func() {\n\t\tresp.Data = bufferedRespWriter.Bytes()\n\t\t{\n\t\t\t_, _ = r.writingConnectionQueue.TakeUntil(func(i interface{}) bool {\n\t\t\t\ti.(*writingConnection).focus()\n\t\t\t\tif i.(*writingConnection).finishCtx.Err() != nil { //nolint: gosimple\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t})\n\t\t}\n\t}\n\n\tprogressiveSend := streamingRespWriter != nil\n\tvar respWriter io.Writer\n\tif progressiveSend {\n\t\trespWriter = streamingRespWriter\n\t} else {\n\t\trespWriter = bufferedRespWriter\n\t}\n\n\tvar bytesSent int\n\tonReceivePacket := func(packet []byte) bool {\n\t\tbytesSent += len(packet) + packetBundler.Overhead()\n\t\terr := packetBundler.WriteToBundle(packet, respWriter)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to write to bundle\").Base(err).WriteToLog()\n\t\t}\n\t\tif streamingRespWriterFlusher != nil {\n\t\t\tstreamingRespWriterFlusher.Flush()\n\t\t}\n\t\tif bytesSent >= r.maxWriteSize {\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t}\n\n\tfinishWriteTimer := time.NewTimer(time.Millisecond * time.Duration(r.maxWriteDuration))\n\n\tif !progressiveSend {\n\t\tselect {\n\t\tcase <-onFocusCtx.Done():\n\t\tcase <-onFinishCtx.Done():\n\t\t\tfinishWrite()\n\t\t\treturn resp, nil\n\t\t}\n\t} else {\n\t\tselect {\n\t\tcase <-onFinishCtx.Done():\n\t\t\tfinishWrite()\n\t\t\treturn resp, nil\n\t\tdefault:\n\t\t}\n\t}\n\tfirstRead := true\n\tfor {\n\t\tselect {\n\t\tcase <-onFinishCtx.Done():\n\t\t\tfinishWrite()\n\t\t\tfinishWriteTimer.Stop()\n\t\t\treturn resp, nil\n\t\tcase packet := <-r.writerChan:\n\t\t\tkeepSending := onReceivePacket(packet)\n\t\t\tif firstRead {\n\t\t\t\tfirstRead = false\n\t\t\t}\n\t\t\tif !keepSending {\n\t\t\t\tfinishWrite()\n\t\t\t\tfinishWriteTimer.Stop()\n\t\t\t\treturn resp, nil\n\t\t\t}\n\t\tcase <-finishWriteTimer.C:\n\t\t\tfinishWrite()\n\t\t\treturn resp, nil\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/udpassembler.go",
    "content": "package packetconn\n\nimport (\n\t\"golang.org/x/net/context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype wrappedTransportEnvironment struct {\n\tenvironment.TransportEnvironment\n\tclient *requestToPacketConnClient\n\tserver *requestToPacketConnServer\n}\n\nfunc (w *wrappedTransportEnvironment) Listen(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.Listener, error) {\n\treturn nil, newError(\"not implemented\")\n}\n\nfunc (w *wrappedTransportEnvironment) ListenPacket(ctx context.Context, addr net.Addr, sockopt *internet.SocketConfig) (net.PacketConn, error) {\n\tpacketConn := newWrappedPacketConn(ctx)\n\tw.server.onSessionReceiverReady(packetConn)\n\treturn packetConn, nil\n}\n\nfunc (w *wrappedTransportEnvironment) Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *internet.SocketConfig) (net.Conn, error) {\n\tsession, err := w.client.Dial()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newWrappedConn(session), nil\n}\n\nfunc (w *wrappedTransportEnvironment) Dialer() internet.SystemDialer {\n\treturn w\n}\n\nfunc (w *wrappedTransportEnvironment) Listener() internet.SystemListener {\n\treturn w\n}\n\nfunc newUDPAssemblerServerFromConfig(ctx context.Context, config *ServerConfig) (*udpAssemblerServer, error) {\n\tinstance, err := serial.GetInstanceOf(config.UnderlyingTransportSetting)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get instance of underlying transport\").Base(err).AtError()\n\t}\n\tmemcfg := &internet.MemoryStreamConfig{ProtocolName: config.UnderlyingTransportName, ProtocolSettings: instance}\n\treturn newUDPAssemblerServer(ctx, config, memcfg), nil\n}\n\nfunc newUDPAssemblerClientFromConfig(ctx context.Context, config *ClientConfig) (*udpAssemblerClient, error) {\n\tinstance, err := serial.GetInstanceOf(config.UnderlyingTransportSetting)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get instance of underlying transport\").Base(err).AtError()\n\t}\n\tmemcfg := &internet.MemoryStreamConfig{ProtocolName: config.UnderlyingTransportName, ProtocolSettings: instance}\n\treturn newUDPAssemblerClient(ctx, config, memcfg), nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tserverConfig, ok := config.(*ServerConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a ServerConfig\")\n\t\t}\n\t\treturn newUDPAssemblerServerFromConfig(ctx, serverConfig)\n\t}))\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tclientConfig, ok := config.(*ClientConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a ClientConfig\")\n\t\t}\n\t\treturn newUDPAssemblerClientFromConfig(ctx, clientConfig)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/udpassemblerClient.go",
    "content": "package packetconn\n\nimport (\n\t\"io\"\n\tgonet \"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\ntype udpAssemblerClient struct {\n\tctx            context.Context\n\tstreamSettings *internet.MemoryStreamConfig\n\tassembly       request.TransportClientAssembly\n\treq2connc      *requestToPacketConnClient\n}\n\nfunc (u *udpAssemblerClient) NewSession(ctx context.Context, opts ...request.SessionOption) (request.Session, error) {\n\treturn u.dial(net.Destination{})\n}\n\nfunc (u *udpAssemblerClient) OnTransportClientAssemblyReady(assembly request.TransportClientAssembly) {\n\tu.assembly = assembly\n\tu.req2connc.OnTransportClientAssemblyReady(assembly)\n}\n\nfunc newWrappedConn(in io.ReadWriteCloser) net.Conn {\n\treturn wrappedConn{in}\n}\n\ntype wrappedConn struct {\n\tio.ReadWriteCloser\n}\n\nfunc (w wrappedConn) LocalAddr() gonet.Addr {\n\treturn nil\n}\n\nfunc (w wrappedConn) RemoteAddr() gonet.Addr {\n\treturn nil\n}\n\nfunc (w wrappedConn) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (w wrappedConn) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (w wrappedConn) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc newWrappedPacketConn(ctx context.Context) *wrappedPacketConn {\n\tctxWithCancel, cancel := context.WithCancel(ctx)\n\treturn &wrappedPacketConn{\n\t\tconn:     make(map[string]*serverSession),\n\t\treadChan: make(chan packet, 16), ctx: ctxWithCancel, finish: cancel, connLock: &sync.Mutex{},\n\t}\n}\n\nfunc newUDPAssemblerClient(ctx context.Context, config *ClientConfig, streamSettings *internet.MemoryStreamConfig) *udpAssemblerClient {\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\ttransportEnvironmentWrapped := &wrappedTransportEnvironment{TransportEnvironment: transportEnvironment}\n\ttransportEnvironmentWrapped.client, _ = newRequestToPacketConnClient(ctx, config)\n\twrappedContext := envctx.ContextWithEnvironment(ctx, transportEnvironmentWrapped)\n\treturn &udpAssemblerClient{ctx: wrappedContext, streamSettings: streamSettings, req2connc: transportEnvironmentWrapped.client}\n}\n\nfunc (u *udpAssemblerClient) dial(dest net.Destination) (internet.Connection, error) {\n\t_ = dest\n\treturn internet.Dial(u.ctx, net.TCPDestination(net.LocalHostIP, 0), u.streamSettings)\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/packetconn/udpassemblerServer.go",
    "content": "package packetconn\n\nimport (\n\t\"crypto/rand\"\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tnet2 \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\ntype packet struct {\n\taddr string\n\tdata []byte\n}\n\ntype wrappedPacketConn struct {\n\tconnLock *sync.Mutex\n\tconn     map[string]*serverSession\n\n\treadChan chan packet\n\n\tctx    context.Context\n\tfinish func()\n}\n\nfunc (w *wrappedPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {\n\tselect {\n\tcase pack := <-w.readChan:\n\t\tn := copy(p, pack.data)\n\t\tif n < len(pack.data) {\n\t\t\treturn n, nil, io.ErrShortBuffer\n\t\t}\n\t\treturn n, &net.UDPAddr{IP: net2.IP(pack.addr)}, nil\n\tcase <-w.ctx.Done():\n\t\treturn 0, nil, w.ctx.Err()\n\t}\n}\n\nfunc (w *wrappedPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {\n\tw.connLock.Lock()\n\tconn := w.conn[string(addr.(*net.UDPAddr).IP)]\n\tw.connLock.Unlock()\n\treturn conn.Write(p)\n}\n\nfunc (w *wrappedPacketConn) Close() error {\n\tw.finish()\n\treturn nil\n}\n\nfunc (w *wrappedPacketConn) LocalAddr() net.Addr {\n\treturn nil\n}\n\nfunc (w *wrappedPacketConn) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (w *wrappedPacketConn) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (w *wrappedPacketConn) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (w wrappedPacketConn) OnNewSession(ctx context.Context, sess request.Session, opts ...request.SessionOption) error {\n\timaginaryAddr := net2.UDPAddr{\n\t\tIP:   net2.AnyIPv6.IP(),\n\t\tPort: 0,\n\t}\n\trand.Read([]byte(imaginaryAddr.IP))\n\tsession := newServerSession(ctx, sess, string(imaginaryAddr.IP), &w)\n\tw.connLock.Lock()\n\tw.conn[string(imaginaryAddr.IP)] = session\n\tw.connLock.Unlock()\n\tsession.start()\n\treturn nil\n}\n\nfunc newServerSession(ctx context.Context, sess request.Session, name string, listener *wrappedPacketConn) *serverSession {\n\t_ = ctx\n\treturn &serverSession{session: sess, name: name, listener: listener}\n}\n\ntype serverSession struct {\n\tname     string\n\tsession  request.Session\n\tlistener *wrappedPacketConn\n}\n\nfunc (s *serverSession) start() {\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-s.listener.ctx.Done():\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tbuf := make([]byte, 2000)\n\t\t\t\tn, err := s.session.Read(buf)\n\t\t\t\tif err != nil || n > 2000 {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ts.listener.readChan <- packet{s.name, buf[:n]}\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc (s *serverSession) Write(p []byte) (int, error) {\n\treturn s.session.Write(p)\n}\n\ntype udpAssemblerServer struct {\n\tctx            context.Context\n\tstreamSettings *internet.MemoryStreamConfig\n\tassembly       request.TransportServerAssembly\n\treq2packs      *requestToPacketConnServer\n\tlistener       internet.Listener\n}\n\nfunc (u *udpAssemblerServer) Start() error {\n\tlistener, err := u.listen(net2.LocalHostIP, 0)\n\tif err != nil {\n\t\treturn newError(\"failed to listen\").Base(err).AtError()\n\t}\n\tu.listener = listener\n\treturn nil\n}\n\nfunc (u *udpAssemblerServer) Close() error {\n\treturn u.listener.Close()\n}\n\nfunc (u *udpAssemblerServer) OnRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\treturn u.req2packs.OnRoundTrip(ctx, req, opts...)\n}\n\nfunc (u *udpAssemblerServer) OnTransportServerAssemblyReady(assembly request.TransportServerAssembly) {\n\tu.assembly = assembly\n}\n\nfunc newUDPAssemblerServer(ctx context.Context, config *ServerConfig, streamSettings *internet.MemoryStreamConfig) *udpAssemblerServer {\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\ttransportEnvironmentWrapped := &wrappedTransportEnvironment{TransportEnvironment: transportEnvironment}\n\ttransportEnvironmentWrapped.server = newRequestToPacketConnServer(ctx, config)\n\twrappedContext := envctx.ContextWithEnvironment(ctx, transportEnvironmentWrapped)\n\treturn &udpAssemblerServer{ctx: wrappedContext, streamSettings: streamSettings, req2packs: transportEnvironmentWrapped.server}\n}\n\nfunc (u *udpAssemblerServer) listen(address net2.Address, port net2.Port) (internet.Listener, error) {\n\treturn internet.ListenTCP(u.ctx, address, port, u.streamSettings, func(connection internet.Connection) {\n\t\terr := u.assembly.SessionReceiver().OnNewSession(u.ctx, connection)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to handle new session\").Base(err).WriteToLog()\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/simple/client.go",
    "content": "package simple\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\nfunc newClient(config *ClientConfig) request.SessionAssemblerClient {\n\treturn &simpleAssemblerClient{config: config}\n}\n\ntype simpleAssemblerClient struct {\n\tassembly request.TransportClientAssembly\n\tconfig   *ClientConfig\n}\n\nfunc (s *simpleAssemblerClient) OnTransportClientAssemblyReady(assembly request.TransportClientAssembly) {\n\ts.assembly = assembly\n}\n\nfunc (s *simpleAssemblerClient) NewSession(ctx context.Context, opts ...request.SessionOption) (request.Session, error) {\n\tsessionID := make([]byte, 16)\n\t_, err := io.ReadFull(rand.Reader, sessionID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsessionContext, finish := context.WithCancel(ctx)\n\tsession := &simpleAssemblerClientSession{\n\t\tsessionID: sessionID, tripper: s.assembly.Tripper(), readBuffer: bytes.NewBuffer(nil),\n\t\tctx: sessionContext, finish: finish, writerChan: make(chan []byte), readerChan: make(chan []byte, 16), assembler: s,\n\t}\n\tgo session.keepRunning()\n\treturn session, nil\n}\n\ntype simpleAssemblerClientSession struct {\n\tsessionID        []byte\n\tcurrentWriteWait int\n\n\tassembler  *simpleAssemblerClient\n\ttripper    request.Tripper\n\treadBuffer *bytes.Buffer\n\twriterChan chan []byte\n\treaderChan chan []byte\n\tctx        context.Context\n\tfinish     func()\n}\n\nfunc (s *simpleAssemblerClientSession) keepRunning() {\n\ts.currentWriteWait = int(s.assembler.config.InitialPollingIntervalMs)\n\tfor s.ctx.Err() == nil {\n\t\ts.runOnce()\n\t}\n}\n\nfunc (s *simpleAssemblerClientSession) runOnce() {\n\tsendBuffer := bytes.NewBuffer(nil)\n\tif s.currentWriteWait != 0 {\n\t\twaitTimer := time.NewTimer(time.Millisecond * time.Duration(s.currentWriteWait))\n\t\twaitForFirstWrite := true\n\tcopyFromWriterLoop:\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-s.ctx.Done():\n\t\t\t\treturn\n\t\t\tcase data := <-s.writerChan:\n\t\t\t\tsendBuffer.Write(data)\n\t\t\t\tif sendBuffer.Len() >= int(s.assembler.config.MaxWriteSize) {\n\t\t\t\t\tbreak copyFromWriterLoop\n\t\t\t\t}\n\t\t\t\tif waitForFirstWrite {\n\t\t\t\t\twaitForFirstWrite = false\n\t\t\t\t\twaitTimer.Reset(time.Millisecond * time.Duration(s.assembler.config.WaitSubsequentWriteMs))\n\t\t\t\t}\n\t\t\tcase <-waitTimer.C:\n\t\t\t\tbreak copyFromWriterLoop\n\t\t\t}\n\t\t}\n\t\twaitTimer.Stop()\n\t}\n\n\tfirstRound := true\n\tpollConnection := true\n\tfor sendBuffer.Len() != 0 || firstRound {\n\t\tfirstRound = false\n\t\tsendAmount := sendBuffer.Len()\n\t\tif sendAmount > int(s.assembler.config.MaxWriteSize) {\n\t\t\tsendAmount = int(s.assembler.config.MaxWriteSize)\n\t\t}\n\t\tdata := sendBuffer.Next(sendAmount)\n\t\tif len(data) != 0 {\n\t\t\tpollConnection = false\n\t\t}\n\t\tfor {\n\t\t\tresp, err := s.tripper.RoundTrip(s.ctx, request.Request{Data: data, ConnectionTag: s.sessionID})\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to send data\").Base(err).WriteToLog()\n\t\t\t\tif s.ctx.Err() != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttime.Sleep(time.Millisecond * time.Duration(s.assembler.config.FailedRetryIntervalMs))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif len(resp.Data) != 0 {\n\t\t\t\ts.readerChan <- resp.Data\n\t\t\t}\n\t\t\tif len(resp.Data) != 0 {\n\t\t\t\tpollConnection = false\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\tif pollConnection {\n\t\ts.currentWriteWait = int(s.assembler.config.BackoffFactor * float32(s.currentWriteWait))\n\t\tif s.currentWriteWait > int(s.assembler.config.MaxPollingIntervalMs) {\n\t\t\ts.currentWriteWait = int(s.assembler.config.MaxPollingIntervalMs)\n\t\t}\n\t\tif s.currentWriteWait < int(s.assembler.config.MinPollingIntervalMs) {\n\t\t\ts.currentWriteWait = int(s.assembler.config.MinPollingIntervalMs)\n\t\t}\n\t} else {\n\t\ts.currentWriteWait = int(0)\n\t}\n}\n\nfunc (s *simpleAssemblerClientSession) Read(p []byte) (n int, err error) {\n\tif s.readBuffer.Len() == 0 {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn 0, s.ctx.Err()\n\t\tcase data := <-s.readerChan:\n\t\t\ts.readBuffer.Write(data)\n\t\t}\n\t}\n\tn, err = s.readBuffer.Read(p)\n\tif err == io.EOF {\n\t\ts.readBuffer.Reset()\n\t\treturn 0, nil\n\t}\n\treturn\n}\n\nfunc (s *simpleAssemblerClientSession) Write(p []byte) (n int, err error) {\n\tbuf := make([]byte, len(p))\n\tcopy(buf, p)\n\tselect {\n\tcase <-s.ctx.Done():\n\t\treturn 0, s.ctx.Err()\n\tcase s.writerChan <- buf:\n\t\treturn len(p), nil\n\t}\n}\n\nfunc (s *simpleAssemblerClientSession) Close() error {\n\ts.finish()\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tclientConfig, ok := config.(*ClientConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a ClientConfig\")\n\t\t}\n\t\treturn newClient(clientConfig), nil\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/simple/config.pb.go",
    "content": "package simple\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ClientConfig struct {\n\tstate                    protoimpl.MessageState `protogen:\"open.v1\"`\n\tMaxWriteSize             int32                  `protobuf:\"varint,1,opt,name=max_write_size,json=maxWriteSize,proto3\" json:\"max_write_size,omitempty\"`\n\tWaitSubsequentWriteMs    int32                  `protobuf:\"varint,2,opt,name=wait_subsequent_write_ms,json=waitSubsequentWriteMs,proto3\" json:\"wait_subsequent_write_ms,omitempty\"`\n\tInitialPollingIntervalMs int32                  `protobuf:\"varint,3,opt,name=initial_polling_interval_ms,json=initialPollingIntervalMs,proto3\" json:\"initial_polling_interval_ms,omitempty\"`\n\tMaxPollingIntervalMs     int32                  `protobuf:\"varint,4,opt,name=max_polling_interval_ms,json=maxPollingIntervalMs,proto3\" json:\"max_polling_interval_ms,omitempty\"`\n\tMinPollingIntervalMs     int32                  `protobuf:\"varint,5,opt,name=min_polling_interval_ms,json=minPollingIntervalMs,proto3\" json:\"min_polling_interval_ms,omitempty\"`\n\tBackoffFactor            float32                `protobuf:\"fixed32,6,opt,name=backoff_factor,json=backoffFactor,proto3\" json:\"backoff_factor,omitempty\"`\n\tFailedRetryIntervalMs    int32                  `protobuf:\"varint,7,opt,name=failed_retry_interval_ms,json=failedRetryIntervalMs,proto3\" json:\"failed_retry_interval_ms,omitempty\"`\n\tunknownFields            protoimpl.UnknownFields\n\tsizeCache                protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_transport_internet_request_assembler_simple_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_assembler_simple_config_proto_msgTypes[0]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_assembler_simple_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ClientConfig) GetMaxWriteSize() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteSize\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetWaitSubsequentWriteMs() int32 {\n\tif x != nil {\n\t\treturn x.WaitSubsequentWriteMs\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetInitialPollingIntervalMs() int32 {\n\tif x != nil {\n\t\treturn x.InitialPollingIntervalMs\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetMaxPollingIntervalMs() int32 {\n\tif x != nil {\n\t\treturn x.MaxPollingIntervalMs\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetMinPollingIntervalMs() int32 {\n\tif x != nil {\n\t\treturn x.MinPollingIntervalMs\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetBackoffFactor() float32 {\n\tif x != nil {\n\t\treturn x.BackoffFactor\n\t}\n\treturn 0\n}\n\nfunc (x *ClientConfig) GetFailedRetryIntervalMs() int32 {\n\tif x != nil {\n\t\treturn x.FailedRetryIntervalMs\n\t}\n\treturn 0\n}\n\ntype ServerConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tMaxWriteSize  int32                  `protobuf:\"varint,1,opt,name=max_write_size,json=maxWriteSize,proto3\" json:\"max_write_size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_transport_internet_request_assembler_simple_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_assembler_simple_config_proto_msgTypes[1]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_assembler_simple_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ServerConfig) GetMaxWriteSize() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteSize\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_request_assembler_simple_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_assembler_simple_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"8transport/internet/request/assembler/simple/config.proto\\x126v2ray.core.transport.internet.request.assembler.simple\\x1a common/protoext/extensions.proto\\\"\\xac\\x03\\n\" +\n\t\"\\fClientConfig\\x12$\\n\" +\n\t\"\\x0emax_write_size\\x18\\x01 \\x01(\\x05R\\fmaxWriteSize\\x127\\n\" +\n\t\"\\x18wait_subsequent_write_ms\\x18\\x02 \\x01(\\x05R\\x15waitSubsequentWriteMs\\x12=\\n\" +\n\t\"\\x1binitial_polling_interval_ms\\x18\\x03 \\x01(\\x05R\\x18initialPollingIntervalMs\\x125\\n\" +\n\t\"\\x17max_polling_interval_ms\\x18\\x04 \\x01(\\x05R\\x14maxPollingIntervalMs\\x125\\n\" +\n\t\"\\x17min_polling_interval_ms\\x18\\x05 \\x01(\\x05R\\x14minPollingIntervalMs\\x12%\\n\" +\n\t\"\\x0ebackoff_factor\\x18\\x06 \\x01(\\x02R\\rbackoffFactor\\x127\\n\" +\n\t\"\\x18failed_retry_interval_ms\\x18\\a \\x01(\\x05R\\x15failedRetryIntervalMs:0\\x82\\xb5\\x18,\\n\" +\n\t\"\\\"transport.request.assembler.client\\x12\\x06simple\\\"f\\n\" +\n\t\"\\fServerConfig\\x12$\\n\" +\n\t\"\\x0emax_write_size\\x18\\x01 \\x01(\\x05R\\fmaxWriteSize:0\\x82\\xb5\\x18,\\n\" +\n\t\"\\\"transport.request.assembler.server\\x12\\x06simpleB\\xc3\\x01\\n\" +\n\t\":com.v2ray.core.transport.internet.request.assembler.simpleP\\x01ZJgithub.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/simple\\xaa\\x026V2Ray.Core.Transport.Internet.Request.Assembler.Simpleb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_assembler_simple_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_assembler_simple_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_assembler_simple_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_assembler_simple_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_assembler_simple_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_assembler_simple_config_proto_rawDesc), len(file_transport_internet_request_assembler_simple_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_assembler_simple_config_proto_rawDescData\n}\n\nvar file_transport_internet_request_assembler_simple_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_request_assembler_simple_config_proto_goTypes = []any{\n\t(*ClientConfig)(nil), // 0: v2ray.core.transport.internet.request.assembler.simple.ClientConfig\n\t(*ServerConfig)(nil), // 1: v2ray.core.transport.internet.request.assembler.simple.ServerConfig\n}\nvar file_transport_internet_request_assembler_simple_config_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_transport_internet_request_assembler_simple_config_proto_init() }\nfunc file_transport_internet_request_assembler_simple_config_proto_init() {\n\tif File_transport_internet_request_assembler_simple_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_assembler_simple_config_proto_rawDesc), len(file_transport_internet_request_assembler_simple_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_assembler_simple_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_assembler_simple_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_assembler_simple_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_assembler_simple_config_proto = out.File\n\tfile_transport_internet_request_assembler_simple_config_proto_goTypes = nil\n\tfile_transport_internet_request_assembler_simple_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/simple/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.assembler.simple;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.Assembler.Simple\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/simple\";\noption java_package = \"com.v2ray.core.transport.internet.request.assembler.simple\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.assembler.client\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"simple\";\n\n  int32 max_write_size = 1;\n  int32 wait_subsequent_write_ms = 2;\n  int32 initial_polling_interval_ms = 3;\n  int32 max_polling_interval_ms = 4;\n  int32 min_polling_interval_ms = 5;\n  float backoff_factor = 6;\n  int32 failed_retry_interval_ms = 7;\n}\n\nmessage ServerConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.assembler.server\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"simple\";\n\n  int32 max_write_size = 1;\n}"
  },
  {
    "path": "transport/internet/request/assembler/simple/errors.generated.go",
    "content": "package simple\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/simple/server.go",
    "content": "package simple\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\nfunc newServer(config *ServerConfig) request.SessionAssemblerServer {\n\treturn &simpleAssemblerServer{}\n}\n\ntype simpleAssemblerServer struct {\n\tsessions sync.Map\n\tassembly request.TransportServerAssembly\n}\n\nfunc (s *simpleAssemblerServer) OnTransportServerAssemblyReady(assembly request.TransportServerAssembly) {\n\ts.assembly = assembly\n}\n\nfunc (s *simpleAssemblerServer) OnRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption,\n) (resp request.Response, err error) {\n\tconnectionID := req.ConnectionTag\n\tsession := newSimpleAssemblerServerSession(ctx)\n\tloadedSession, loaded := s.sessions.LoadOrStore(string(connectionID), session)\n\tif loaded {\n\t\tsession = loadedSession.(*simpleAssemblerServerSession)\n\t} else {\n\t\tif err := s.assembly.SessionReceiver().OnNewSession(ctx, session); err != nil {\n\t\t\treturn request.Response{}, newError(\"failed to create new session\").Base(err)\n\t\t}\n\t}\n\treturn session.OnRoundTrip(ctx, req, opts...)\n}\n\nfunc newSimpleAssemblerServerSession(ctx context.Context) *simpleAssemblerServerSession {\n\tsessionCtx, finish := context.WithCancel(ctx)\n\treturn &simpleAssemblerServerSession{\n\t\treadBuffer:       bytes.NewBuffer(nil),\n\t\treadChan:         make(chan []byte, 16),\n\t\trequestProcessed: make(chan struct{}),\n\t\twriteLock:        new(sync.Mutex),\n\t\twriteBuffer:      bytes.NewBuffer(nil),\n\t\tmaxWriteSize:     4096,\n\t\tctx:              sessionCtx,\n\t\tfinish:           finish,\n\t}\n}\n\ntype simpleAssemblerServerSession struct {\n\tmaxWriteSize int\n\n\treadBuffer       *bytes.Buffer\n\treadChan         chan []byte\n\trequestProcessed chan struct{}\n\n\twriteLock   *sync.Mutex\n\twriteBuffer *bytes.Buffer\n\n\tctx    context.Context\n\tfinish func()\n}\n\nfunc (s *simpleAssemblerServerSession) Read(p []byte) (n int, err error) {\n\tif s.readBuffer.Len() == 0 {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn 0, s.ctx.Err()\n\t\tcase data := <-s.readChan:\n\t\t\ts.readBuffer.Write(data)\n\t\t}\n\t}\n\treturn s.readBuffer.Read(p)\n}\n\nfunc (s *simpleAssemblerServerSession) Write(p []byte) (n int, err error) {\n\ts.writeLock.Lock()\n\n\tn, err = s.writeBuffer.Write(p)\n\tlength := s.writeBuffer.Len()\n\ts.writeLock.Unlock()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif length > s.maxWriteSize {\n\t\tselect {\n\t\tcase <-s.requestProcessed:\n\t\tcase <-s.ctx.Done():\n\t\t\treturn 0, s.ctx.Err()\n\t\t}\n\t}\n\treturn\n}\n\nfunc (s *simpleAssemblerServerSession) Close() error {\n\ts.finish()\n\treturn nil\n}\n\nfunc (s *simpleAssemblerServerSession) OnRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption,\n) (resp request.Response, err error) {\n\tif len(req.Data) > 0 {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn request.Response{}, s.ctx.Err()\n\t\tcase s.readChan <- req.Data:\n\t\t}\n\t}\n\n\ts.writeLock.Lock()\n\tnextWrite := s.writeBuffer.Next(s.maxWriteSize)\n\tdata := make([]byte, len(nextWrite))\n\tcopy(data, nextWrite)\n\ts.writeLock.Unlock()\n\tselect {\n\tcase s.requestProcessed <- struct{}{}:\n\tcase <-s.ctx.Done():\n\t\treturn request.Response{}, s.ctx.Err()\n\tdefault:\n\t}\n\treturn request.Response{Data: data}, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tserverConfig, ok := config.(*ServerConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a SimpleServerConfig\")\n\t\t}\n\t\treturn newServer(serverConfig), nil\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/request/assembler/simple/simple.go",
    "content": "package simple\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/request/assembler.go",
    "content": "package request\n\nimport (\n\t\"io\"\n)\n\ntype SessionAssemblerClient interface {\n\tSessionCreator\n\tTransportClientAssemblyReceiver\n}\ntype SessionAssemblerServer interface {\n\tTripperReceiver\n\tTransportServerAssemblyReceiver\n}\n\ntype SessionOption interface {\n\tRoundTripperOption()\n}\n\ntype Session interface {\n\tio.ReadWriteCloser\n}\n"
  },
  {
    "path": "transport/internet/request/assembly/assembly.go",
    "content": "package assembly\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst protocolName = \"request\"\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn nil, newError(\"request is a transport protocol.\")\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/request/assembly/config.pb.go",
    "content": "package assembly\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tAssembler     *anypb.Any             `protobuf:\"bytes,1,opt,name=assembler,proto3\" json:\"assembler,omitempty\"`\n\tRoundtripper  *anypb.Any             `protobuf:\"bytes,2,opt,name=roundtripper,proto3\" json:\"roundtripper,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_request_assembly_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_assembly_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_assembly_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetAssembler() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Assembler\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetRoundtripper() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Roundtripper\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_request_assembly_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_assembly_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"0transport/internet/request/assembly/config.proto\\x12.v2ray.core.transport.internet.request.assembly\\x1a common/protoext/extensions.proto\\x1a\\x19google/protobuf/any.proto\\\"\\x90\\x01\\n\" +\n\t\"\\x06Config\\x122\\n\" +\n\t\"\\tassembler\\x18\\x01 \\x01(\\v2\\x14.google.protobuf.AnyR\\tassembler\\x128\\n\" +\n\t\"\\froundtripper\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\froundtripper:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\ttransport\\x12\\arequestB\\xab\\x01\\n\" +\n\t\"2com.v2ray.core.transport.internet.request.assemblyP\\x01ZBgithub.com/v2fly/v2ray-core/v5/transport/internet/request/assembly\\xaa\\x02.V2Ray.Core.Transport.Internet.Request.Assemblyb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_assembly_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_assembly_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_assembly_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_assembly_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_assembly_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_assembly_config_proto_rawDesc), len(file_transport_internet_request_assembly_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_assembly_config_proto_rawDescData\n}\n\nvar file_transport_internet_request_assembly_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_request_assembly_config_proto_goTypes = []any{\n\t(*Config)(nil),    // 0: v2ray.core.transport.internet.request.assembly.Config\n\t(*anypb.Any)(nil), // 1: google.protobuf.Any\n}\nvar file_transport_internet_request_assembly_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.request.assembly.Config.assembler:type_name -> google.protobuf.Any\n\t1, // 1: v2ray.core.transport.internet.request.assembly.Config.roundtripper:type_name -> google.protobuf.Any\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_request_assembly_config_proto_init() }\nfunc file_transport_internet_request_assembly_config_proto_init() {\n\tif File_transport_internet_request_assembly_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_assembly_config_proto_rawDesc), len(file_transport_internet_request_assembly_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_assembly_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_assembly_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_assembly_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_assembly_config_proto = out.File\n\tfile_transport_internet_request_assembly_config_proto_goTypes = nil\n\tfile_transport_internet_request_assembly_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/assembly/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.assembly;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.Assembly\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembly\";\noption java_package = \"com.v2ray.core.transport.internet.request.assembly\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"google/protobuf/any.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"request\";\n\n  google.protobuf.Any assembler = 1;\n  google.protobuf.Any roundtripper = 2;\n}"
  },
  {
    "path": "transport/internet/request/assembly/dialer.go",
    "content": "package assembly\n\nimport (\n\t\"context\"\n\tgonet \"net\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\ntype client struct {\n\ttripper   request.RoundTripperClient\n\tassembler request.SessionAssemblerClient\n\n\tstreamSettings *internet.MemoryStreamConfig\n\tdest           net.Destination\n}\n\nfunc (c client) Dial(ctx context.Context) (net.Conn, error) {\n\treturn transportcommon.DialWithSecuritySettings(ctx, c.dest, c.streamSettings)\n}\n\nfunc (c client) AutoImplDialer() request.Dialer {\n\treturn c\n}\n\nfunc (c client) Tripper() request.Tripper {\n\treturn c.tripper\n}\n\nfunc (c client) dialRequestSession(ctx context.Context) (net.Conn, error) {\n\tsession, err := c.assembler.NewSession(ctx)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create new session\").Base(err)\n\t}\n\treturn clientConnection{session}, nil\n}\n\ntype clientConnection struct {\n\trequest.Session\n}\n\nfunc (c clientConnection) LocalAddr() gonet.Addr {\n\treturn &net.UnixAddr{Name: \"unimplemented\"}\n}\n\nfunc (c clientConnection) RemoteAddr() gonet.Addr {\n\treturn &net.UnixAddr{Name: \"unimplemented\"}\n}\n\nfunc (c clientConnection) SetDeadline(t time.Time) error {\n\t// Unimplemented\n\treturn nil\n}\n\nfunc (c clientConnection) SetReadDeadline(t time.Time) error {\n\t// Unimplemented\n\treturn nil\n}\n\nfunc (c clientConnection) SetWriteDeadline(t time.Time) error {\n\t// Unimplemented\n\treturn nil\n}\n\nfunc dialRequest(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {\n\tclientAssembly := &client{}\n\ttransportConfiguration := streamSettings.ProtocolSettings.(*Config)\n\n\tassemblerConfigInstance, err := serial.GetInstanceOf(transportConfiguration.Assembler)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get config instance of assembler\").Base(err)\n\t}\n\tassembler, err := common.CreateObject(ctx, assemblerConfigInstance)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create assembler\").Base(err)\n\t}\n\tif typedAssembler, ok := assembler.(request.SessionAssemblerClient); !ok {\n\t\treturn nil, newError(\"failed to type assert assembler to SessionAssemblerClient\")\n\t} else {\n\t\tclientAssembly.assembler = typedAssembler\n\t}\n\n\troundtripperConfigInstance, err := serial.GetInstanceOf(transportConfiguration.Roundtripper)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get config instance of roundtripper\").Base(err)\n\t}\n\troundtripper, err := common.CreateObject(ctx, roundtripperConfigInstance)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create roundtripper\").Base(err)\n\t}\n\tif typedRoundtripper, ok := roundtripper.(request.RoundTripperClient); !ok {\n\t\treturn nil, newError(\"failed to type assert roundtripper to RoundTripperClient\")\n\t} else {\n\t\tclientAssembly.tripper = typedRoundtripper\n\t}\n\n\tclientAssembly.streamSettings = streamSettings\n\tclientAssembly.dest = dest\n\n\tclientAssembly.assembler.OnTransportClientAssemblyReady(clientAssembly)\n\tclientAssembly.tripper.OnTransportClientAssemblyReady(clientAssembly)\n\treturn clientAssembly.dialRequestSession(ctx)\n}\n\nfunc dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tnewError(\"creating connection to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tconn, err := dialRequest(ctx, dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial request to \", dest).Base(err)\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, dial))\n}\n"
  },
  {
    "path": "transport/internet/request/assembly/errors.generated.go",
    "content": "package assembly\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/assembly/hub.go",
    "content": "package assembly\n\nimport (\n\t\"context\"\n\tgonet \"net\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\ntype server struct {\n\ttripper   request.RoundTripperServer\n\tassembler request.SessionAssemblerServer\n\taddConn   internet.ConnHandler\n\n\tstreamSettings *internet.MemoryStreamConfig\n\taddr           net.Address\n\tport           net.Port\n}\n\nfunc (s server) Listen(ctx context.Context) (net.Listener, error) {\n\treturn transportcommon.ListenWithSecuritySettings(ctx, s.addr, s.port, s.streamSettings)\n}\n\nfunc (s server) AutoImplListener() request.Listener {\n\treturn s\n}\n\nfunc (s server) Close() error {\n\tif err := s.tripper.Close(); err != nil {\n\t\treturn newError(\"failed to close tripper\").Base(err)\n\t}\n\tif runnableAssembler, ok := s.assembler.(common.Runnable); ok {\n\t\tif err := runnableAssembler.Close(); err != nil {\n\t\t\treturn newError(\"failed to close assembler\").Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s server) Addr() net.Addr {\n\t// Unimplemented\n\treturn nil\n}\n\ntype serverConnection struct {\n\trequest.Session\n}\n\nfunc (s serverConnection) LocalAddr() gonet.Addr {\n\treturn &net.UnixAddr{Name: \"unimplemented\"}\n}\n\nfunc (s serverConnection) RemoteAddr() gonet.Addr {\n\treturn &net.UnixAddr{Name: \"unimplemented\"}\n}\n\nfunc (s serverConnection) SetDeadline(t time.Time) error {\n\t// Unimplemented\n\treturn nil\n}\n\nfunc (s serverConnection) SetReadDeadline(t time.Time) error {\n\t// Unimplemented\n\treturn nil\n}\n\nfunc (s serverConnection) SetWriteDeadline(t time.Time) error {\n\t// Unimplemented\n\treturn nil\n}\n\nfunc (s server) OnNewSession(ctx context.Context, sess request.Session, opts ...request.SessionOption) error {\n\ts.addConn(&serverConnection{sess})\n\treturn nil\n}\n\nfunc (s server) SessionReceiver() request.SessionReceiver {\n\treturn s\n}\n\nfunc (s server) TripperReceiver() request.TripperReceiver {\n\treturn s.assembler\n}\n\nfunc listenRequest(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {\n\ttransportConfiguration := streamSettings.ProtocolSettings.(*Config)\n\tserverAssembly := &server{addConn: addConn}\n\n\tassemblerConfigInstance, err := serial.GetInstanceOf(transportConfiguration.Assembler)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get config instance of assembler\").Base(err)\n\t}\n\tassembler, err := common.CreateObject(ctx, assemblerConfigInstance)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create assembler\").Base(err)\n\t}\n\tif typedAssembler, ok := assembler.(request.SessionAssemblerServer); !ok {\n\t\treturn nil, newError(\"failed to type assert assembler to SessionAssemblerServer\")\n\t} else {\n\t\tserverAssembly.assembler = typedAssembler\n\t}\n\n\troundtripperConfigInstance, err := serial.GetInstanceOf(transportConfiguration.Roundtripper)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get config instance of roundtripper\").Base(err)\n\t}\n\troundtripper, err := common.CreateObject(ctx, roundtripperConfigInstance)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create roundtripper\").Base(err)\n\t}\n\tif typedRoundtripper, ok := roundtripper.(request.RoundTripperServer); !ok {\n\t\treturn nil, newError(\"failed to type assert roundtripper to RoundTripperServer\")\n\t} else {\n\t\tserverAssembly.tripper = typedRoundtripper\n\t}\n\n\tserverAssembly.addr = address\n\tserverAssembly.port = port\n\tserverAssembly.streamSettings = streamSettings\n\n\tserverAssembly.assembler.OnTransportServerAssemblyReady(serverAssembly)\n\tserverAssembly.tripper.OnTransportServerAssemblyReady(serverAssembly)\n\n\tif err := serverAssembly.tripper.Start(); err != nil {\n\t\treturn nil, newError(\"failed to start tripper\").Base(err)\n\t}\n\n\tif runnableAssembler, ok := serverAssembly.assembler.(common.Runnable); ok {\n\t\tif err := runnableAssembler.Start(); err != nil {\n\t\t\treturn nil, newError(\"failed to start assembler\").Base(err)\n\t\t}\n\t}\n\n\treturn serverAssembly, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, listenRequest))\n}\n"
  },
  {
    "path": "transport/internet/request/options.go",
    "content": "package request\n"
  },
  {
    "path": "transport/internet/request/request.go",
    "content": "package request\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype TransportClientAssembly interface {\n\tTripper() Tripper\n\tAutoImplDialer() Dialer\n}\n\ntype TransportClientAssemblyReceiver interface {\n\tOnTransportClientAssemblyReady(TransportClientAssembly)\n}\n\ntype TransportServerAssembly interface {\n\tTripperReceiver() TripperReceiver\n\tSessionReceiver() SessionReceiver\n\tAutoImplListener() Listener\n}\n\ntype TransportServerAssemblyReceiver interface {\n\tOnTransportServerAssemblyReady(TransportServerAssembly)\n}\n\ntype SessionCreator interface {\n\tNewSession(ctx context.Context, opts ...SessionOption) (Session, error)\n}\n\ntype SessionReceiver interface {\n\tOnNewSession(ctx context.Context, sess Session, opts ...SessionOption) error\n}\n\ntype Dialer interface {\n\tDial(ctx context.Context) (net.Conn, error)\n}\n\ntype Listener interface {\n\tListen(ctx context.Context) (net.Listener, error)\n}\n"
  },
  {
    "path": "transport/internet/request/reverser.go",
    "content": "package request\n\nimport \"context\"\n\ntype ReverserImpl interface {\n\tOnOtherRoundTrip(ctx context.Context, req Request, opts ...RoundTripperOption) (resp Response, err error)\n\tOnAuthenticatedServerIntentRoundTrip(ctx context.Context, serverPublic []byte, req Request, opts ...RoundTripperOption) (resp Response, err error)\n}\n\ntype ReverserAccessChecker interface {\n\tCheckReverserAccess(ctx context.Context, serverKey []byte) (clientKey []byte, err error)\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripper/httprt/config.pb.go",
    "content": "package httprt\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ClientConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tHttp          *HTTPConfig            `protobuf:\"bytes,1,opt,name=http,proto3\" json:\"http,omitempty\"`\n\tAllowHttp     bool                   `protobuf:\"varint,2,opt,name=allow_http,json=allowHttp,proto3\" json:\"allow_http,omitempty\"`\n\tH2PoolSize    int32                  `protobuf:\"varint,3,opt,name=h2_pool_size,json=h2PoolSize,proto3\" json:\"h2_pool_size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes[0]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_roundtripper_httprt_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ClientConfig) GetHttp() *HTTPConfig {\n\tif x != nil {\n\t\treturn x.Http\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetAllowHttp() bool {\n\tif x != nil {\n\t\treturn x.AllowHttp\n\t}\n\treturn false\n}\n\nfunc (x *ClientConfig) GetH2PoolSize() int32 {\n\tif x != nil {\n\t\treturn x.H2PoolSize\n\t}\n\treturn 0\n}\n\ntype ServerConfig struct {\n\tstate                protoimpl.MessageState `protogen:\"open.v1\"`\n\tHttp                 *HTTPConfig            `protobuf:\"bytes,1,opt,name=http,proto3\" json:\"http,omitempty\"`\n\tNoDecodingSessionTag bool                   `protobuf:\"varint,2,opt,name=no_decoding_session_tag,json=noDecodingSessionTag,proto3\" json:\"no_decoding_session_tag,omitempty\"`\n\tunknownFields        protoimpl.UnknownFields\n\tsizeCache            protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes[1]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_roundtripper_httprt_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ServerConfig) GetHttp() *HTTPConfig {\n\tif x != nil {\n\t\treturn x.Http\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetNoDecodingSessionTag() bool {\n\tif x != nil {\n\t\treturn x.NoDecodingSessionTag\n\t}\n\treturn false\n}\n\ntype HTTPConfig struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tPath          string                 `protobuf:\"bytes,1,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tUrlPrefix     string                 `protobuf:\"bytes,2,opt,name=urlPrefix,proto3\" json:\"urlPrefix,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *HTTPConfig) Reset() {\n\t*x = HTTPConfig{}\n\tmi := &file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *HTTPConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HTTPConfig) ProtoMessage() {}\n\nfunc (x *HTTPConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes[2]\n\tif 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 HTTPConfig.ProtoReflect.Descriptor instead.\nfunc (*HTTPConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_roundtripper_httprt_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *HTTPConfig) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *HTTPConfig) GetUrlPrefix() string {\n\tif x != nil {\n\t\treturn x.UrlPrefix\n\t}\n\treturn \"\"\n}\n\nvar File_transport_internet_request_roundtripper_httprt_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_roundtripper_httprt_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\";transport/internet/request/roundtripper/httprt/config.proto\\x129v2ray.core.transport.internet.request.roundtripper.httprt\\x1a common/protoext/extensions.proto\\\"\\xdf\\x01\\n\" +\n\t\"\\fClientConfig\\x12Y\\n\" +\n\t\"\\x04http\\x18\\x01 \\x01(\\v2E.v2ray.core.transport.internet.request.roundtripper.httprt.HTTPConfigR\\x04http\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"allow_http\\x18\\x02 \\x01(\\bR\\tallowHttp\\x12 \\n\" +\n\t\"\\fh2_pool_size\\x18\\x03 \\x01(\\x05R\\n\" +\n\t\"h2PoolSize:3\\x82\\xb5\\x18/\\n\" +\n\t\"%transport.request.roundtripper.client\\x12\\x06httprt\\\"\\xd5\\x01\\n\" +\n\t\"\\fServerConfig\\x12Y\\n\" +\n\t\"\\x04http\\x18\\x01 \\x01(\\v2E.v2ray.core.transport.internet.request.roundtripper.httprt.HTTPConfigR\\x04http\\x125\\n\" +\n\t\"\\x17no_decoding_session_tag\\x18\\x02 \\x01(\\bR\\x14noDecodingSessionTag:3\\x82\\xb5\\x18/\\n\" +\n\t\"%transport.request.roundtripper.server\\x12\\x06httprt\\\">\\n\" +\n\t\"\\n\" +\n\t\"HTTPConfig\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x01 \\x01(\\tR\\x04path\\x12\\x1c\\n\" +\n\t\"\\turlPrefix\\x18\\x02 \\x01(\\tR\\turlPrefixB\\xcc\\x01\\n\" +\n\t\"=com.v2ray.core.transport.internet.request.roundtripper.httprtP\\x01ZMgithub.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripper/httprt\\xaa\\x029V2Ray.Core.Transport.Internet.Request.Roundtripper.httprtb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_roundtripper_httprt_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_roundtripper_httprt_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_roundtripper_httprt_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_roundtripper_httprt_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_roundtripper_httprt_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_roundtripper_httprt_config_proto_rawDesc), len(file_transport_internet_request_roundtripper_httprt_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_roundtripper_httprt_config_proto_rawDescData\n}\n\nvar file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_transport_internet_request_roundtripper_httprt_config_proto_goTypes = []any{\n\t(*ClientConfig)(nil), // 0: v2ray.core.transport.internet.request.roundtripper.httprt.ClientConfig\n\t(*ServerConfig)(nil), // 1: v2ray.core.transport.internet.request.roundtripper.httprt.ServerConfig\n\t(*HTTPConfig)(nil),   // 2: v2ray.core.transport.internet.request.roundtripper.httprt.HTTPConfig\n}\nvar file_transport_internet_request_roundtripper_httprt_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.transport.internet.request.roundtripper.httprt.ClientConfig.http:type_name -> v2ray.core.transport.internet.request.roundtripper.httprt.HTTPConfig\n\t2, // 1: v2ray.core.transport.internet.request.roundtripper.httprt.ServerConfig.http:type_name -> v2ray.core.transport.internet.request.roundtripper.httprt.HTTPConfig\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_request_roundtripper_httprt_config_proto_init() }\nfunc file_transport_internet_request_roundtripper_httprt_config_proto_init() {\n\tif File_transport_internet_request_roundtripper_httprt_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_roundtripper_httprt_config_proto_rawDesc), len(file_transport_internet_request_roundtripper_httprt_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_roundtripper_httprt_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_roundtripper_httprt_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_roundtripper_httprt_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_roundtripper_httprt_config_proto = out.File\n\tfile_transport_internet_request_roundtripper_httprt_config_proto_goTypes = nil\n\tfile_transport_internet_request_roundtripper_httprt_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripper/httprt/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.roundtripper.httprt;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.Roundtripper.httprt\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripper/httprt\";\noption java_package = \"com.v2ray.core.transport.internet.request.roundtripper.httprt\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage ClientConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.roundtripper.client\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"httprt\";\n\n  HTTPConfig http = 1;\n  bool allow_http = 2;\n  int32 h2_pool_size = 3;\n}\n\nmessage ServerConfig {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.roundtripper.server\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"httprt\";\n  HTTPConfig http = 1;\n  bool no_decoding_session_tag = 2;\n}\n\nmessage HTTPConfig {\n  string path = 1;\n  string urlPrefix = 2;\n}"
  },
  {
    "path": "transport/internet/request/roundtripper/httprt/errors.generated.go",
    "content": "package httprt\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripper/httprt/httprt.go",
    "content": "package httprt\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"io\"\n\tgonet \"net\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\nfunc newHTTPRoundTripperClient(ctx context.Context, config *ClientConfig) request.RoundTripperClient {\n\t_ = ctx\n\treturn &httpTripperClient{config: config}\n}\n\ntype httpTripperClient struct {\n\thttpRTT  http.RoundTripper\n\tconfig   *ClientConfig\n\tassembly request.TransportClientAssembly\n}\n\ntype unimplementedBackDrop struct{}\n\nfunc (u unimplementedBackDrop) RoundTrip(r *http.Request) (*http.Response, error) {\n\treturn nil, newError(\"unimplemented\")\n}\n\nfunc (h *httpTripperClient) OnTransportClientAssemblyReady(assembly request.TransportClientAssembly) {\n\th.assembly = assembly\n}\n\nfunc (h *httpTripperClient) RoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\tvar streamingWriter io.Writer\n\tfor _, v := range opts {\n\t\tif streamingResp, ok := v.(request.OptionSupportsStreamingResponse); ok {\n\t\t\tstreamingWriter = streamingResp.GetResponseWriter()\n\t\t}\n\t}\n\tif h.httpRTT == nil {\n\t\tvar backDrop http.RoundTripper = unimplementedBackDrop{}\n\t\tif h.config.AllowHttp {\n\t\t\tbackDrop = &http.Transport{\n\t\t\t\tDialContext: func(_ context.Context, network, addr string) (gonet.Conn, error) {\n\t\t\t\t\treturn h.assembly.AutoImplDialer().Dial(ctx)\n\t\t\t\t},\n\t\t\t\tDialTLSContext: func(_ context.Context, network, addr string) (gonet.Conn, error) {\n\t\t\t\t\treturn nil, newError(\"unexpected dial of TLS\")\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\th.httpRTT = transportcommon.NewALPNAwareHTTPRoundTripperWithH2Pool(ctx, func(ctx context.Context, addr string) (gonet.Conn, error) {\n\t\t\treturn h.assembly.AutoImplDialer().Dial(ctx)\n\t\t}, backDrop, int(h.config.H2PoolSize))\n\t}\n\n\tconnectionTagStr := base64.RawURLEncoding.EncodeToString(req.ConnectionTag)\n\n\thttpRequest, err := http.NewRequest(\"POST\", h.config.Http.UrlPrefix+h.config.Http.Path, bytes.NewReader(req.Data))\n\tif err != nil {\n\t\treturn resp, err\n\t}\n\n\thttpRequest.Header.Set(\"X-Session-ID\", connectionTagStr)\n\n\thttpResp, err := h.httpRTT.RoundTrip(httpRequest)\n\tif err != nil {\n\t\treturn resp, err\n\t}\n\tdefer httpResp.Body.Close()\n\tif httpResp.StatusCode != http.StatusOK {\n\t\tnewError(\"non-200 response: \", httpResp.Status).AtInfo().WriteToLog()\n\t}\n\tif streamingWriter == nil {\n\t\tresult, err := io.ReadAll(httpResp.Body)\n\t\tif err != nil {\n\t\t\treturn request.Response{}, err\n\t\t}\n\t\treturn request.Response{Data: result}, nil\n\t}\n\t_, err = io.Copy(streamingWriter, httpResp.Body)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"unable to copy response\").Base(err)\n\t}\n\treturn request.Response{}, nil\n}\n\nfunc newHTTPRoundTripperServer(ctx context.Context, config *ServerConfig) request.RoundTripperServer {\n\treturn &httpTripperServer{ctx: ctx, config: config}\n}\n\ntype httpTripperServer struct {\n\tctx      context.Context\n\tlistener net.Listener\n\tassembly request.TransportServerAssembly\n\n\tconfig *ServerConfig\n}\n\nfunc (h *httpTripperServer) OnTransportServerAssemblyReady(assembly request.TransportServerAssembly) {\n\th.assembly = assembly\n}\n\nfunc (h *httpTripperServer) ServeHTTP(writer http.ResponseWriter, r *http.Request) {\n\th.onRequest(writer, r)\n}\n\ntype httpRespStreamWriting struct {\n\tresp http.ResponseWriter\n\tused bool\n}\n\nfunc (h *httpRespStreamWriting) RoundTripperOption() {\n}\n\nfunc (h *httpRespStreamWriting) GetResponseWriter() io.Writer {\n\th.used = true\n\treturn h.resp\n}\n\nfunc (h *httpRespStreamWriting) Flush() {\n\tif f, ok := h.resp.(http.Flusher); ok {\n\t\tf.Flush()\n\t}\n}\n\nfunc (h *httpTripperServer) onRequest(resp http.ResponseWriter, req *http.Request) {\n\ttail := req.Header.Get(\"X-Session-ID\")\n\tdata := []byte(tail)\n\tif !h.config.NoDecodingSessionTag {\n\t\tdecodedData, err := base64.RawURLEncoding.DecodeString(tail)\n\t\tif err != nil {\n\t\t\tnewError(\"unable to decode tag\").Base(err).AtInfo().WriteToLog()\n\t\t\treturn\n\t\t}\n\t\tdata = decodedData\n\t}\n\tbody, err := io.ReadAll(req.Body)\n\treq.Body.Close()\n\tif err != nil {\n\t\tnewError(\"unable to read body\").Base(err).AtInfo().WriteToLog()\n\t}\n\n\tstreamingRespOption := &httpRespStreamWriting{resp: resp}\n\trecvResp, err := h.assembly.TripperReceiver().OnRoundTrip(h.ctx, request.Request{Data: body, ConnectionTag: data},\n\t\tstreamingRespOption)\n\tif err != nil {\n\t\tnewError(\"unable to process roundtrip\").Base(err).AtInfo().WriteToLog()\n\t}\n\tif streamingRespOption.used {\n\t\treturn\n\t}\n\t_, err = io.Copy(resp, bytes.NewReader(recvResp.Data))\n\tif err != nil {\n\t\tnewError(\"unable to send response\").Base(err).AtInfo().WriteToLog()\n\t}\n}\n\nfunc (h *httpTripperServer) Start() error {\n\tlistener, err := h.assembly.AutoImplListener().Listen(h.ctx)\n\tif err != nil {\n\t\treturn newError(\"unable to create a listener for http tripper server\").Base(err)\n\t}\n\th.listener = listener\n\tgo func() {\n\t\thttpServer := http.Server{\n\t\t\tReadHeaderTimeout: 240 * time.Second,\n\t\t\tReadTimeout:       240 * time.Second,\n\t\t\tWriteTimeout:      240 * time.Second,\n\t\t\tIdleTimeout:       240 * time.Second,\n\t\t}\n\t\thttpServer.Handler = h\n\t\terr := httpServer.Serve(h.listener)\n\t\tif err != nil {\n\t\t\tnewError(\"unable to serve listener for http tripper server\").Base(err).WriteToLog()\n\t\t}\n\t}()\n\treturn nil\n}\n\nfunc (h *httpTripperServer) Close() error {\n\treturn h.listener.Close()\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tclientConfig, ok := config.(*ClientConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a ClientConfig\")\n\t\t}\n\t\treturn newHTTPRoundTripperClient(ctx, clientConfig), nil\n\t}))\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\tserverConfig, ok := config.(*ServerConfig)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"not a ServerConfig\")\n\t\t}\n\t\treturn newHTTPRoundTripperServer(ctx, serverConfig), nil\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripper.go",
    "content": "package request\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype RoundTripperClient interface {\n\tTripper\n\tTransportClientAssemblyReceiver\n}\n\ntype RoundTripperServer interface {\n\tcommon.Runnable\n\tTransportServerAssemblyReceiver\n}\n\ntype Tripper interface {\n\tRoundTrip(ctx context.Context, req Request, opts ...RoundTripperOption) (resp Response, err error)\n}\n\ntype TripperReceiver interface {\n\tOnRoundTrip(ctx context.Context, req Request, opts ...RoundTripperOption) (resp Response, err error)\n}\n\ntype RoundTripperOption interface {\n\tRoundTripperOption()\n}\n\ntype Request struct {\n\tData          []byte\n\tConnectionTag []byte\n}\n\ntype Response struct {\n\tData []byte\n}\n\ntype OptionSupportsStreamingResponse interface {\n\tRoundTripperOption\n\tGetResponseWriter() io.Writer\n}\n\ntype OptionSupportsStreamingResponseExtensionFlusher interface {\n\tFlush()\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/accesschecker_password.go",
    "content": "package roundtripperreverserserver\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/hkdf\"\n\t\"crypto/sha256\"\n\t\"math\"\n\n\t\"github.com/v2fly/struc\"\n)\n\ntype PasswordAccessChecker struct {\n\tPassword string\n\n\tblock cipher.Block\n}\n\n// NewPasswordAccessChecker creates a PasswordAccessChecker from the given password\n// and initializes its internal cipher block. It returns an error if initialization\n// fails.\nfunc NewPasswordAccessChecker(password string) (*PasswordAccessChecker, error) {\n\tp := &PasswordAccessChecker{Password: password}\n\tif err := p.init(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n\ntype tokenUnpacked struct {\n\tUserID int64  `struc:\"int64,little\"`\n\tCheck  uint64 `struc:\"uint64,little\"`\n}\n\nfunc (p *PasswordAccessChecker) CheckReverserAccess(ctx context.Context, serverKey []byte) (clientKey []byte, err error) {\n\tif len(serverKey) != 16 {\n\t\treturn nil, newError(\"invalid server key length\")\n\t}\n\tbuffer := make([]byte, 16)\n\t// Decrypt into buffer from serverKey\n\tp.block.Decrypt(buffer, serverKey)\n\n\ttoken := &tokenUnpacked{}\n\n\terr = struc.Unpack(bytes.NewReader(buffer), token)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to unpack token\").Base(err)\n\t}\n\n\texpectedCheck := uint64(0)\n\tif token.Check != expectedCheck {\n\t\treturn nil, newError(\"invalid token check value\")\n\t}\n\n\tif token.UserID == int64(math.MinInt64) {\n\t\treturn nil, newError(\"invalid token userID: MinInt64\")\n\t}\n\n\tif token.UserID < 0 {\n\t\treturn nil, newError(\"invalid token userID for server: client token has negative userID\")\n\t}\n\n\t// pack client token into a buffer with capacity 16\n\tbuf := bytes.NewBuffer(make([]byte, 0, 16))\n\terr = struc.Pack(buf, &tokenUnpacked{\n\t\tUserID: -token.UserID,\n\t\tCheck:  expectedCheck,\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"failed to pack client token\").Base(err)\n\t}\n\tclientKeyBuffer := buf.Bytes()\n\tif len(clientKeyBuffer) != 16 {\n\t\treturn nil, newError(\"invalid packed client token length\")\n\t}\n\t// encrypt into a fresh slice to avoid overlapping issues\n\tencrypted := make([]byte, 16)\n\tp.block.Encrypt(encrypted, clientKeyBuffer)\n\treturn encrypted, nil\n}\n\nfunc (p *PasswordAccessChecker) GenerateToken(userID int64) ([]byte, error) {\n\tif userID == int64(math.MinInt64) {\n\t\treturn nil, newError(\"userID cannot be MinInt64\")\n\t}\n\texpectedCheck := uint64(0)\n\t// pack token into a buffer with capacity 16\n\tbuf := bytes.NewBuffer(make([]byte, 0, 16))\n\terr := struc.Pack(buf, &tokenUnpacked{\n\t\tUserID: userID,\n\t\tCheck:  expectedCheck,\n\t})\n\tif err != nil {\n\t\treturn nil, newError(\"failed to pack token\").Base(err)\n\t}\n\tbuffer := buf.Bytes()\n\tif len(buffer) != 16 {\n\t\treturn nil, newError(\"invalid packed token length\")\n\t}\n\tencrypted := make([]byte, 16)\n\tp.block.Encrypt(encrypted, buffer)\n\treturn encrypted, nil\n}\n\nfunc (p *PasswordAccessChecker) init() error {\n\tblock, err := createBlockFromPassword(p.Password)\n\tif err != nil {\n\t\treturn newError(\"failed to create block from password\").Base(err)\n\t}\n\tp.block = block\n\treturn nil\n}\n\nfunc createBlockFromPassword(password string) (cipher.Block, error) {\n\t// derive a 16-byte key from the password with hkdf\n\tkey, err := hkdf.Expand(sha256.New, []byte(password), \"v2ray-hd87BYQL-aBzumdEh-Yv4E6Rdu:request-roundtripperreverserserver\"+\"createBlockFromPassword\", 16)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to derive key from password\").Base(err)\n\t}\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create AES cipher\").Base(err)\n\t}\n\treturn block, nil\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/accesschecker_password_test.go",
    "content": "package roundtripperreverserserver\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"math\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/v2fly/struc\"\n)\n\nfunc TestGenerateTokenLength(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"test-password\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker: %v\", err)\n\t}\n\n\ttok, err := p.GenerateToken(12345)\n\tif err != nil {\n\t\tt.Fatalf(\"GenerateToken failed: %v\", err)\n\t}\n\n\tif len(tok) != 16 {\n\t\tt.Fatalf(\"expected token length 16, got %d\", len(tok))\n\t}\n}\n\nfunc TestGenerateAndCheckRoundTrip(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"another-secret\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker: %v\", err)\n\t}\n\n\tuserID := int64(42)\n\tserverKey, err := p.GenerateToken(userID)\n\tif err != nil {\n\t\tt.Fatalf(\"GenerateToken failed: %v\", err)\n\t}\n\n\tclientKey, err := p.CheckReverserAccess(context.Background(), serverKey)\n\tif err != nil {\n\t\tt.Fatalf(\"CheckReverserAccess failed: %v\", err)\n\t}\n\n\tif len(clientKey) != 16 {\n\t\tt.Fatalf(\"expected client key length 16, got %d\", len(clientKey))\n\t}\n\n\t// decrypt clientKey using internal block to inspect contents\n\tdecrypted := make([]byte, 16)\n\tp.block.Decrypt(decrypted, clientKey)\n\n\ttoken := &tokenUnpacked{}\n\tif err := struc.Unpack(bytes.NewReader(decrypted), token); err != nil {\n\t\tt.Fatalf(\"failed to unpack client token: %v\", err)\n\t}\n\n\tif token.Check != 0 {\n\t\tt.Fatalf(\"expected check 0, got %d\", token.Check)\n\t}\n\tif token.UserID != -userID {\n\t\tt.Fatalf(\"expected userID %d, got %d\", -userID, token.UserID)\n\t}\n}\n\nfunc TestPasswordAccessChecker_ValidRoundTrip(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"test-password\")\n\tif err != nil {\n\t\tt.Fatalf(\"NewPasswordAccessChecker failed: %v\", err)\n\t}\n\n\tuserID := int64(42)\n\ttoken, err := p.GenerateToken(userID)\n\tif err != nil {\n\t\tt.Fatalf(\"GenerateToken failed: %v\", err)\n\t}\n\n\tclientKey, err := p.CheckReverserAccess(context.TODO(), token)\n\tif err != nil {\n\t\tt.Fatalf(\"CheckReverserAccess failed: %v\", err)\n\t}\n\n\t// decrypt clientKey and verify contents\n\tbuf := make([]byte, 16)\n\tp.block.Decrypt(buf, clientKey)\n\ttok := &tokenUnpacked{}\n\tif err := struc.Unpack(bytes.NewReader(buf), tok); err != nil {\n\t\tt.Fatalf(\"failed to unpack client token: %v\", err)\n\t}\n\n\tif tok.Check != 0 {\n\t\tt.Fatalf(\"unexpected Check value: got %d want 0\", tok.Check)\n\t}\n\tif tok.UserID != -userID {\n\t\tt.Fatalf(\"unexpected UserID: got %d want %d\", tok.UserID, -userID)\n\t}\n}\n\nfunc TestPasswordAccessChecker_InvalidKeyLength(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"test-password\")\n\tif err != nil {\n\t\tt.Fatalf(\"NewPasswordAccessChecker failed: %v\", err)\n\t}\n\n\t_, err = p.CheckReverserAccess(context.TODO(), []byte{1, 2, 3})\n\tif err == nil {\n\t\tt.Fatalf(\"expected error for invalid key length, got nil\")\n\t}\n\tif !strings.Contains(err.Error(), \"invalid server key length\") {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestPasswordAccessChecker_InvalidTokenCheckValue(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"test-password\")\n\tif err != nil {\n\t\tt.Fatalf(\"NewPasswordAccessChecker failed: %v\", err)\n\t}\n\n\t// craft a token with non-zero Check\n\tbuf := bytes.NewBuffer(make([]byte, 0, 16))\n\tif err := struc.Pack(buf, &tokenUnpacked{UserID: 7, Check: 1}); err != nil {\n\t\tt.Fatalf(\"failed to pack token: %v\", err)\n\t}\n\tplain := buf.Bytes()\n\tif len(plain) != 16 {\n\t\tt.Fatalf(\"unexpected packed length: %d\", len(plain))\n\t}\n\tencrypted := make([]byte, 16)\n\tp.block.Encrypt(encrypted, plain)\n\n\t_, err = p.CheckReverserAccess(context.TODO(), encrypted)\n\tif err == nil {\n\t\tt.Fatalf(\"expected error for invalid token check value, got nil\")\n\t}\n\tif !strings.Contains(err.Error(), \"invalid token check value\") {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestTokensNotInterchangeable(t *testing.T) {\n\tp1, err := NewPasswordAccessChecker(\"password-one\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker p1: %v\", err)\n\t}\n\tp2, err := NewPasswordAccessChecker(\"password-two\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker p2: %v\", err)\n\t}\n\n\tuserID := int64(7)\n\t// token created by p1 should not be accepted by p2\n\ttok1, err := p1.GenerateToken(userID)\n\tif err != nil {\n\t\tt.Fatalf(\"p1.GenerateToken failed: %v\", err)\n\t}\n\tif _, err := p2.CheckReverserAccess(context.Background(), tok1); err == nil {\n\t\tt.Fatalf(\"expected p2 to reject token generated by p1, but it accepted it\")\n\t}\n\n\t// token created by p2 should not be accepted by p1\n\ttok2, err := p2.GenerateToken(userID)\n\tif err != nil {\n\t\tt.Fatalf(\"p2.GenerateToken failed: %v\", err)\n\t}\n\tif _, err := p1.CheckReverserAccess(context.Background(), tok2); err == nil {\n\t\tt.Fatalf(\"expected p1 to reject token generated by p2, but it accepted it\")\n\t}\n}\n\nfunc TestCheckReverserAccess_NegativeUserID(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"neg-test\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker: %v\", err)\n\t}\n\n\t// craft a token with negative UserID and Check == 0\n\tbuf := bytes.NewBuffer(make([]byte, 0, 16))\n\tif err := struc.Pack(buf, &tokenUnpacked{UserID: -5, Check: 0}); err != nil {\n\t\tt.Fatalf(\"failed to pack token: %v\", err)\n\t}\n\tplain := buf.Bytes()\n\tif len(plain) != 16 {\n\t\tt.Fatalf(\"unexpected packed length: %d\", len(plain))\n\t}\n\tserverKey := make([]byte, 16)\n\tp.block.Encrypt(serverKey, plain)\n\n\tif _, err := p.CheckReverserAccess(context.Background(), serverKey); err == nil {\n\t\tt.Fatalf(\"expected error for negative userID token, got nil\")\n\t} else if !strings.Contains(err.Error(), \"invalid token userID for server\") {\n\t\tt.Fatalf(\"unexpected error for negative userID token: %v\", err)\n\t}\n}\n\nfunc TestCheckReverserAccess_MinInt64Token(t *testing.T) {\n\tp, err := NewPasswordAccessChecker(\"minint-test\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker: %v\", err)\n\t}\n\n\t// craft a token with MinInt64 and Check == 0\n\tbuf := bytes.NewBuffer(make([]byte, 0, 16))\n\tif err := struc.Pack(buf, &tokenUnpacked{UserID: math.MinInt64, Check: 0}); err != nil {\n\t\tt.Fatalf(\"failed to pack token: %v\", err)\n\t}\n\tplain := buf.Bytes()\n\tif len(plain) != 16 {\n\t\tt.Fatalf(\"unexpected packed length: %d\", len(plain))\n\t}\n\tserverKey := make([]byte, 16)\n\tp.block.Encrypt(serverKey, plain)\n\n\tif _, err := p.CheckReverserAccess(context.Background(), serverKey); err == nil {\n\t\tt.Fatalf(\"expected error for MinInt64 token, got nil\")\n\t} else if !strings.Contains(err.Error(), \"invalid token userID: MinInt64\") {\n\t\tt.Fatalf(\"unexpected error for MinInt64 token: %v\", err)\n\t}\n}\n\nfunc TestGenerateTokensDifferentPasswords(t *testing.T) {\n\tp1, err := NewPasswordAccessChecker(\"pw-a\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker p1: %v\", err)\n\t}\n\tp2, err := NewPasswordAccessChecker(\"pw-b\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker p2: %v\", err)\n\t}\n\n\tuserID := int64(100)\n\ttok1, err := p1.GenerateToken(userID)\n\tif err != nil {\n\t\tt.Fatalf(\"p1.GenerateToken failed: %v\", err)\n\t}\n\ttok2, err := p2.GenerateToken(userID)\n\tif err != nil {\n\t\tt.Fatalf(\"p2.GenerateToken failed: %v\", err)\n\t}\n\n\tif bytes.Equal(tok1, tok2) {\n\t\tt.Fatalf(\"expected tokens from different passwords to differ, but they are equal\")\n\t}\n}\n\nfunc TestNewPasswordAccessChecker_EmptyPassword(t *testing.T) {\n\t// ensure creating a checker with empty password succeeds and block is set\n\tp, err := NewPasswordAccessChecker(\"\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create checker with empty password: %v\", err)\n\t}\n\tif p.block == nil {\n\t\tt.Fatalf(\"expected block to be initialized for empty password\")\n\t}\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/clicommand/errors.generated.go",
    "content": "package clicommand\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/clicommand/generate_token_cli.go",
    "content": "package clicommand\n\nimport (\n\t\"encoding/base64\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripperreverserserver\"\n)\n\nvar (\n\tgenPassword      *string\n\tgenPasswordShort *string\n\tgenUser          *string\n\tgenOut           *string\n)\n\nvar cmdGenerateToken = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering request-rtt-reverser-gen-token\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\t// user-facing flag name: access passphrase\n\t\tgenPassword = fs.String(\"access-passphrase\", \"\", \"access passphrase used to derive token key (required)\")\n\t\t// short alias for convenience\n\t\tgenPasswordShort = fs.String(\"p\", \"\", \"access passphrase (shorthand)\")\n\t\tgenUser = fs.String(\"u\", \"\", \"userID (required, int64, positive)\")\n\t\tgenOut = fs.String(\"o\", \"\", \"write base64 tokens to file (optional)\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tif err := cmd.Flag.Parse(args); err != nil {\n\t\t\tbase.Fatalf(\"failed to parse flags: %v\", err)\n\t\t}\n\n\t\t// require password (either long form or short alias)\n\t\tvar passphrase string\n\t\tif genPasswordShort != nil && *genPasswordShort != \"\" {\n\t\t\tpassphrase = *genPasswordShort\n\t\t} else if genPassword != nil && *genPassword != \"\" {\n\t\t\tpassphrase = *genPassword\n\t\t} else {\n\t\t\tbase.Fatalf(\"-access-passphrase (or -p) is required\")\n\t\t}\n\n\t\tif *genUser == \"\" {\n\t\t\tbase.Fatalf(\"-u userID is required\")\n\t\t}\n\t\tid, err := strconv.ParseInt(*genUser, 10, 64)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"invalid userID %q: %v\", *genUser, err)\n\t\t}\n\n\t\t// require positive userID\n\t\tif id <= 0 {\n\t\t\tbase.Fatalf(\"userID must be a positive integer\")\n\t\t}\n\n\t\tchecker, err := roundtripperreverserserver.NewPasswordAccessChecker(passphrase)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to create PasswordAccessChecker: %v\", err)\n\t\t}\n\n\t\t// generate private (positive) and public (negative) tokens\n\t\tprivToken, err := checker.GenerateToken(id)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"GenerateToken (private) failed: %v\", err)\n\t\t}\n\t\tpubToken, err := checker.GenerateToken(-id)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"GenerateToken (public) failed: %v\", err)\n\t\t}\n\n\t\tb64Priv := base64.StdEncoding.EncodeToString(privToken)\n\t\tb64Pub := base64.StdEncoding.EncodeToString(pubToken)\n\n\t\tif *genOut != \"\" {\n\t\t\tcontent := fmt.Sprintf(\"private: %s\\npublic: %s\\n\", b64Priv, b64Pub)\n\t\t\tif err := os.WriteFile(*genOut, []byte(content), 0o600); err != nil {\n\t\t\t\tbase.Fatalf(\"failed to write tokens to file %q: %v\", *genOut, err)\n\t\t\t}\n\t\t\tif _, err := fmt.Fprintf(os.Stdout, \"wrote base64 tokens to %s\\n\", *genOut); err != nil {\n\t\t\t\tbase.Fatalf(\"failed to write token message: %v\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\t// print both tokens to stdout\n\t\tfmt.Printf(\"private: %s\\npublic: %s\\n\", b64Priv, b64Pub)\n\t},\n}\n\nfunc init() {\n\tengineering.AddCommand(cmdGenerateToken)\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/clicommand/roundTripperReserseServerCli.go",
    "content": "package clicommand\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"flag\"\n\t\"os\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/systemnetworkimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripperreverserserver\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nvar config *string\n\nvar cmdRTTReverseServer = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering request-rtt-reverse-server\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"\", flag.ExitOnError)\n\t\tconfig = fs.String(\"c\", \"\", \"\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\terr := cmd.Flag.Parse(args)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to parse flags: %v\", err)\n\t\t}\n\t\tfd, err := os.Open(*config)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to open config file %q: %v\", *config, err)\n\t\t}\n\t\tdefer func() { _ = fd.Close() }()\n\t\tcontent := bytes.NewBuffer(nil)\n\t\t_, err = content.ReadFrom(fd)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to read config file %q: %v\", *config, err)\n\t\t}\n\t\tvar reverserConfig roundtripperreverserserver.Config\n\t\terr = protojson.Unmarshal(content.Bytes(), &reverserConfig)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to unmarshal JSON config from %q: %v\", *config, err)\n\t\t}\n\n\t\tctx := context.Background()\n\t\tsystemNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()\n\t\tctx = envctx.ContextWithEnvironment(ctx, systemNetworkImpl)\n\n\t\tserver, err := roundtripperreverserserver.NewReverser(ctx, &reverserConfig)\n\t\tif err != nil {\n\t\t\tbase.Fatalf(\"failed to create RTT reverse server: %v\", err)\n\t\t}\n\t\t_ = server\n\t\tselect {}\n\t},\n}\n\nfunc init() {\n\tengineering.AddCommand(cmdRTTReverseServer)\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/config.pb.go",
    "content": "package roundtripperreverserserver\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 Config struct {\n\tstate              protoimpl.MessageState `protogen:\"open.v1\"`\n\tRoundTripperServer *anypb.Any             `protobuf:\"bytes,2,opt,name=round_tripper_server,json=roundTripperServer,proto3\" json:\"round_tripper_server,omitempty\"`\n\tListen             string                 `protobuf:\"bytes,3,opt,name=listen,proto3\" json:\"listen,omitempty\"`\n\tAccessPassphrase   string                 `protobuf:\"bytes,4,opt,name=access_passphrase,json=accessPassphrase,proto3\" json:\"access_passphrase,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_request_roundtripperreverserserver_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_roundtripperreverserserver_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_roundtripperreverserserver_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetRoundTripperServer() *anypb.Any {\n\tif x != nil {\n\t\treturn x.RoundTripperServer\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetListen() string {\n\tif x != nil {\n\t\treturn x.Listen\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetAccessPassphrase() string {\n\tif x != nil {\n\t\treturn x.AccessPassphrase\n\t}\n\treturn \"\"\n}\n\nvar File_transport_internet_request_roundtripperreverserserver_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_roundtripperreverserserver_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"Btransport/internet/request/roundtripperreverserserver/config.proto\\x12@v2ray.core.transport.internet.request.roundtripperreverserserver\\x1a common/protoext/extensions.proto\\x1a\\x19google/protobuf/any.proto\\\"\\xc9\\x01\\n\" +\n\t\"\\x06Config\\x12F\\n\" +\n\t\"\\x14round_tripper_server\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x12roundTripperServer\\x12\\x16\\n\" +\n\t\"\\x06listen\\x18\\x03 \\x01(\\tR\\x06listen\\x12+\\n\" +\n\t\"\\x11access_passphrase\\x18\\x04 \\x01(\\tR\\x10accessPassphrase:2\\x82\\xb5\\x18.\\n\" +\n\t\",transport.request.roundtripperreverserserverB\\xe0\\x01\\n\" +\n\t\"Dcom.v2ray.core.transport.internet.request.roundtripperreverserserverP\\x01ZTgithub.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripperreverserserver\\xaa\\x02?V2Ray.Core.Transport.Internet.Request.RoundtripperReverseServerb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_roundtripperreverserserver_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_roundtripperreverserserver_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_roundtripperreverserserver_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_roundtripperreverserserver_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_roundtripperreverserserver_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_roundtripperreverserserver_config_proto_rawDesc), len(file_transport_internet_request_roundtripperreverserserver_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_roundtripperreverserserver_config_proto_rawDescData\n}\n\nvar file_transport_internet_request_roundtripperreverserserver_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_request_roundtripperreverserserver_config_proto_goTypes = []any{\n\t(*Config)(nil),    // 0: v2ray.core.transport.internet.request.roundtripperreverserserver.Config\n\t(*anypb.Any)(nil), // 1: google.protobuf.Any\n}\nvar file_transport_internet_request_roundtripperreverserserver_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.request.roundtripperreverserserver.Config.round_tripper_server:type_name -> google.protobuf.Any\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_request_roundtripperreverserserver_config_proto_init() }\nfunc file_transport_internet_request_roundtripperreverserserver_config_proto_init() {\n\tif File_transport_internet_request_roundtripperreverserserver_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_roundtripperreverserserver_config_proto_rawDesc), len(file_transport_internet_request_roundtripperreverserserver_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_roundtripperreverserserver_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_roundtripperreverserserver_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_roundtripperreverserserver_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_roundtripperreverserserver_config_proto = out.File\n\tfile_transport_internet_request_roundtripperreverserserver_config_proto_goTypes = nil\n\tfile_transport_internet_request_roundtripperreverserserver_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.roundtripperreverserserver;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.RoundtripperReverseServer\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripperreverserserver\";\noption java_package = \"com.v2ray.core.transport.internet.request.roundtripperreverserserver\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"google/protobuf/any.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport.request.roundtripperreverserserver\";\n  google.protobuf.Any round_tripper_server = 2;\n  string listen = 3;\n  string access_passphrase = 4;\n}"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/errors.generated.go",
    "content": "package roundtripperreverserserver\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/reverser.go",
    "content": "package roundtripperreverserserver\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc NewReverser(ctx context.Context, config *Config) (*Reverser, error) {\n\treverser := &Reverser{\n\t\tctx:    ctx,\n\t\tconfig: config,\n\t}\n\tif err := reverser.init(); err != nil {\n\t\treturn nil, newError(\"failed to initialize Reverser\").Base(err).AtError()\n\t}\n\treturn reverser, nil\n}\n\ntype Reverser struct {\n\tctx           context.Context\n\tconfig        *Config\n\trttServer     request.RoundTripperServer\n\treverser      request.ReverserImpl\n\taccessChecker request.ReverserAccessChecker\n}\n\nfunc (s *Reverser) OnRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\tserverIntent := len(req.ConnectionTag) == 16\n\tif serverIntent {\n\t\tserverPublic, err := s.accessChecker.CheckReverserAccess(ctx, req.ConnectionTag)\n\t\tif err != nil {\n\t\t\treturn request.Response{}, newError(\"reverser access check failed\").Base(err).AtError()\n\t\t}\n\t\treverserImpl, err := s.reverser.OnAuthenticatedServerIntentRoundTrip(ctx, serverPublic, req, opts...)\n\t\tif err != nil {\n\t\t\treturn request.Response{}, newError(\"failed to handle authenticated server round trip\").Base(err).AtError()\n\t\t}\n\t\treturn reverserImpl, nil\n\t}\n\tif len(req.ConnectionTag) != 32 {\n\t\treturn request.Response{}, newError(\"invalid ConnectionTag length\")\n\t}\n\treverserImpl, err := s.reverser.OnOtherRoundTrip(ctx, req, opts...)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"failed to handle client round trip\").Base(err).AtError()\n\t}\n\treturn reverserImpl, nil\n}\n\nfunc (s *Reverser) Listen(ctx context.Context) (v2net.Listener, error) {\n\tsystemNetworkCapabilitySet := envctx.EnvironmentFromContext(s.ctx).(environment.SystemNetworkCapabilitySet)\n\tlistener := systemNetworkCapabilitySet.Listener()\n\taddr, err := v2net.ParseDestination(s.config.Listen)\n\tif err != nil {\n\t\treturn nil, newError(\"invalid listen address \" + s.config.Listen).Base(err).AtError()\n\t}\n\tnetaddr := &net.TCPAddr{IP: addr.Address.IP(), Port: int(addr.Port)}\n\tl, err := listener.Listen(ctx, netaddr, nil)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to listen on \" + s.config.Listen).Base(err).AtError()\n\t}\n\treturn l, nil\n}\n\nfunc (s *Reverser) init() error {\n\tif s.config == nil {\n\t\treturn newError(\"nil ServerConfig\")\n\t}\n\n\tif s.config.AccessPassphrase == \"\" {\n\t\treturn newError(\"empty AccessPassphrase in ServerConfig\")\n\t}\n\taccessChecker, err := NewPasswordAccessChecker(s.config.AccessPassphrase)\n\tif err != nil {\n\t\treturn newError(\"failed to create AccessChecker\").Base(err).AtError()\n\t}\n\ts.accessChecker = accessChecker\n\n\tReverserImplInst, err := NewReverserImpl()\n\tif err != nil {\n\t\treturn newError(\"failed to create ReverserImpl\").Base(err).AtError()\n\t}\n\ts.reverser = ReverserImplInst\n\n\tif s.config.RoundTripperServer == nil {\n\t\treturn newError(\"nil RoundTripperServer in ServerConfig\")\n\t}\n\tRoundTripperServerConfig, err := serial.GetInstanceOf(s.config.RoundTripperServer)\n\tif err != nil {\n\t\treturn newError(\"failed to get instance of RoundTripperServer\").Base(err).AtError()\n\t}\n\tRoundTripperServerObj, err := common.CreateObject(s.ctx, RoundTripperServerConfig)\n\tif err != nil {\n\t\treturn newError(\"failed to create RoundTripperServer\").Base(err).AtError()\n\t}\n\tRoundTripperServerTyped, ok := RoundTripperServerObj.(request.RoundTripperServer)\n\tif !ok {\n\t\treturn newError(\"RoundTripperServer is not a valid request.RoundTripperServer\")\n\t}\n\ts.rttServer = RoundTripperServerTyped\n\ts.rttServer.OnTransportServerAssemblyReady(s)\n\tif err := s.rttServer.Start(); err != nil {\n\t\treturn newError(\"failed to start RoundTripperServer\").Base(err).AtError()\n\t}\n\treturn nil\n}\n\nfunc (s *Reverser) TripperReceiver() request.TripperReceiver {\n\treturn s\n}\n\nfunc (s *Reverser) SessionReceiver() request.SessionReceiver {\n\treturn nil\n}\n\nfunc (s *Reverser) AutoImplListener() request.Listener {\n\treturn s\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/reverserimpl.go",
    "content": "package roundtripperreverserserver\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/task\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\nfunc NewReverserImpl() (request.ReverserImpl, error) {\n\tr := &ReverserImpl{\n\t\ttimeoutDuration: 5 * time.Minute,\n\t}\n\n\t// configure periodic cleaner\n\tr.periodicCleaner = &task.Periodic{\n\t\tInterval: time.Second * 30,\n\t\tExecute: func() error {\n\t\t\tnow := time.Now()\n\t\t\tr.serverPublicKeyToStateMap.Range(func(k, v interface{}) bool {\n\t\t\t\tss, ok := v.(*serverState)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tif now.Sub(ss.lastSeen) > r.timeoutDuration {\n\t\t\t\t\tr.serverPublicKeyToStateMap.Delete(k)\n\t\t\t\t\tr.serverPrivateKeyToPublicKey.Delete(ss.privateKey)\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t})\n\t\t\treturn nil\n\t\t},\n\t}\n\n\t// start the cleaner; return error if Start fails\n\tif err := r.periodicCleaner.Start(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn r, nil\n}\n\ntype ReverserImpl struct {\n\tserverPublicKeyToStateMap   sync.Map\n\tserverPrivateKeyToPublicKey sync.Map\n\n\tclientTemporaryKeyToStateMap sync.Map\n\n\t// cleanup fields\n\tperiodicCleaner *task.Periodic\n\ttimeoutDuration time.Duration\n}\n\n// StopCleanup stops the periodic cleaner (if running).\nfunc (r *ReverserImpl) StopCleanup() error {\n\tif r.periodicCleaner == nil {\n\t\treturn nil\n\t}\n\treturn r.periodicCleaner.Close()\n}\n\nfunc (r *ReverserImpl) OnOtherRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\t_ = ctx\n\t_ = opts\n\troutingKey := req.ConnectionTag\n\tif len(routingKey) != 32 {\n\t\treturn request.Response{}, newError(\"invalid routing key\")\n\t}\n\tsourceKey := routingKey[:16]\n\tdestKey := routingKey[16:]\n\n\tif _, ok := r.serverPrivateKeyToPublicKey.Load(string(sourceKey)); ok {\n\t\tstateInterface, clientOk := r.clientTemporaryKeyToStateMap.Load(string(destKey))\n\t\tif clientOk {\n\t\t\tstate := stateInterface.(*clientState)\n\t\t\tmessage := &reverserMessage{\n\t\t\t\tData: req.Data,\n\t\t\t}\n\t\t\tselect {\n\t\t\tcase state.messageQueue <- message:\n\t\t\tdefault:\n\t\t\t\treturn request.Response{}, newError(\"client message queue full\")\n\t\t\t}\n\t\t\treturn request.Response{}, nil\n\t\t}\n\t\treturn request.Response{}, newError(\"no client found for the given routing key\")\n\t}\n\n\t// try if this is a client to server message\n\tstateInterface, _ := r.clientTemporaryKeyToStateMap.LoadOrStore(string(sourceKey), &clientState{\n\t\tmessageQueue: make(chan *reverserMessage, 1),\n\t})\n\tstate := stateInterface.(*clientState)\n\tdefer func() {\n\t\tr.clientTemporaryKeyToStateMap.Delete(string(sourceKey))\n\t}()\n\n\tserverStateInterface, ok := r.serverPublicKeyToStateMap.Load(string(destKey))\n\tif ok {\n\t\tserverStateInst := serverStateInterface.(*serverState)\n\t\tmessage := &reverserMessage{\n\t\t\tData: req.Data,\n\t\t}\n\t\ttimeOutTimer := time.NewTimer(time.Second * 25)\n\t\tselect {\n\t\tcase serverStateInst.messageQueue <- message:\n\t\tcase <-timeOutTimer.C:\n\t\t\treturn request.Response{}, newError(\"server message queue full timeout\")\n\t\t}\n\n\t\tselect {\n\t\tcase respMessage := <-state.messageQueue:\n\t\t\ttimeOutTimer.Stop()\n\t\t\treturn request.Response{\n\t\t\t\tData: respMessage.Data,\n\t\t\t}, nil\n\t\tcase <-timeOutTimer.C:\n\t\t\treturn request.Response{}, newError(\"client message queue empty timeout\")\n\t\t}\n\t}\n\n\treturn request.Response{}, newError(\"no server found for the given routing key\")\n}\n\nfunc (r *ReverserImpl) OnAuthenticatedServerIntentRoundTrip(ctx context.Context, serverPublic []byte, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\t_ = ctx\n\t_ = opts\n\tif len(req.ConnectionTag) != 16 {\n\t\treturn request.Response{}, newError(\"invalid server private key\")\n\t}\n\n\tif len(serverPublic) != 16 {\n\t\treturn request.Response{}, newError(\"invalid server public key\")\n\t}\n\n\tserverPrivate := req.ConnectionTag\n\t// store mapping from private -> public\n\tr.serverPrivateKeyToPublicKey.Store(string(serverPrivate), string(serverPublic))\n\tstateInterface, _ := r.serverPublicKeyToStateMap.LoadOrStore(string(serverPublic), &serverState{\n\t\tmessageQueue: make(chan *reverserMessage, 16),\n\t\tlastSeen:     time.Now(),\n\t})\n\tstate := stateInterface.(*serverState)\n\tstate.lastSeen = time.Now()\n\ttimeOutTimer := time.NewTimer(time.Minute)\n\tselect {\n\tcase message := <-state.messageQueue:\n\t\ttimeOutTimer.Stop()\n\t\treturn request.Response{\n\t\t\tData: message.Data,\n\t\t}, nil\n\tcase <-timeOutTimer.C:\n\t\treturn request.Response{}, nil\n\t}\n}\n\nfunc (r *ReverserImpl) __CleanupNow____TestOnly() {\n\t// trigger cleanup immediately for testing purposes\n\tr.periodicCleaner.Execute()\n}\n\ntype clientState struct {\n\tmessageQueue chan *reverserMessage\n}\n\ntype serverState struct {\n\tmessageQueue chan *reverserMessage\n\tlastSeen     time.Time\n\tprivateKey   string\n}\n\ntype reverserMessage struct {\n\tData []byte\n}\n"
  },
  {
    "path": "transport/internet/request/roundtripperreverserserver/reverserimpl_test.go",
    "content": "package roundtripperreverserserver\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n)\n\n// helper to make a byte slice of given length filled with a pattern\nfunc fill(b byte, n int) []byte {\n\tres := make([]byte, n)\n\tfor i := range res {\n\t\tres[i] = b\n\t}\n\treturn res\n}\n\n// stopCleanup tries to call StopCleanup on concrete *ReverserImpl returned by NewReverserImpl.\nfunc stopCleanup(t *testing.T, r request.ReverserImpl) {\n\tif r == nil {\n\t\treturn\n\t}\n\tif impl, ok := r.(*ReverserImpl); ok {\n\t\tif err := impl.StopCleanup(); err != nil {\n\t\t\tt.Fatalf(\"StopCleanup failed: %v\", err)\n\t\t}\n\t} else {\n\t\tt.Fatalf(\"expected *ReverserImpl, got %T\", r)\n\t}\n}\n\nfunc TestOnOtherRoundTrip_InvalidRoutingKeyLength(t *testing.T) {\n\tr, err := NewReverserImpl()\n\tif err != nil {\n\t\t// constructor currently never errors\n\t\tt.Fatalf(\"unexpected constructor error: %v\", err)\n\t}\n\tdefer stopCleanup(t, r)\n\t_, gotErr := r.OnOtherRoundTrip(context.Background(), request.Request{ConnectionTag: []byte(\"short\")})\n\tif gotErr == nil {\n\t\tt.Fatalf(\"expected error for invalid routing key length\")\n\t}\n\tif !strings.Contains(gotErr.Error(), \"invalid routing key\") {\n\t\tt.Fatalf(\"unexpected error: %v\", gotErr)\n\t}\n}\n\nfunc TestOnOtherRoundTrip_ServerToClient_NoClientFound(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tsource := fill('A', 16)\n\tdest := fill('B', 16)\n\timpl.serverPrivateKeyToPublicKey.Store(string(source), string(source))\n\t_, err := impl.OnOtherRoundTrip(context.Background(), request.Request{ConnectionTag: append(source, dest...)})\n\tif err == nil || !strings.Contains(err.Error(), \"no client found\") {\n\t\tt.Fatalf(\"expected no client found error, got: %v\", err)\n\t}\n}\n\nfunc TestOnOtherRoundTrip_ServerToClient_Success(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tsource := fill('S', 16)\n\tdest := fill('C', 16)\n\timpl.serverPrivateKeyToPublicKey.Store(string(source), string(source))\n\tclientState := &clientState{messageQueue: make(chan *reverserMessage, 1)}\n\timpl.clientTemporaryKeyToStateMap.Store(string(dest), clientState)\n\tdata := []byte(\"hello-client\")\n\t_, err := impl.OnOtherRoundTrip(context.Background(), request.Request{ConnectionTag: append(source, dest...), Data: data})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\tselect {\n\tcase msg := <-clientState.messageQueue:\n\t\tif string(msg.Data) != string(data) {\n\t\t\tt.Fatalf(\"unexpected message data: got %q want %q\", msg.Data, data)\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"expected message queued for client but queue empty\")\n\t}\n}\n\nfunc TestOnOtherRoundTrip_ServerToClient_QueueFull(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tsource := fill('F', 16)\n\tdest := fill('Q', 16)\n\timpl.serverPrivateKeyToPublicKey.Store(string(source), string(source))\n\tclientState := &clientState{messageQueue: make(chan *reverserMessage, 1)}\n\t// pre-fill queue so next send fails non-blocking\n\tclientState.messageQueue <- &reverserMessage{Data: []byte(\"prefill\")}\n\timpl.clientTemporaryKeyToStateMap.Store(string(dest), clientState)\n\t_, err := impl.OnOtherRoundTrip(context.Background(), request.Request{ConnectionTag: append(source, dest...), Data: []byte(\"new\")})\n\tif err == nil || !strings.Contains(err.Error(), \"client message queue full\") {\n\t\tt.Fatalf(\"expected queue full error, got: %v\", err)\n\t}\n}\n\nfunc TestOnOtherRoundTrip_ClientToServer_NoServerFound(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tsource := fill('X', 16)\n\tdest := fill('Y', 16)\n\t_, err := impl.OnOtherRoundTrip(context.Background(), request.Request{ConnectionTag: append(source, dest...), Data: []byte(\"ping\")})\n\tif err == nil || !strings.Contains(err.Error(), \"no server found\") {\n\t\tt.Fatalf(\"expected no server found error, got: %v\", err)\n\t}\n}\n\nfunc TestOnOtherRoundTrip_ClientToServer_Success(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tsource := fill('1', 16)\n\tdest := fill('2', 16)\n\tserverState := &serverState{messageQueue: make(chan *reverserMessage, 1)}\n\timpl.serverPublicKeyToStateMap.Store(string(dest), serverState)\n\tclientState := &clientState{messageQueue: make(chan *reverserMessage, 1)}\n\tclientState.messageQueue <- &reverserMessage{Data: []byte(\"pong\")}\n\timpl.clientTemporaryKeyToStateMap.Store(string(source), clientState)\n\tdata := []byte(\"ping\")\n\tresp, err := impl.OnOtherRoundTrip(context.Background(), request.Request{ConnectionTag: append(source, dest...), Data: data})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\t// verify server received the original message\n\tselect {\n\tcase msg := <-serverState.messageQueue:\n\t\tif string(msg.Data) != string(data) {\n\t\t\tt.Fatalf(\"server message mismatch: got %q want %q\", msg.Data, data)\n\t\t}\n\tdefault:\n\t\tt.Fatalf(\"expected server to receive message but queue empty\")\n\t}\n\tif string(resp.Data) != \"pong\" {\n\t\tt.Fatalf(\"unexpected response data: got %q want %q\", resp.Data, \"pong\")\n\t}\n}\n\nfunc TestOnAuthenticatedServerIntentRoundTrip_InvalidPrivateKeyLength(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tserverPublic := fill('P', 16)\n\t_, err := impl.OnAuthenticatedServerIntentRoundTrip(context.Background(), serverPublic, request.Request{ConnectionTag: fill('Z', 15)})\n\tif err == nil || !strings.Contains(err.Error(), \"invalid server private key\") {\n\t\tt.Fatalf(\"expected invalid server private key error, got: %v\", err)\n\t}\n}\n\nfunc TestOnAuthenticatedServerIntentRoundTrip_InvalidPublicKeyLength(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\t_, err := impl.OnAuthenticatedServerIntentRoundTrip(context.Background(), fill('P', 15), request.Request{ConnectionTag: fill('K', 16)})\n\tif err == nil || !strings.Contains(err.Error(), \"invalid server public key\") {\n\t\tt.Fatalf(\"expected invalid server public key error, got: %v\", err)\n\t}\n}\n\nfunc TestOnAuthenticatedServerIntentRoundTrip_SuccessMessage(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\tserverPublic := fill('P', 16)\n\tserverPrivate := fill('K', 16)\n\tstate := &serverState{messageQueue: make(chan *reverserMessage, 1)}\n\tstate.messageQueue <- &reverserMessage{Data: []byte(\"welcome\")}\n\timpl.serverPublicKeyToStateMap.Store(string(serverPublic), state)\n\tresp, err := impl.OnAuthenticatedServerIntentRoundTrip(context.Background(), serverPublic, request.Request{ConnectionTag: serverPrivate})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\tif string(resp.Data) != \"welcome\" {\n\t\tt.Fatalf(\"unexpected response data: got %q want %q\", resp.Data, \"welcome\")\n\t}\n\tif _, ok := impl.serverPrivateKeyToPublicKey.Load(string(serverPrivate)); !ok {\n\t\tt.Fatalf(\"expected server private key mapping to be stored\")\n\t}\n}\n\nfunc TestSmoke(t *testing.T) {\n\tif _, err := NewReverserImpl(); err != nil {\n\t\tt.Fatalf(\"unexpected error constructing reverser: %v\", err)\n\t}\n}\n\nfunc TestPeriodicCleanupRemovesOldServer(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\n\t// configure short durations for test speed\n\timpl.timeoutDuration = 10 * time.Millisecond\n\timpl.periodicCleaner.Interval = 5 * time.Millisecond\n\n\t// insert a server state with lastSeen far in the past\n\told := &serverState{messageQueue: make(chan *reverserMessage, 1), lastSeen: time.Now().Add(-time.Hour)}\n\timpl.serverPublicKeyToStateMap.Store(\"old-server\", old)\n\n\t// trigger cleanup now\n\timpl.__CleanupNow____TestOnly()\n\n\tif _, ok := impl.serverPublicKeyToStateMap.Load(\"old-server\"); ok {\n\t\tt.Fatalf(\"expected old server entry to be removed by cleaner\")\n\t}\n}\n\nfunc TestCleanupNowRemovesServerAndPrivateMapping(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\n\t// create an old server entry with private key present in private->public map\n\tpublicKey := \"old-server-public\"\n\tprivateKey := \"old-server-private\"\n\told := &serverState{messageQueue: make(chan *reverserMessage, 1), lastSeen: time.Now().Add(-time.Hour), privateKey: privateKey}\n\timpl.serverPublicKeyToStateMap.Store(publicKey, old)\n\timpl.serverPrivateKeyToPublicKey.Store(privateKey, publicKey)\n\n\t// trigger immediate cleanup\n\timpl.__CleanupNow____TestOnly()\n\n\tif _, ok := impl.serverPublicKeyToStateMap.Load(publicKey); ok {\n\t\tt.Fatalf(\"expected old server entry to be removed by cleaner via CleanupNow\")\n\t}\n\tif _, ok := impl.serverPrivateKeyToPublicKey.Load(privateKey); ok {\n\t\tt.Fatalf(\"expected old private->public mapping to be removed by cleaner via CleanupNow\")\n\t}\n}\n\nfunc TestStopCleanupIdempotent(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\timpl := r.(*ReverserImpl)\n\t// first stop\n\tif err := impl.StopCleanup(); err != nil {\n\t\tt.Fatalf(\"StopCleanup failed: %v\", err)\n\t}\n\t// second stop should not panic or return error\n\tif err := impl.StopCleanup(); err != nil {\n\t\tt.Fatalf(\"StopCleanup second call failed: %v\", err)\n\t}\n}\n\nfunc TestOnAuthenticatedServerIntentRoundTrip_UpdatesLastSeenAndMapping(t *testing.T) {\n\tr, _ := NewReverserImpl()\n\tdefer stopCleanup(t, r)\n\timpl := r.(*ReverserImpl)\n\n\tserverPublic := fill('P', 16)\n\tserverPrivate := fill('K', 16)\n\n\t// pre-insert a server state that has an old lastSeen but contains a queued message\n\tstate := &serverState{messageQueue: make(chan *reverserMessage, 1), lastSeen: time.Now().Add(-time.Hour)}\n\tstate.messageQueue <- &reverserMessage{Data: []byte(\"welcome-back\")}\n\timpl.serverPublicKeyToStateMap.Store(string(serverPublic), state)\n\n\tresp, err := impl.OnAuthenticatedServerIntentRoundTrip(context.Background(), serverPublic, request.Request{ConnectionTag: serverPrivate})\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\tif string(resp.Data) != \"welcome-back\" {\n\t\tt.Fatalf(\"unexpected response data: got %q want %q\", resp.Data, \"welcome-back\")\n\t}\n\n\t// mapping from private -> public should be stored\n\tif v, ok := impl.serverPrivateKeyToPublicKey.Load(string(serverPrivate)); !ok || v != string(serverPublic) {\n\t\tt.Fatalf(\"expected private->public mapping stored, got %v (ok=%v)\", v, ok)\n\t}\n\n\t// lastSeen should be updated to a recent time\n\tsi, ok := impl.serverPublicKeyToStateMap.Load(string(serverPublic))\n\tif !ok {\n\t\tt.Fatalf(\"expected server state to still exist after intent call\")\n\t}\n\tss := si.(*serverState)\n\tif time.Since(ss.lastSeen) > time.Second*2 {\n\t\tt.Fatalf(\"expected lastSeen to be updated recently, got %v\", ss.lastSeen)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/request/stereotype/meek/config.pb.go",
    "content": "package meek\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tUrl           string                 `protobuf:\"bytes,1,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_request_stereotype_meek_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_stereotype_meek_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_stereotype_meek_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nvar File_transport_internet_request_stereotype_meek_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_stereotype_meek_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"7transport/internet/request/stereotype/meek/config.proto\\x125v2ray.core.transport.internet.request.stereotype.meek\\x1a common/protoext/extensions.proto\\\"5\\n\" +\n\t\"\\x06Config\\x12\\x10\\n\" +\n\t\"\\x03url\\x18\\x01 \\x01(\\tR\\x03url:\\x19\\x82\\xb5\\x18\\x15\\n\" +\n\t\"\\ttransport\\x12\\x04meek\\x90\\xff)\\x01B\\xc0\\x01\\n\" +\n\t\"9com.v2ray.core.transport.internet.request.stereotype.meekP\\x01ZIgithub.com/v2fly/v2ray-core/v5/transport/internet/request/stereotype/meek\\xaa\\x025V2Ray.Core.Transport.Internet.Request.Stereotype.Meekb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_stereotype_meek_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_stereotype_meek_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_stereotype_meek_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_stereotype_meek_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_stereotype_meek_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_stereotype_meek_config_proto_rawDesc), len(file_transport_internet_request_stereotype_meek_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_stereotype_meek_config_proto_rawDescData\n}\n\nvar file_transport_internet_request_stereotype_meek_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_request_stereotype_meek_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.transport.internet.request.stereotype.meek.Config\n}\nvar file_transport_internet_request_stereotype_meek_config_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_transport_internet_request_stereotype_meek_config_proto_init() }\nfunc file_transport_internet_request_stereotype_meek_config_proto_init() {\n\tif File_transport_internet_request_stereotype_meek_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_stereotype_meek_config_proto_rawDesc), len(file_transport_internet_request_stereotype_meek_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_stereotype_meek_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_stereotype_meek_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_stereotype_meek_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_stereotype_meek_config_proto = out.File\n\tfile_transport_internet_request_stereotype_meek_config_proto_goTypes = nil\n\tfile_transport_internet_request_stereotype_meek_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/stereotype/meek/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.stereotype.meek;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.Stereotype.Meek\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/stereotype/meek\";\noption java_package = \"com.v2ray.core.transport.internet.request.stereotype.meek\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Config{\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"meek\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n\n  string url = 1;\n}"
  },
  {
    "path": "transport/internet/request/stereotype/meek/errors.generated.go",
    "content": "package meek\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/stereotype/meek/meek.go",
    "content": "package meek\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/simple\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembly\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripper/httprt\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst protocolName = \"meek\"\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn nil, newError(\"meek is a transport\")\n\t}))\n\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, meekDial))\n\tcommon.Must(internet.RegisterTransportListener(protocolName, meekListen))\n}\n\nfunc meekDial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tmeekSetting := streamSettings.ProtocolSettings.(*Config)\n\tsimpleAssembler := &simple.ClientConfig{\n\t\tMaxWriteSize:             65536,\n\t\tWaitSubsequentWriteMs:    10,\n\t\tInitialPollingIntervalMs: 100,\n\t\tMaxPollingIntervalMs:     1000,\n\t\tMinPollingIntervalMs:     10,\n\t\tBackoffFactor:            1.5,\n\t\tFailedRetryIntervalMs:    1000,\n\t}\n\thttprtSetting := &httprt.ClientConfig{\n\t\tHttp: &httprt.HTTPConfig{\n\t\t\tUrlPrefix: meekSetting.Url,\n\t\t},\n\t}\n\trequest := &assembly.Config{\n\t\tAssembler:    serial.ToTypedMessage(simpleAssembler),\n\t\tRoundtripper: serial.ToTypedMessage(httprtSetting),\n\t}\n\tconstructedSetting := &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"request\",\n\t\tProtocolSettings: request,\n\t\tSecurityType:     streamSettings.SecurityType,\n\t\tSecuritySettings: streamSettings.SecuritySettings,\n\t\tSocketSettings:   streamSettings.SocketSettings,\n\t}\n\treturn internet.Dial(ctx, dest, constructedSetting)\n}\n\nfunc meekListen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, callback internet.ConnHandler) (internet.Listener, error) {\n\tmeekSetting := streamSettings.ProtocolSettings.(*Config)\n\tsimpleAssembler := &simple.ServerConfig{MaxWriteSize: 65536}\n\thttprtSetting := &httprt.ServerConfig{NoDecodingSessionTag: true, Http: &httprt.HTTPConfig{UrlPrefix: meekSetting.Url}}\n\trequest := &assembly.Config{\n\t\tAssembler:    serial.ToTypedMessage(simpleAssembler),\n\t\tRoundtripper: serial.ToTypedMessage(httprtSetting),\n\t}\n\tconstructedSetting := &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"request\",\n\t\tProtocolSettings: request,\n\t\tSecurityType:     streamSettings.SecurityType,\n\t\tSecuritySettings: streamSettings.SecuritySettings,\n\t\tSocketSettings:   streamSettings.SocketSettings,\n\t}\n\treturn internet.ListenTCP(ctx, address, port, constructedSetting, callback)\n}\n"
  },
  {
    "path": "transport/internet/request/stereotype/mekya/config.pb.go",
    "content": "package mekya\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tkcp \"github.com/v2fly/v2ray-core/v5/transport/internet/kcp\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\tKcp   *kcp.Config            `protobuf:\"bytes,1,opt,name=kcp,proto3\" json:\"kcp,omitempty\"`\n\t// Client\n\tMaxWriteDelay          int32 `protobuf:\"varint,1003,opt,name=max_write_delay,json=maxWriteDelay,proto3\" json:\"max_write_delay,omitempty\"`\n\tMaxRequestSize         int32 `protobuf:\"varint,1004,opt,name=max_request_size,json=maxRequestSize,proto3\" json:\"max_request_size,omitempty\"`\n\tPollingIntervalInitial int32 `protobuf:\"varint,1005,opt,name=polling_interval_initial,json=pollingIntervalInitial,proto3\" json:\"polling_interval_initial,omitempty\"`\n\t// Server\n\tMaxWriteSize                   int32 `protobuf:\"varint,2003,opt,name=max_write_size,json=maxWriteSize,proto3\" json:\"max_write_size,omitempty\"`\n\tMaxWriteDurationMs             int32 `protobuf:\"varint,2004,opt,name=max_write_duration_ms,json=maxWriteDurationMs,proto3\" json:\"max_write_duration_ms,omitempty\"`\n\tMaxSimultaneousWriteConnection int32 `protobuf:\"varint,2005,opt,name=max_simultaneous_write_connection,json=maxSimultaneousWriteConnection,proto3\" json:\"max_simultaneous_write_connection,omitempty\"`\n\tPacketWritingBuffer            int32 `protobuf:\"varint,2006,opt,name=packet_writing_buffer,json=packetWritingBuffer,proto3\" json:\"packet_writing_buffer,omitempty\"`\n\t// Roundtripper\n\tUrl           string `protobuf:\"bytes,3001,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tH2PoolSize    int32  `protobuf:\"varint,3003,opt,name=h2_pool_size,json=h2PoolSize,proto3\" json:\"h2_pool_size,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_request_stereotype_mekya_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_request_stereotype_mekya_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_request_stereotype_mekya_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetKcp() *kcp.Config {\n\tif x != nil {\n\t\treturn x.Kcp\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetMaxWriteDelay() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteDelay\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetMaxRequestSize() int32 {\n\tif x != nil {\n\t\treturn x.MaxRequestSize\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetPollingIntervalInitial() int32 {\n\tif x != nil {\n\t\treturn x.PollingIntervalInitial\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetMaxWriteSize() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteSize\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetMaxWriteDurationMs() int32 {\n\tif x != nil {\n\t\treturn x.MaxWriteDurationMs\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetMaxSimultaneousWriteConnection() int32 {\n\tif x != nil {\n\t\treturn x.MaxSimultaneousWriteConnection\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetPacketWritingBuffer() int32 {\n\tif x != nil {\n\t\treturn x.PacketWritingBuffer\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetH2PoolSize() int32 {\n\tif x != nil {\n\t\treturn x.H2PoolSize\n\t}\n\treturn 0\n}\n\nvar File_transport_internet_request_stereotype_mekya_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_request_stereotype_mekya_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"8transport/internet/request/stereotype/mekya/config.proto\\x126v2ray.core.transport.internet.request.stereotype.mekya\\x1a common/protoext/extensions.proto\\x1a#transport/internet/kcp/config.proto\\\"\\x82\\x04\\n\" +\n\t\"\\x06Config\\x12;\\n\" +\n\t\"\\x03kcp\\x18\\x01 \\x01(\\v2).v2ray.core.transport.internet.kcp.ConfigR\\x03kcp\\x12'\\n\" +\n\t\"\\x0fmax_write_delay\\x18\\xeb\\a \\x01(\\x05R\\rmaxWriteDelay\\x12)\\n\" +\n\t\"\\x10max_request_size\\x18\\xec\\a \\x01(\\x05R\\x0emaxRequestSize\\x129\\n\" +\n\t\"\\x18polling_interval_initial\\x18\\xed\\a \\x01(\\x05R\\x16pollingIntervalInitial\\x12%\\n\" +\n\t\"\\x0emax_write_size\\x18\\xd3\\x0f \\x01(\\x05R\\fmaxWriteSize\\x122\\n\" +\n\t\"\\x15max_write_duration_ms\\x18\\xd4\\x0f \\x01(\\x05R\\x12maxWriteDurationMs\\x12J\\n\" +\n\t\"!max_simultaneous_write_connection\\x18\\xd5\\x0f \\x01(\\x05R\\x1emaxSimultaneousWriteConnection\\x123\\n\" +\n\t\"\\x15packet_writing_buffer\\x18\\xd6\\x0f \\x01(\\x05R\\x13packetWritingBuffer\\x12\\x11\\n\" +\n\t\"\\x03url\\x18\\xb9\\x17 \\x01(\\tR\\x03url\\x12!\\n\" +\n\t\"\\fh2_pool_size\\x18\\xbb\\x17 \\x01(\\x05R\\n\" +\n\t\"h2PoolSize:\\x1a\\x82\\xb5\\x18\\x16\\n\" +\n\t\"\\ttransport\\x12\\x05mekya\\x90\\xff)\\x01B\\xc3\\x01\\n\" +\n\t\":com.v2ray.core.transport.internet.request.stereotype.mekyaP\\x01ZJgithub.com/v2fly/v2ray-core/v5/transport/internet/request/stereotype/mekya\\xaa\\x026V2Ray.Core.Transport.Internet.Request.Stereotype.Mekyab\\x06proto3\"\n\nvar (\n\tfile_transport_internet_request_stereotype_mekya_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_request_stereotype_mekya_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_request_stereotype_mekya_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_request_stereotype_mekya_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_request_stereotype_mekya_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_request_stereotype_mekya_config_proto_rawDesc), len(file_transport_internet_request_stereotype_mekya_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_request_stereotype_mekya_config_proto_rawDescData\n}\n\nvar file_transport_internet_request_stereotype_mekya_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_request_stereotype_mekya_config_proto_goTypes = []any{\n\t(*Config)(nil),     // 0: v2ray.core.transport.internet.request.stereotype.mekya.Config\n\t(*kcp.Config)(nil), // 1: v2ray.core.transport.internet.kcp.Config\n}\nvar file_transport_internet_request_stereotype_mekya_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.request.stereotype.mekya.Config.kcp:type_name -> v2ray.core.transport.internet.kcp.Config\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_request_stereotype_mekya_config_proto_init() }\nfunc file_transport_internet_request_stereotype_mekya_config_proto_init() {\n\tif File_transport_internet_request_stereotype_mekya_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_request_stereotype_mekya_config_proto_rawDesc), len(file_transport_internet_request_stereotype_mekya_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_request_stereotype_mekya_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_request_stereotype_mekya_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_request_stereotype_mekya_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_request_stereotype_mekya_config_proto = out.File\n\tfile_transport_internet_request_stereotype_mekya_config_proto_goTypes = nil\n\tfile_transport_internet_request_stereotype_mekya_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/request/stereotype/mekya/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.request.stereotype.mekya;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Request.Stereotype.Mekya\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/request/stereotype/mekya\";\noption java_package = \"com.v2ray.core.transport.internet.request.stereotype.mekya\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nimport \"transport/internet/kcp/config.proto\";\n\nmessage Config{\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"mekya\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n\n  v2ray.core.transport.internet.kcp.Config kcp = 1;\n\n  // Client\n  int32 max_write_delay = 1003;\n  int32 max_request_size = 1004;\n  int32 polling_interval_initial = 1005;\n\n  // Server\n  int32 max_write_size = 2003;\n  int32 max_write_duration_ms = 2004;\n  int32 max_simultaneous_write_connection = 2005;\n  int32 packet_writing_buffer = 2006;\n\n  // Roundtripper\n  string url = 3001;\n  int32 h2_pool_size = 3003;\n}"
  },
  {
    "path": "transport/internet/request/stereotype/mekya/errors.generated.go",
    "content": "package mekya\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/request/stereotype/mekya/mekya.go",
    "content": "package mekya\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembler/packetconn\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/assembly\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request/roundtripper/httprt\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst protocolName = \"mekya\"\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn nil, newError(\"meek is a transport\")\n\t}))\n\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, mekyaDial))\n\tcommon.Must(internet.RegisterTransportListener(protocolName, mekyaListen))\n}\n\nfunc mekyaDial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tmekyaSetting := streamSettings.ProtocolSettings.(*Config)\n\tpacketConnAssembler := &packetconn.ClientConfig{}\n\tpacketConnAssembler.PollingIntervalInitial = mekyaSetting.PollingIntervalInitial\n\tpacketConnAssembler.MaxRequestSize = mekyaSetting.MaxRequestSize\n\tpacketConnAssembler.MaxWriteDelay = mekyaSetting.MaxWriteDelay\n\tpacketConnAssembler.UnderlyingTransportName = \"kcp\"\n\tpacketConnAssembler.UnderlyingTransportSetting = serial.ToTypedMessage(mekyaSetting.Kcp)\n\n\thttprtSetting := &httprt.ClientConfig{\n\t\tHttp: &httprt.HTTPConfig{\n\t\t\tUrlPrefix: mekyaSetting.Url,\n\t\t},\n\t\tH2PoolSize: mekyaSetting.H2PoolSize,\n\t}\n\n\trequest := &assembly.Config{\n\t\tAssembler:    serial.ToTypedMessage(packetConnAssembler),\n\t\tRoundtripper: serial.ToTypedMessage(httprtSetting),\n\t}\n\n\tconstructedSetting := &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"request\",\n\t\tProtocolSettings: request,\n\t\tSecurityType:     streamSettings.SecurityType,\n\t\tSecuritySettings: streamSettings.SecuritySettings,\n\t\tSocketSettings:   streamSettings.SocketSettings,\n\t}\n\n\treturn internet.Dial(ctx, dest, constructedSetting)\n}\n\nfunc mekyaListen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, callback internet.ConnHandler) (internet.Listener, error) {\n\tmekyaSetting := streamSettings.ProtocolSettings.(*Config)\n\tpacketConnAssembler := &packetconn.ServerConfig{}\n\tpacketConnAssembler.MaxWriteSize = mekyaSetting.MaxWriteSize\n\tpacketConnAssembler.MaxSimultaneousWriteConnection = mekyaSetting.MaxSimultaneousWriteConnection\n\tpacketConnAssembler.MaxWriteDurationMs = mekyaSetting.MaxWriteDurationMs\n\tpacketConnAssembler.PacketWritingBuffer = mekyaSetting.PacketWritingBuffer\n\tpacketConnAssembler.UnderlyingTransportName = \"kcp\"\n\tpacketConnAssembler.UnderlyingTransportSetting = serial.ToTypedMessage(mekyaSetting.Kcp)\n\n\trequest := &assembly.Config{\n\t\tAssembler:    serial.ToTypedMessage(packetConnAssembler),\n\t\tRoundtripper: serial.ToTypedMessage(&httprt.ServerConfig{}),\n\t}\n\n\tconstructedSetting := &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"request\",\n\t\tProtocolSettings: request,\n\t\tSecurityType:     streamSettings.SecurityType,\n\t\tSecuritySettings: streamSettings.SecuritySettings,\n\t\tSocketSettings:   streamSettings.SocketSettings,\n\t}\n\n\treturn internet.ListenTCP(ctx, address, port, constructedSetting, callback)\n}\n"
  },
  {
    "path": "transport/internet/security/connprop.go",
    "content": "package security\n\ntype ConnectionApplicationProtocol interface {\n\tGetConnectionApplicationProtocol() (string, error)\n}\n"
  },
  {
    "path": "transport/internet/security/errors.generated.go",
    "content": "package security\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/security/security.go",
    "content": "package security\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype Engine interface {\n\tClient(conn net.Conn, opts ...Option) (Conn, error)\n}\n\ntype Conn interface {\n\tnet.Conn\n}\n\ntype Option interface {\n\tisSecurityOption()\n}\n\ntype OptionWithALPN struct {\n\tALPNs []string\n}\n\nfunc (a OptionWithALPN) isSecurityOption() {\n}\n\ntype OptionWithDestination struct {\n\tDest net.Destination\n}\n\nfunc (a OptionWithDestination) isSecurityOption() {\n}\n"
  },
  {
    "path": "transport/internet/security/util.go",
    "content": "package security\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc CreateSecurityEngineFromSettings(context context.Context, settings *internet.MemoryStreamConfig) (Engine, error) {\n\tif settings == nil || settings.SecurityType == \"\" {\n\t\treturn nil, nil\n\t}\n\tsecurityEngine, err := common.CreateObject(context, settings.SecuritySettings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create security engine from security settings\").Base(err)\n\t}\n\tsecurityEngineTyped, ok := securityEngine.(Engine)\n\tif !ok {\n\t\treturn nil, newError(\"type assertion error when create security engine from security settings\")\n\t}\n\treturn securityEngineTyped, nil\n}\n"
  },
  {
    "path": "transport/internet/socket_activation_other.go",
    "content": "//go:build !unix\n// +build !unix\n\npackage internet\n\nimport (\n\t\"fmt\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc activateSocket(address string, f func(network, address string, fd uintptr)) (net.Listener, error) {\n\treturn nil, fmt.Errorf(\"socket activation is not supported on this platform\")\n}\n"
  },
  {
    "path": "transport/internet/socket_activation_unix.go",
    "content": "//go:build unix\n// +build unix\n\npackage internet\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n\t\"syscall\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc activateSocket(address string, f func(network, address string, fd uintptr)) (net.Listener, error) {\n\tfd, err := strconv.Atoi(path.Base(address))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = syscall.SetNonblock(fd, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tacceptConn, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ACCEPTCONN)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif acceptConn == 0 {\n\t\treturn nil, fmt.Errorf(\"socket '%s' has not been marked to accept connections\", address)\n\t}\n\n\tsockType, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif sockType != syscall.SOCK_STREAM {\n\t\t// XXX: currently only stream socks are supported\n\t\treturn nil, fmt.Errorf(\"socket '%s' is not a stream socket\", address)\n\t}\n\n\tufd := uintptr(fd)\n\n\tsa, err := syscall.Getsockname(fd)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch sa := sa.(type) {\n\tcase *syscall.SockaddrInet4:\n\t\taddr := net.TCPAddr{IP: sa.Addr[:], Port: sa.Port, Zone: \"\"}\n\t\tf(\"tcp4\", addr.String(), ufd)\n\tcase *syscall.SockaddrInet6:\n\t\taddr := net.TCPAddr{IP: sa.Addr[:], Port: sa.Port, Zone: strconv.Itoa(int(sa.ZoneId))}\n\t\tf(\"tcp6\", addr.String(), ufd)\n\t}\n\n\tfile := os.NewFile(ufd, address)\n\tdefer file.Close()\n\n\treturn net.FileListener(file)\n}\n"
  },
  {
    "path": "transport/internet/sockopt.go",
    "content": "package internet\n\nfunc isTCPSocket(network string) bool {\n\tswitch network {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc isUDPSocket(network string) bool {\n\tswitch network {\n\tcase \"udp\", \"udp4\", \"udp6\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "transport/internet/sockopt_darwin.go",
    "content": "package internet\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\t// TCP_FASTOPEN_SERVER is the value to enable TCP fast open on darwin for server connections.\n\tTCP_FASTOPEN_SERVER = 0x01 // nolint: revive,stylecheck\n\t// TCP_FASTOPEN_CLIENT is the value to enable TCP fast open on darwin for client connections.\n\tTCP_FASTOPEN_CLIENT = 0x02 // nolint: revive,stylecheck\n)\n\nfunc applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {\n\tif isTCPSocket(network) {\n\t\tswitch config.Tfo {\n\t\tcase SocketConfig_Enable:\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, TCP_FASTOPEN_CLIENT); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase SocketConfig_Disable:\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPINTVL\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveIdle)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPALIVE (TCP keepalive idle time on Darwin)\").Base(err)\n\t\t\t}\n\t\t}\n\n\t\tif config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.BindToDevice != \"\" {\n\t\tiface, err := net.InterfaceByName(config.BindToDevice)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get interface \", config.BindToDevice).Base(err)\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index); err != nil {\n\t\t\treturn newError(\"failed to set IP_BOUND_IF\", err)\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index); err != nil {\n\t\t\treturn newError(\"failed to set IPV6_BOUND_IF\", err)\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, int(config.RxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {\n\tif isTCPSocket(network) {\n\t\tswitch config.Tfo {\n\t\tcase SocketConfig_Enable:\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, TCP_FASTOPEN_SERVER); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase SocketConfig_Disable:\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPINTVL\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveIdle)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPALIVE (TCP keepalive idle time on Darwin)\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.BindToDevice != \"\" {\n\t\tiface, err := net.InterfaceByName(config.BindToDevice)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get interface \", config.BindToDevice).Base(err)\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index); err != nil {\n\t\t\treturn newError(\"failed to set IP_BOUND_IF\", err)\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, iface.Index); err != nil {\n\t\t\treturn newError(\"failed to set IPV6_BOUND_IF\", err)\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF/SO_SNDBUFFORCE\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, int(config.RxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF/SO_RCVBUFFORCE\").Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc bindAddr(fd uintptr, address []byte, port uint32) error {\n\treturn nil\n}\n\nfunc setReuseAddr(fd uintptr) error {\n\treturn nil\n}\n\nfunc setReusePort(fd uintptr) error {\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/sockopt_freebsd.go",
    "content": "package internet\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\tsysPFINOUT     = 0x0\n\tsysPFIN        = 0x1\n\tsysPFOUT       = 0x2\n\tsysPFFWD       = 0x3\n\tsysDIOCNATLOOK = 0xc04c4417\n)\n\ntype pfiocNatlook struct {\n\tSaddr     [16]byte /* pf_addr */\n\tDaddr     [16]byte /* pf_addr */\n\tRsaddr    [16]byte /* pf_addr */\n\tRdaddr    [16]byte /* pf_addr */\n\tSport     uint16\n\tDport     uint16\n\tRsport    uint16\n\tRdport    uint16\n\tAf        uint8\n\tProto     uint8\n\tDirection uint8\n\tPad       [1]byte\n}\n\nconst (\n\tsizeofPfiocNatlook = 0x4c\n\tsoReUsePort        = 0x00000200\n\tsoReUsePortLB      = 0x00010000\n)\n\nfunc ioctl(s uintptr, ioc int, b []byte) error {\n\tif _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, s, uintptr(ioc), uintptr(unsafe.Pointer(&b[0]))); errno != 0 {\n\t\treturn error(errno)\n\t}\n\treturn nil\n}\n\nfunc (nl *pfiocNatlook) rdPort() int {\n\treturn int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&nl.Rdport))[:]))\n}\n\nfunc (nl *pfiocNatlook) setPort(remote, local int) {\n\tbinary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Sport))[:], uint16(remote))\n\tbinary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Dport))[:], uint16(local))\n}\n\n// OriginalDst uses ioctl to read original destination from /dev/pf\nfunc OriginalDst(la, ra net.Addr) (net.IP, int, error) {\n\tf, err := os.Open(\"/dev/pf\")\n\tif err != nil {\n\t\treturn net.IP{}, -1, newError(\"failed to open device /dev/pf\").Base(err)\n\t}\n\tdefer f.Close()\n\tfd := f.Fd()\n\tb := make([]byte, sizeofPfiocNatlook)\n\tnl := (*pfiocNatlook)(unsafe.Pointer(&b[0]))\n\tvar raIP, laIP net.IP\n\tvar raPort, laPort int\n\tswitch la.(type) {\n\tcase *net.TCPAddr:\n\t\traIP = ra.(*net.TCPAddr).IP\n\t\tlaIP = la.(*net.TCPAddr).IP\n\t\traPort = ra.(*net.TCPAddr).Port\n\t\tlaPort = la.(*net.TCPAddr).Port\n\t\tnl.Proto = syscall.IPPROTO_TCP\n\tcase *net.UDPAddr:\n\t\traIP = ra.(*net.UDPAddr).IP\n\t\tlaIP = la.(*net.UDPAddr).IP\n\t\traPort = ra.(*net.UDPAddr).Port\n\t\tlaPort = la.(*net.UDPAddr).Port\n\t\tnl.Proto = syscall.IPPROTO_UDP\n\t}\n\tif raIP.To4() != nil {\n\t\tif laIP.IsUnspecified() {\n\t\t\tlaIP = net.ParseIP(\"127.0.0.1\")\n\t\t}\n\t\tcopy(nl.Saddr[:net.IPv4len], raIP.To4())\n\t\tcopy(nl.Daddr[:net.IPv4len], laIP.To4())\n\t\tnl.Af = syscall.AF_INET\n\t}\n\tif raIP.To16() != nil && raIP.To4() == nil {\n\t\tif laIP.IsUnspecified() {\n\t\t\tlaIP = net.ParseIP(\"::1\")\n\t\t}\n\t\tcopy(nl.Saddr[:], raIP)\n\t\tcopy(nl.Daddr[:], laIP)\n\t\tnl.Af = syscall.AF_INET6\n\t}\n\tnl.setPort(raPort, laPort)\n\tioc := uintptr(sysDIOCNATLOOK)\n\tfor _, dir := range []byte{sysPFOUT, sysPFIN} {\n\t\tnl.Direction = dir\n\t\terr = ioctl(fd, int(ioc), b)\n\t\tif err == nil || err != syscall.ENOENT {\n\t\t\tbreak\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn net.IP{}, -1, os.NewSyscallError(\"ioctl\", err)\n\t}\n\n\todPort := nl.rdPort()\n\tvar odIP net.IP\n\tswitch nl.Af {\n\tcase syscall.AF_INET:\n\t\todIP = make(net.IP, net.IPv4len)\n\t\tcopy(odIP, nl.Rdaddr[:net.IPv4len])\n\tcase syscall.AF_INET6:\n\t\todIP = make(net.IP, net.IPv6len)\n\t\tcopy(odIP, nl.Rdaddr[:])\n\t}\n\treturn odIP, odPort, nil\n}\n\nfunc applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {\n\tif config.Mark != 0 {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_USER_COOKIE, int(config.Mark)); err != nil {\n\t\t\treturn newError(\"failed to set SO_USER_COOKIE\").Base(err)\n\t\t}\n\t}\n\n\tif isTCPSocket(network) {\n\t\tswitch config.Tfo {\n\t\tcase SocketConfig_Enable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN_CONNECT=1\").Base(err)\n\t\t\t}\n\t\tcase SocketConfig_Disable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN_CONNECT=0\").Base(err)\n\t\t\t}\n\t\t}\n\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPIDLE\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPINTVL\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.Tproxy.IsEnabled() {\n\t\tip, _, _ := net.SplitHostPort(address)\n\t\tif net.ParseIP(ip).To4() != nil {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BINDANY, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set outbound IP_BINDANY\").Base(err)\n\t\t\t}\n\t\t} else {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BINDANY, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set outbound IPV6_BINDANY\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, int(config.RxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {\n\tif config.Mark != 0 {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_USER_COOKIE, int(config.Mark)); err != nil {\n\t\t\treturn newError(\"failed to set SO_USER_COOKIE\").Base(err)\n\t\t}\n\t}\n\tif isTCPSocket(network) {\n\t\tswitch config.Tfo {\n\t\tcase SocketConfig_Enable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN=1\").Base(err)\n\t\t\t}\n\t\tcase SocketConfig_Disable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_FASTOPEN, 0); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN=0\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPIDLE\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPINTVL\").Base(err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.Tproxy.IsEnabled() {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BINDANY, 1); err != nil {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BINDANY, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set inbound IP_BINDANY\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF, int(config.RxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc bindAddr(fd uintptr, ip []byte, port uint32) error {\n\tsetReuseAddr(fd)\n\tsetReusePort(fd)\n\n\tvar sockaddr syscall.Sockaddr\n\n\tswitch len(ip) {\n\tcase net.IPv4len:\n\t\ta4 := &syscall.SockaddrInet4{\n\t\t\tPort: int(port),\n\t\t}\n\t\tcopy(a4.Addr[:], ip)\n\t\tsockaddr = a4\n\tcase net.IPv6len:\n\t\ta6 := &syscall.SockaddrInet6{\n\t\t\tPort: int(port),\n\t\t}\n\t\tcopy(a6.Addr[:], ip)\n\t\tsockaddr = a6\n\tdefault:\n\t\treturn newError(\"unexpected length of ip\")\n\t}\n\n\treturn syscall.Bind(int(fd), sockaddr)\n}\n\nfunc setReuseAddr(fd uintptr) error {\n\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {\n\t\treturn newError(\"failed to set SO_REUSEADDR\").Base(err).AtWarning()\n\t}\n\treturn nil\n}\n\nfunc setReusePort(fd uintptr) error {\n\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, soReUsePortLB, 1); err != nil {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, soReUsePort, 1); err != nil {\n\t\t\treturn newError(\"failed to set SO_REUSEPORT\").Base(err).AtWarning()\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/sockopt_linux.go",
    "content": "package internet\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\t// For incoming connections.\n\tTCP_FASTOPEN = 23 // nolint: revive,stylecheck\n\t// For out-going connections.\n\tTCP_FASTOPEN_CONNECT = 30 // nolint: revive,stylecheck\n)\n\nfunc bindAddr(fd uintptr, ip []byte, port uint32) error {\n\tsetReuseAddr(fd)\n\tsetReusePort(fd)\n\n\tvar sockaddr syscall.Sockaddr\n\n\tswitch len(ip) {\n\tcase net.IPv4len:\n\t\ta4 := &syscall.SockaddrInet4{\n\t\t\tPort: int(port),\n\t\t}\n\t\tcopy(a4.Addr[:], ip)\n\t\tsockaddr = a4\n\tcase net.IPv6len:\n\t\ta6 := &syscall.SockaddrInet6{\n\t\t\tPort: int(port),\n\t\t}\n\t\tcopy(a6.Addr[:], ip)\n\t\tsockaddr = a6\n\tdefault:\n\t\treturn newError(\"unexpected length of ip\")\n\t}\n\n\treturn syscall.Bind(int(fd), sockaddr)\n}\n\nfunc applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {\n\tif config.Mark != 0 {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, int(config.Mark)); err != nil {\n\t\t\treturn newError(\"failed to set SO_MARK\").Base(err)\n\t\t}\n\t}\n\n\tif isTCPSocket(network) {\n\t\tswitch config.Tfo {\n\t\tcase SocketConfig_Enable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN_CONNECT=1\").Base(err)\n\t\t\t}\n\t\tcase SocketConfig_Disable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN_CONNECT, 0); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN_CONNECT=0\").Base(err)\n\t\t\t}\n\t\t}\n\n\t\tif config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPINTVL\", err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPIDLE\", err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\").Base(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.Tproxy.IsEnabled() {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {\n\t\t\treturn newError(\"failed to set IP_TRANSPARENT\").Base(err)\n\t\t}\n\t}\n\n\tif config.BindToDevice != \"\" {\n\t\tif err := unix.BindToDevice(int(fd), config.BindToDevice); err != nil {\n\t\t\treturn newError(\"failed to set SO_BINDTODEVICE\").Base(err)\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tsyscallTarget := unix.SO_SNDBUF\n\t\tif config.ForceBufSize {\n\t\t\tsyscallTarget = unix.SO_SNDBUFFORCE\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, syscallTarget, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF/SO_SNDBUFFORCE\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tsyscallTarget := unix.SO_RCVBUF\n\t\tif config.ForceBufSize {\n\t\t\tsyscallTarget = unix.SO_RCVBUFFORCE\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, syscallTarget, int(config.RxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF/SO_RCVBUFFORCE\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {\n\tif config.Mark != 0 {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, int(config.Mark)); err != nil {\n\t\t\treturn newError(\"failed to set SO_MARK\").Base(err)\n\t\t}\n\t}\n\tif isTCPSocket(network) {\n\t\tswitch config.Tfo {\n\t\tcase SocketConfig_Enable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, int(config.TfoQueueLength)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN=\", config.TfoQueueLength).Base(err)\n\t\t\t}\n\t\tcase SocketConfig_Disable:\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_TCP, TCP_FASTOPEN, 0); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_FASTOPEN=0\").Base(err)\n\t\t\t}\n\t\t}\n\n\t\tif config.TcpKeepAliveInterval > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPINTVL\", err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil {\n\t\t\t\treturn newError(\"failed to set TCP_KEEPIDLE\", err)\n\t\t\t}\n\t\t}\n\t\tif config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.Tproxy.IsEnabled() {\n\t\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {\n\t\t\treturn newError(\"failed to set IP_TRANSPARENT\").Base(err)\n\t\t}\n\t}\n\n\tif config.ReceiveOriginalDestAddress && isUDPSocket(network) {\n\t\terr1 := syscall.SetsockoptInt(int(fd), syscall.SOL_IPV6, unix.IPV6_RECVORIGDSTADDR, 1)\n\t\terr2 := syscall.SetsockoptInt(int(fd), syscall.SOL_IP, syscall.IP_RECVORIGDSTADDR, 1)\n\t\tif err1 != nil && err2 != nil {\n\t\t\treturn err1\n\t\t}\n\t}\n\n\tif config.BindToDevice != \"\" {\n\t\tif err := unix.BindToDevice(int(fd), config.BindToDevice); err != nil {\n\t\t\treturn newError(\"failed to set SO_BINDTODEVICE\").Base(err)\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tsyscallTarget := unix.SO_SNDBUF\n\t\tif config.ForceBufSize {\n\t\t\tsyscallTarget = unix.SO_SNDBUFFORCE\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, syscallTarget, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF/SO_SNDBUFFORCE\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tsyscallTarget := unix.SO_RCVBUF\n\t\tif config.ForceBufSize {\n\t\t\tsyscallTarget = unix.SO_RCVBUFFORCE\n\t\t}\n\t\tif err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, syscallTarget, int(config.RxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF/SO_RCVBUFFORCE\").Base(err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc setReuseAddr(fd uintptr) error {\n\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {\n\t\treturn newError(\"failed to set SO_REUSEADDR\").Base(err).AtWarning()\n\t}\n\treturn nil\n}\n\nfunc setReusePort(fd uintptr) error {\n\tif err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {\n\t\treturn newError(\"failed to set SO_REUSEPORT\").Base(err).AtWarning()\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/sockopt_linux_test.go",
    "content": "package internet_test\n\nimport (\n\t\"context\"\n\t\"syscall\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc TestSockOptMark(t *testing.T) {\n\tt.Skip(\"requires CAP_NET_ADMIN\")\n\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: func(b []byte) []byte {\n\t\t\treturn b\n\t\t},\n\t}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tconst mark = 1\n\tdialer := DefaultSystemDialer{}\n\tconn, err := dialer.Dial(context.Background(), nil, dest, &SocketConfig{Mark: mark})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\trawConn, err := conn.(*net.TCPConn).SyscallConn()\n\tcommon.Must(err)\n\terr = rawConn.Control(func(fd uintptr) {\n\t\tm, err := syscall.GetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK)\n\t\tcommon.Must(err)\n\t\tif mark != m {\n\t\t\tt.Fatal(\"unexpected connection mark\", m, \" want \", mark)\n\t\t}\n\t})\n\tcommon.Must(err)\n}\n"
  },
  {
    "path": "transport/internet/sockopt_other.go",
    "content": "//go:build js || dragonfly || netbsd || openbsd || solaris\n// +build js dragonfly netbsd openbsd solaris\n\npackage internet\n\nfunc applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {\n\treturn nil\n}\n\nfunc applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {\n\treturn nil\n}\n\nfunc bindAddr(fd uintptr, ip []byte, port uint32) error {\n\treturn nil\n}\n\nfunc setReuseAddr(fd uintptr) error {\n\treturn nil\n}\n\nfunc setReusePort(fd uintptr) error {\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/sockopt_test.go",
    "content": "package internet_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc TestTCPFastOpen(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: func(b []byte) []byte {\n\t\t\treturn b\n\t\t},\n\t}\n\tdest, err := tcpServer.StartContext(context.Background(), &SocketConfig{Tfo: SocketConfig_Enable})\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tctx := context.Background()\n\tdialer := DefaultSystemDialer{}\n\tconn, err := dialer.Dial(ctx, nil, dest, &SocketConfig{\n\t\tTfo: SocketConfig_Enable,\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\t_, err = conn.Write([]byte(\"abcd\"))\n\tcommon.Must(err)\n\n\tb := buf.New()\n\tcommon.Must2(b.ReadFrom(conn))\n\tif r := cmp.Diff(b.Bytes(), []byte(\"abcd\")); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n\n// Currently, Multipath TCP is only supported on Linux.\n// We test the Multipath TCP Settings on other platforms for ensure code will not have any negative impact on other platforms.\nfunc TestMultipathTCP(t *testing.T) {\n\ttcpServer := tcp.Server{\n\t\tMsgProcessor: func(b []byte) []byte {\n\t\t\treturn b\n\t\t},\n\t}\n\tdest, err := tcpServer.StartContext(context.Background(), &SocketConfig{Mptcp: MPTCPState_Enable})\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tctx := context.Background()\n\tdialer := DefaultSystemDialer{}\n\tconn, err := dialer.Dial(ctx, nil, dest, &SocketConfig{\n\t\tMptcp: MPTCPState_Enable,\n\t})\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\t_, err = conn.Write([]byte(\"abcd\"))\n\tcommon.Must(err)\n\n\tb := buf.New()\n\tcommon.Must2(b.ReadFrom(conn))\n\tif r := cmp.Diff(b.Bytes(), []byte(\"abcd\")); r != \"\" {\n\t\tt.Fatal(r)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/sockopt_windows.go",
    "content": "package internet\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nconst (\n\tTCP_FASTOPEN    = 15 // nolint: revive,stylecheck\n\tIP_UNICAST_IF   = 31 // nolint: revive,stylecheck\n\tIPV6_UNICAST_IF = 31 // nolint: revive,stylecheck\n)\n\nfunc setTFO(fd syscall.Handle, settings SocketConfig_TCPFastOpenState) error {\n\tswitch settings {\n\tcase SocketConfig_Enable:\n\t\tif err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, 1); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase SocketConfig_Disable:\n\t\tif err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, TCP_FASTOPEN, 0); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {\n\tif isTCPSocket(network) {\n\t\tif err := setTFO(syscall.Handle(fd), config.Tfo); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.BindToDevice != \"\" {\n\t\tiface, err := net.InterfaceByName(config.BindToDevice)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get interface \", config.BindToDevice).Base(err)\n\t\t}\n\t\tif err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_UNICAST_IF, iface.Index); err != nil {\n\t\t\treturn newError(\"failed to set IP_UNICAST_IF\", err)\n\t\t}\n\t\tif err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_UNICAST_IF, iface.Index); err != nil {\n\t\t\treturn newError(\"failed to set IPV6_UNICAST_IF\", err)\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tif err := windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_SNDBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tif err := windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_RCVBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) error {\n\tif isTCPSocket(network) {\n\t\tif err := setTFO(syscall.Handle(fd), config.Tfo); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif config.TcpKeepAliveIdle > 0 {\n\t\t\tif err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {\n\t\t\t\treturn newError(\"failed to set SO_KEEPALIVE\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif config.TxBufSize != 0 {\n\t\tif err := windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_SNDBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_SNDBUF\").Base(err)\n\t\t}\n\t}\n\n\tif config.RxBufSize != 0 {\n\t\tif err := windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_RCVBUF, int(config.TxBufSize)); err != nil {\n\t\t\treturn newError(\"failed to set SO_RCVBUF\").Base(err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc bindAddr(fd uintptr, ip []byte, port uint32) error {\n\treturn nil\n}\n\nfunc setReuseAddr(fd uintptr) error {\n\treturn nil\n}\n\nfunc setReusePort(fd uintptr) error {\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/system_dialer.go",
    "content": "package internet\n\nimport (\n\t\"context\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n)\n\nvar effectiveSystemDialer SystemDialer = &DefaultSystemDialer{}\n\ntype SystemDialer interface {\n\tDial(ctx context.Context, source net.Address, destination net.Destination, sockopt *SocketConfig) (net.Conn, error)\n}\n\ntype DefaultSystemDialer struct {\n\tcontrollers []controller\n}\n\nfunc resolveSrcAddr(network net.Network, src net.Address) net.Addr {\n\tif src == nil || src == net.AnyIP {\n\t\treturn nil\n\t}\n\n\tif network == net.Network_TCP {\n\t\treturn &net.TCPAddr{\n\t\t\tIP:   src.IP(),\n\t\t\tPort: 0,\n\t\t}\n\t}\n\n\treturn &net.UDPAddr{\n\t\tIP:   src.IP(),\n\t\tPort: 0,\n\t}\n}\n\nfunc hasBindAddr(sockopt *SocketConfig) bool {\n\treturn sockopt != nil && len(sockopt.BindAddress) > 0 && sockopt.BindPort > 0\n}\n\nfunc (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {\n\tif dest.Network == net.Network_UDP && !hasBindAddr(sockopt) {\n\t\tsrcAddr := resolveSrcAddr(net.Network_UDP, src)\n\t\tif srcAddr == nil {\n\t\t\tsrcAddr = &net.UDPAddr{\n\t\t\t\tIP:   []byte{0, 0, 0, 0},\n\t\t\t\tPort: 0,\n\t\t\t}\n\t\t}\n\t\tpacketConn, err := ListenSystemPacket(ctx, srcAddr, sockopt)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdestAddr, err := net.ResolveUDPAddr(\"udp\", dest.NetAddr())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &packetConnWrapper{\n\t\t\tconn: packetConn,\n\t\t\tdest: destAddr,\n\t\t}, nil\n\t}\n\tgoStdKeepAlive := time.Duration(0)\n\tif sockopt != nil && (sockopt.TcpKeepAliveInterval != 0 || sockopt.TcpKeepAliveIdle != 0) {\n\t\tgoStdKeepAlive = time.Duration(-1)\n\t}\n\tdialer := &net.Dialer{\n\t\tTimeout:   time.Second * 16,\n\t\tLocalAddr: resolveSrcAddr(dest.Network, src),\n\t\tKeepAlive: goStdKeepAlive,\n\t}\n\n\tif dest.Network == net.Network_TCP && sockopt != nil {\n\t\tswitch sockopt.Mptcp {\n\t\tcase MPTCPState_Enable:\n\t\t\tdialer.SetMultipathTCP(true)\n\t\tcase MPTCPState_Disable:\n\t\t\tdialer.SetMultipathTCP(false)\n\t\t}\n\t}\n\n\tif sockopt != nil || len(d.controllers) > 0 {\n\t\tdialer.Control = func(network, address string, c syscall.RawConn) error {\n\t\t\treturn c.Control(func(fd uintptr) {\n\t\t\t\tif sockopt != nil {\n\t\t\t\t\tif err := applyOutboundSocketOptions(network, address, fd, sockopt); err != nil {\n\t\t\t\t\t\tnewError(\"failed to apply socket options\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t\t}\n\t\t\t\t\tif dest.Network == net.Network_UDP && hasBindAddr(sockopt) {\n\t\t\t\t\t\tif err := bindAddr(fd, sockopt.BindAddress, sockopt.BindPort); err != nil {\n\t\t\t\t\t\t\tnewError(\"failed to bind source address to \", sockopt.BindAddress).Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor _, ctl := range d.controllers {\n\t\t\t\t\tif err := ctl(network, address, fd); err != nil {\n\t\t\t\t\t\tnewError(\"failed to apply external controller\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\treturn dialer.DialContext(ctx, dest.Network.SystemString(), dest.NetAddr())\n}\n\ntype packetConnWrapper struct {\n\tconn net.PacketConn\n\tdest net.Addr\n}\n\nfunc (c *packetConnWrapper) Close() error {\n\treturn c.conn.Close()\n}\n\nfunc (c *packetConnWrapper) LocalAddr() net.Addr {\n\treturn c.conn.LocalAddr()\n}\n\nfunc (c *packetConnWrapper) RemoteAddr() net.Addr {\n\treturn c.dest\n}\n\nfunc (c *packetConnWrapper) Write(p []byte) (int, error) {\n\treturn c.conn.WriteTo(p, c.dest)\n}\n\nfunc (c *packetConnWrapper) Read(p []byte) (int, error) {\n\tn, _, err := c.conn.ReadFrom(p)\n\treturn n, err\n}\n\nfunc (c *packetConnWrapper) SetDeadline(t time.Time) error {\n\treturn c.conn.SetDeadline(t)\n}\n\nfunc (c *packetConnWrapper) SetReadDeadline(t time.Time) error {\n\treturn c.conn.SetReadDeadline(t)\n}\n\nfunc (c *packetConnWrapper) SetWriteDeadline(t time.Time) error {\n\treturn c.conn.SetWriteDeadline(t)\n}\n\ntype SystemDialerAdapter interface {\n\tDial(network string, address string) (net.Conn, error)\n}\n\ntype SimpleSystemDialer struct {\n\tadapter SystemDialerAdapter\n}\n\nfunc WithAdapter(dialer SystemDialerAdapter) SystemDialer {\n\treturn &SimpleSystemDialer{\n\t\tadapter: dialer,\n\t}\n}\n\nfunc (v *SimpleSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {\n\treturn v.adapter.Dial(dest.Network.SystemString(), dest.NetAddr())\n}\n\n// UseAlternativeSystemDialer replaces the current system dialer with a given one.\n// Caller must ensure there is no race condition.\n//\n// v2ray:api:stable\nfunc UseAlternativeSystemDialer(dialer SystemDialer) {\n\tif dialer == nil {\n\t\tdialer = &DefaultSystemDialer{}\n\t}\n\teffectiveSystemDialer = dialer\n}\n\n// RegisterDialerController adds a controller to the effective system dialer.\n// The controller can be used to operate on file descriptors before they are put into use.\n// It only works when effective dialer is the default dialer.\n//\n// v2ray:api:beta\nfunc RegisterDialerController(ctl func(network, address string, fd uintptr) error) error {\n\tif ctl == nil {\n\t\treturn newError(\"nil listener controller\")\n\t}\n\n\tdialer, ok := effectiveSystemDialer.(*DefaultSystemDialer)\n\tif !ok {\n\t\treturn newError(\"RegisterListenerController not supported in custom dialer\")\n\t}\n\n\tdialer.controllers = append(dialer.controllers, ctl)\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/system_dns_android.go",
    "content": "//go:build android\n// +build android\n\npackage internet\n\nimport (\n\t\"context\"\n\t\"net\"\n)\n\nconst SystemDNS = \"8.8.8.8:53\"\n\n/*\nDNSResolverFunc\n\n\tThis is a temporary API and is subject to removal at any time.\n*/\ntype DNSResolverFunc func() *net.Resolver\n\n/*\nNewDNSResolver\n\n\tThis is a temporary API and is subject to removal at any time.\n*/\nvar NewDNSResolver DNSResolverFunc = func() *net.Resolver {\n\treturn &net.Resolver{\n\t\tPreferGo: true,\n\t\tDial: func(ctx context.Context, network, _ string) (net.Conn, error) {\n\t\t\tvar dialer net.Dialer\n\t\t\treturn dialer.DialContext(ctx, network, SystemDNS)\n\t\t},\n\t}\n}\n\nfunc init() {\n\tnet.DefaultResolver = NewDNSResolver()\n}\n"
  },
  {
    "path": "transport/internet/system_dns_android_test.go",
    "content": "//go:build android\n// +build android\n\npackage internet\n\nimport (\n\t\"context\"\n\t\"testing\"\n)\n\nfunc TestDNSResolver(t *testing.T) {\n\tresolver := NewDNSResolver()\n\tif ips, err := resolver.LookupIP(context.Background(), \"ip\", \"www.google.com\"); err != nil {\n\t\tt.Errorf(\"failed to lookupIP, %v, %v\", ips, err)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/system_listener.go",
    "content": "package internet\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/pires/go-proxyproto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n)\n\nvar effectiveListener = DefaultListener{}\n\ntype controller func(network, address string, fd uintptr) error\n\ntype DefaultListener struct {\n\tcontrollers []controller\n}\n\ntype combinedListener struct {\n\tnet.Listener\n\tlocker *FileLocker // for unix domain socket\n}\n\nfunc (l *combinedListener) Close() error {\n\tif l.locker != nil {\n\t\tl.locker.Release()\n\t\tl.locker = nil\n\t}\n\treturn l.Listener.Close()\n}\n\nfunc getRawControlFunc(network, address string, ctx context.Context, sockopt *SocketConfig, controllers []controller) func(fd uintptr) {\n\treturn func(fd uintptr) {\n\t\tif sockopt != nil {\n\t\t\tif err := applyInboundSocketOptions(network, fd, sockopt); err != nil {\n\t\t\t\tnewError(\"failed to apply socket options to incoming connection\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t}\n\t\t}\n\n\t\tsetReusePort(fd) // nolint: staticcheck\n\n\t\tfor _, controller := range controllers {\n\t\t\tif err := controller(network, address, fd); err != nil {\n\t\t\t\tnewError(\"failed to apply external controller\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc getControlFunc(ctx context.Context, sockopt *SocketConfig, controllers []controller) func(network, address string, c syscall.RawConn) error {\n\treturn func(network, address string, c syscall.RawConn) error {\n\t\treturn c.Control(getRawControlFunc(network, address, ctx, sockopt, controllers))\n\t}\n}\n\nfunc (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error) {\n\tvar lc net.ListenConfig\n\tvar network, address string\n\tvar l net.Listener\n\tvar err error\n\t// callback is called after the Listen function returns\n\t// this is used to wrap the listener and do some post processing\n\tcallback := func(l net.Listener, err error) (net.Listener, error) {\n\t\treturn l, err\n\t}\n\tswitch addr := addr.(type) {\n\tcase *net.TCPAddr:\n\t\tnetwork = addr.Network()\n\t\taddress = addr.String()\n\t\tlc.Control = getControlFunc(ctx, sockopt, dl.controllers)\n\t\tif sockopt != nil {\n\t\t\tswitch sockopt.Mptcp {\n\t\t\tcase MPTCPState_Enable:\n\t\t\t\tlc.SetMultipathTCP(true)\n\t\t\tcase MPTCPState_Disable:\n\t\t\t\tlc.SetMultipathTCP(false)\n\t\t\t}\n\n\t\t\tif sockopt.TcpKeepAliveInterval != 0 || sockopt.TcpKeepAliveIdle != 0 {\n\t\t\t\tlc.KeepAlive = time.Duration(-1)\n\t\t\t}\n\t\t}\n\tcase *net.UnixAddr:\n\t\tlc.Control = nil\n\t\tnetwork = addr.Network()\n\t\taddress = addr.Name\n\t\tif (runtime.GOOS == \"linux\" || runtime.GOOS == \"android\") && address[0] == '@' { //nolint: gocritic\n\t\t\t// linux abstract unix domain socket is lockfree\n\t\t\tif len(address) > 1 && address[1] == '@' {\n\t\t\t\t// but may need padding to work with haproxy\n\t\t\t\tfullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path))\n\t\t\t\tcopy(fullAddr, address[1:])\n\t\t\t\taddress = string(fullAddr)\n\t\t\t}\n\t\t} else if strings.HasPrefix(address, \"/dev/fd/\") {\n\t\t\t// socket activation\n\t\t\tl, err = activateSocket(address, func(network, address string, fd uintptr) {\n\t\t\t\tgetRawControlFunc(network, address, ctx, sockopt, dl.controllers)(fd)\n\t\t\t})\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// normal unix domain socket\n\t\t\tvar fileMode *os.FileMode\n\t\t\t// parse file mode from address\n\t\t\tif s := strings.Split(address, \",\"); len(s) == 2 {\n\t\t\t\tfMode, err := strconv.ParseUint(s[1], 8, 32)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, newError(\"failed to parse file mode\").Base(err)\n\t\t\t\t}\n\t\t\t\taddress = s[0]\n\t\t\t\tfm := os.FileMode(fMode)\n\t\t\t\tfileMode = &fm\n\t\t\t}\n\t\t\t// normal unix domain socket needs lock\n\t\t\tlocker := &FileLocker{\n\t\t\t\tpath: address + \".lock\",\n\t\t\t}\n\t\t\tif err := locker.Acquire(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// set file mode for unix domain socket when it is created\n\t\t\tcallback = func(l net.Listener, err error) (net.Listener, error) {\n\t\t\t\tif err != nil {\n\t\t\t\t\tlocker.Release()\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tl = &combinedListener{Listener: l, locker: locker}\n\t\t\t\tif fileMode == nil {\n\t\t\t\t\treturn l, err\n\t\t\t\t}\n\t\t\t\tif cerr := os.Chmod(address, *fileMode); cerr != nil {\n\t\t\t\t\t// failed to set file mode, close the listener\n\t\t\t\t\tl.Close()\n\t\t\t\t\treturn nil, newError(\"failed to set file mode for file: \", address).Base(cerr)\n\t\t\t\t}\n\t\t\t\treturn l, err\n\t\t\t}\n\t\t}\n\t}\n\n\tif l == nil {\n\t\tl, err = lc.Listen(ctx, network, address)\n\t\tl, err = callback(l, err)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif sockopt != nil && sockopt.AcceptProxyProtocol {\n\t\tpolicyFunc := func(upstream net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil }\n\t\tl = &proxyproto.Listener{Listener: l, Policy: policyFunc}\n\t}\n\treturn l, nil\n}\n\nfunc (dl *DefaultListener) ListenPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error) {\n\tvar lc net.ListenConfig\n\n\tlc.Control = getControlFunc(ctx, sockopt, dl.controllers)\n\n\treturn lc.ListenPacket(ctx, addr.Network(), addr.String())\n}\n\n// RegisterListenerController adds a controller to the effective system listener.\n// The controller can be used to operate on file descriptors before they are put into use.\n//\n// v2ray:api:beta\nfunc RegisterListenerController(controller func(network, address string, fd uintptr) error) error {\n\tif controller == nil {\n\t\treturn newError(\"nil listener controller\")\n\t}\n\n\teffectiveListener.controllers = append(effectiveListener.controllers, controller)\n\treturn nil\n}\n\ntype SystemListener interface {\n\tListen(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error)\n\tListenPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error)\n}\n"
  },
  {
    "path": "transport/internet/system_listener_test.go",
    "content": "package internet_test\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc TestRegisterListenerController(t *testing.T) {\n\tvar gotFd uintptr\n\n\tcommon.Must(internet.RegisterListenerController(func(network string, addr string, fd uintptr) error {\n\t\tgotFd = fd\n\t\treturn nil\n\t}))\n\n\tconn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{\n\t\tIP: net.IPv4zero,\n\t}, nil)\n\tcommon.Must(err)\n\tcommon.Must(conn.Close())\n\n\tif gotFd == 0 {\n\t\tt.Error(\"expected none-zero fd, but actually 0\")\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tagged/tagged.go",
    "content": "package tagged\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype DialFunc func(ctx context.Context, dest net.Destination, tag string) (net.Conn, error)\n\nvar Dialer DialFunc\n"
  },
  {
    "path": "transport/internet/tagged/taggedimpl/errors.generated.go",
    "content": "package taggedimpl\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tagged/taggedimpl/impl.go",
    "content": "//go:build !confonly\n// +build !confonly\n\npackage taggedimpl\n\nimport (\n\t\"context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tagged\"\n)\n\nfunc DialTaggedOutbound(ctx context.Context, dest net.Destination, tag string) (net.Conn, error) {\n\tvar dispatcher routing.Dispatcher\n\tif core.FromContext(ctx) == nil {\n\t\treturn nil, newError(\"Instance context variable is not in context, dial denied. \")\n\t}\n\tif err := core.RequireFeatures(ctx, func(dispatcherInstance routing.Dispatcher) {\n\t\tdispatcher = dispatcherInstance\n\t}); err != nil {\n\t\treturn nil, newError(\"Required Feature dispatcher not resolved\").Base(err)\n\t}\n\n\tcontent := new(session.Content)\n\tcontent.SkipDNSResolve = true\n\n\tctx = session.ContextWithContent(ctx, content)\n\tctx = session.SetForcedOutboundTagToContext(ctx, tag)\n\n\tr, err := dispatcher.Dispatch(ctx, dest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar readerOpt net.ConnectionOption\n\tif dest.Network == net.Network_TCP {\n\t\treaderOpt = net.ConnectionOutputMulti(r.Reader)\n\t} else {\n\t\treaderOpt = net.ConnectionOutputMultiUDP(r.Reader)\n\t}\n\treturn net.NewConnection(net.ConnectionInputMulti(r.Writer), readerOpt), nil\n}\n\nfunc init() {\n\ttagged.Dialer = DialTaggedOutbound\n}\n"
  },
  {
    "path": "transport/internet/tagged/taggedimpl/taggedimpl.go",
    "content": "package taggedimpl\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/tcp/config.go",
    "content": "package tcp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst protocolName = \"tcp\"\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tcp/config.pb.go",
    "content": "package tcp\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 Config struct {\n\tstate               protoimpl.MessageState `protogen:\"open.v1\"`\n\tHeaderSettings      *anypb.Any             `protobuf:\"bytes,2,opt,name=header_settings,json=headerSettings,proto3\" json:\"header_settings,omitempty\"`\n\tAcceptProxyProtocol bool                   `protobuf:\"varint,3,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3\" json:\"accept_proxy_protocol,omitempty\"`\n\tunknownFields       protoimpl.UnknownFields\n\tsizeCache           protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_tcp_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tcp_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tcp_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetHeaderSettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.HeaderSettings\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetAcceptProxyProtocol() bool {\n\tif x != nil {\n\t\treturn x.AcceptProxyProtocol\n\t}\n\treturn false\n}\n\nvar File_transport_internet_tcp_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tcp_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"#transport/internet/tcp/config.proto\\x12!v2ray.core.transport.internet.tcp\\x1a\\x19google/protobuf/any.proto\\x1a common/protoext/extensions.proto\\\"\\x9b\\x01\\n\" +\n\t\"\\x06Config\\x12=\\n\" +\n\t\"\\x0fheader_settings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x0eheaderSettings\\x122\\n\" +\n\t\"\\x15accept_proxy_protocol\\x18\\x03 \\x01(\\bR\\x13acceptProxyProtocol:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\ttransport\\x12\\x03tcp\\x90\\xff)\\x01J\\x04\\b\\x01\\x10\\x02B\\x84\\x01\\n\" +\n\t\"%com.v2ray.core.transport.internet.tcpP\\x01Z5github.com/v2fly/v2ray-core/v5/transport/internet/tcp\\xaa\\x02!V2Ray.Core.Transport.Internet.Tcpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tcp_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tcp_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tcp_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tcp_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tcp_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tcp_config_proto_rawDesc), len(file_transport_internet_tcp_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tcp_config_proto_rawDescData\n}\n\nvar file_transport_internet_tcp_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_tcp_config_proto_goTypes = []any{\n\t(*Config)(nil),    // 0: v2ray.core.transport.internet.tcp.Config\n\t(*anypb.Any)(nil), // 1: google.protobuf.Any\n}\nvar file_transport_internet_tcp_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.tcp.Config.header_settings:type_name -> google.protobuf.Any\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_tcp_config_proto_init() }\nfunc file_transport_internet_tcp_config_proto_init() {\n\tif File_transport_internet_tcp_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tcp_config_proto_rawDesc), len(file_transport_internet_tcp_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tcp_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tcp_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_tcp_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tcp_config_proto = out.File\n\tfile_transport_internet_tcp_config_proto_goTypes = nil\n\tfile_transport_internet_tcp_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tcp/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tcp;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tcp\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\";\noption java_package = \"com.v2ray.core.transport.internet.tcp\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\nimport \"common/protoext/extensions.proto\";\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"tcp\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n\n  reserved 1;\n  google.protobuf.Any header_settings = 2;\n  bool accept_proxy_protocol = 3;\n}\n"
  },
  {
    "path": "transport/internet/tcp/dialer.go",
    "content": "package tcp\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n)\n\n// Dial dials a new TCP connection to the given destination.\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tnewError(\"dialing TCP to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\tconn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsecurityEngine, err := security.CreateSecurityEngineFromSettings(ctx, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create security engine\").Base(err)\n\t}\n\n\tif securityEngine != nil {\n\t\tconn, err = securityEngine.Client(conn, security.OptionWithDestination{Dest: dest})\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create security protocol client from security engine\").Base(err)\n\t\t}\n\t}\n\n\ttcpSettings := streamSettings.ProtocolSettings.(*Config)\n\tif tcpSettings.HeaderSettings != nil {\n\t\theaderConfig, err := serial.GetInstanceOf(tcpSettings.HeaderSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get header settings\").Base(err).AtError()\n\t\t}\n\t\tauth, err := internet.CreateConnectionAuthenticator(headerConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create header authenticator\").Base(err).AtError()\n\t\t}\n\t\tconn = auth.Client(conn)\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n"
  },
  {
    "path": "transport/internet/tcp/errors.generated.go",
    "content": "package tcp\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tcp/hub.go",
    "content": "package tcp\n\nimport (\n\t\"context\"\n\tgotls \"crypto/tls\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n// Listener is an internet.Listener that listens for TCP connections.\ntype Listener struct {\n\tlistener   net.Listener\n\ttlsConfig  *gotls.Config\n\tauthConfig internet.ConnectionAuthenticator\n\tconfig     *Config\n\taddConn    internet.ConnHandler\n}\n\n// ListenTCP creates a new Listener based on configurations.\nfunc ListenTCP(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {\n\tl := &Listener{\n\t\taddConn: handler,\n\t}\n\ttcpSettings := streamSettings.ProtocolSettings.(*Config)\n\tl.config = tcpSettings\n\tif l.config != nil {\n\t\tif streamSettings.SocketSettings == nil {\n\t\t\tstreamSettings.SocketSettings = &internet.SocketConfig{}\n\t\t}\n\t\tstreamSettings.SocketSettings.AcceptProxyProtocol = l.config.AcceptProxyProtocol\n\t}\n\tvar listener net.Listener\n\tvar err error\n\tif address.Family().IsDomain() {\n\t\tlistener, err = internet.ListenSystem(ctx, &net.UnixAddr{\n\t\t\tName: address.Domain(),\n\t\t\tNet:  \"unix\",\n\t\t}, streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen Unix Domain Socket on \", address).Base(err)\n\t\t}\n\t\tnewError(\"listening Unix Domain Socket on \", address).WriteToLog(session.ExportIDToError(ctx))\n\t} else {\n\t\tlistener, err = internet.ListenSystem(ctx, &net.TCPAddr{\n\t\t\tIP:   address.IP(),\n\t\t\tPort: int(port),\n\t\t}, streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen TCP on \", address, \":\", port).Base(err)\n\t\t}\n\t\tnewError(\"listening TCP on \", address, \":\", port).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tif streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol {\n\t\tnewError(\"accepting PROXY protocol\").AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tl.listener = listener\n\n\tif config := tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\tl.tlsConfig = config.GetTLSConfig()\n\t}\n\n\tif tcpSettings.HeaderSettings != nil {\n\t\theaderConfig, err := serial.GetInstanceOf(tcpSettings.HeaderSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid header settings\").Base(err).AtError()\n\t\t}\n\t\tauth, err := internet.CreateConnectionAuthenticator(headerConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid header settings.\").Base(err).AtError()\n\t\t}\n\t\tl.authConfig = auth\n\t}\n\n\tgo l.keepAccepting()\n\treturn l, nil\n}\n\nfunc (v *Listener) keepAccepting() {\n\tfor {\n\t\tconn, err := v.listener.Accept()\n\t\tif err != nil {\n\t\t\terrStr := err.Error()\n\t\t\tif strings.Contains(errStr, \"closed\") {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnewError(\"failed to accepted raw connections\").Base(err).AtWarning().WriteToLog()\n\t\t\tif strings.Contains(errStr, \"too many\") {\n\t\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif v.tlsConfig != nil {\n\t\t\tconn = tls.Server(conn, v.tlsConfig)\n\t\t}\n\t\tif v.authConfig != nil {\n\t\t\tconn = v.authConfig.Server(conn)\n\t\t}\n\n\t\tv.addConn(internet.Connection(conn))\n\t}\n}\n\n// Addr implements internet.Listener.Addr.\nfunc (v *Listener) Addr() net.Addr {\n\treturn v.listener.Addr()\n}\n\n// Close implements internet.Listener.Close.\nfunc (v *Listener) Close() error {\n\treturn v.listener.Close()\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, ListenTCP))\n}\n"
  },
  {
    "path": "transport/internet/tcp/sockopt_freebsd.go",
    "content": "//go:build freebsd\n// +build freebsd\n\npackage tcp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// GetOriginalDestination from tcp conn\nfunc GetOriginalDestination(conn internet.Connection) (net.Destination, error) {\n\tla := conn.LocalAddr()\n\tra := conn.RemoteAddr()\n\tip, port, err := internet.OriginalDst(la, ra)\n\tif err != nil {\n\t\treturn net.Destination{}, newError(\"failed to get destination\").Base(err)\n\t}\n\tdest := net.TCPDestination(net.IPAddress(ip), net.Port(port))\n\tif !dest.IsValid() {\n\t\treturn net.Destination{}, newError(\"failed to parse destination.\")\n\t}\n\treturn dest, nil\n}\n"
  },
  {
    "path": "transport/internet/tcp/sockopt_linux.go",
    "content": "//go:build linux\n// +build linux\n\npackage tcp\n\nimport (\n\t\"syscall\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst SO_ORIGINAL_DST = 80 // nolint: revive,stylecheck\n\nfunc GetOriginalDestination(conn internet.Connection) (net.Destination, error) {\n\tsysrawconn, f := conn.(syscall.Conn)\n\tif !f {\n\t\treturn net.Destination{}, newError(\"unable to get syscall.Conn\")\n\t}\n\trawConn, err := sysrawconn.SyscallConn()\n\tif err != nil {\n\t\treturn net.Destination{}, newError(\"failed to get sys fd\").Base(err)\n\t}\n\tvar dest net.Destination\n\terr = rawConn.Control(func(fd uintptr) {\n\t\tvar remoteIP net.IP\n\t\tswitch addr := conn.RemoteAddr().(type) {\n\t\tcase *net.TCPAddr:\n\t\t\tremoteIP = addr.IP\n\t\tcase *net.UDPAddr:\n\t\t\tremoteIP = addr.IP\n\t\tdefault:\n\t\t\tnewError(\"failed to call getsockopt\").WriteToLog()\n\t\t\treturn\n\t\t}\n\t\tif remoteIP.To4() != nil {\n\t\t\t// ipv4\n\t\t\taddr, err := syscall.GetsockoptIPv6Mreq(int(fd), syscall.IPPROTO_IP, SO_ORIGINAL_DST)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to call getsockopt\").Base(err).WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tip := net.IPAddress(addr.Multiaddr[4:8])\n\t\t\tport := uint16(addr.Multiaddr[2])<<8 + uint16(addr.Multiaddr[3])\n\t\t\tdest = net.TCPDestination(ip, net.Port(port))\n\t\t} else {\n\t\t\t// ipv6\n\t\t\taddr, err := syscall.GetsockoptIPv6MTUInfo(int(fd), syscall.IPPROTO_IPV6, SO_ORIGINAL_DST)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to call getsockopt\").Base(err).WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tip := net.IPAddress(addr.Addr.Addr[:])\n\t\t\tport := net.PortFromBytes([]byte{byte(addr.Addr.Port), byte(addr.Addr.Port >> 8)})\n\t\t\tdest = net.TCPDestination(ip, port)\n\t\t}\n\t})\n\tif err != nil {\n\t\treturn net.Destination{}, newError(\"failed to control connection\").Base(err)\n\t}\n\tif !dest.IsValid() {\n\t\treturn net.Destination{}, newError(\"failed to call getsockopt\")\n\t}\n\treturn dest, nil\n}\n"
  },
  {
    "path": "transport/internet/tcp/sockopt_linux_test.go",
    "content": "//go:build linux\n// +build linux\n\npackage tcp_test\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/tcp\"\n)\n\nfunc TestGetOriginalDestination(t *testing.T) {\n\ttcpServer := tcp.Server{}\n\tdest, err := tcpServer.Start()\n\tcommon.Must(err)\n\tdefer tcpServer.Close()\n\n\tconfig, err := internet.ToMemoryStreamConfig(nil)\n\tcommon.Must(err)\n\tconn, err := Dial(context.Background(), dest, config)\n\tcommon.Must(err)\n\tdefer conn.Close()\n\n\toriginalDest, err := GetOriginalDestination(conn)\n\tif !(dest == originalDest || strings.Contains(err.Error(), \"failed to call getsockopt\")) {\n\t\tt.Error(\"unexpected state\")\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tcp/sockopt_other.go",
    "content": "//go:build !linux && !freebsd\n// +build !linux,!freebsd\n\npackage tcp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc GetOriginalDestination(conn internet.Connection) (net.Destination, error) {\n\treturn net.Destination{}, nil\n}\n"
  },
  {
    "path": "transport/internet/tcp/tcp.go",
    "content": "package tcp\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/tcp_hub.go",
    "content": "package internet\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nvar transportListenerCache = make(map[string]ListenFunc)\n\nfunc RegisterTransportListener(protocol string, listener ListenFunc) error {\n\tif _, found := transportListenerCache[protocol]; found {\n\t\treturn newError(protocol, \" listener already registered.\").AtError()\n\t}\n\ttransportListenerCache[protocol] = listener\n\treturn nil\n}\n\ntype ConnHandler func(Connection)\n\ntype ListenFunc func(ctx context.Context, address net.Address, port net.Port, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error)\n\ntype Listener interface {\n\tClose() error\n\tAddr() net.Addr\n}\n\n// ListenUnix is the UDS version of ListenTCP\nfunc ListenUnix(ctx context.Context, address net.Address, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error) {\n\tif settings == nil {\n\t\ts, err := ToMemoryStreamConfig(nil)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create default unix stream settings\").Base(err)\n\t\t}\n\t\tsettings = s\n\t}\n\n\tprotocol := settings.ProtocolName\n\n\tif originalProtocolName := getOriginalMessageName(settings); originalProtocolName != \"\" {\n\t\tprotocol = originalProtocolName\n\t}\n\n\tlistenFunc := transportListenerCache[protocol]\n\tif listenFunc == nil {\n\t\treturn nil, newError(protocol, \" unix istener not registered.\").AtError()\n\t}\n\tlistener, err := listenFunc(ctx, address, net.Port(0), settings, handler)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to listen on unix address: \", address).Base(err)\n\t}\n\treturn listener, nil\n}\n\nfunc ListenTCP(ctx context.Context, address net.Address, port net.Port, settings *MemoryStreamConfig, handler ConnHandler) (Listener, error) {\n\tif settings == nil {\n\t\ts, err := ToMemoryStreamConfig(nil)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create default stream settings\").Base(err)\n\t\t}\n\t\tsettings = s\n\t}\n\n\tif address.Family().IsDomain() && address.Domain() == \"localhost\" {\n\t\taddress = net.LocalHostIP\n\t}\n\n\tif address.Family().IsDomain() {\n\t\treturn nil, newError(\"domain address is not allowed for listening: \", address.Domain())\n\t}\n\n\tprotocol := settings.ProtocolName\n\n\tif originalProtocolName := getOriginalMessageName(settings); originalProtocolName != \"\" {\n\t\tprotocol = originalProtocolName\n\t}\n\n\tlistenFunc := transportListenerCache[protocol]\n\tif listenFunc == nil {\n\t\treturn nil, newError(protocol, \" listener not registered.\").AtError()\n\t}\n\tlistener, err := listenFunc(ctx, address, port, settings, handler)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to listen on address: \", address, \":\", port).Base(err)\n\t}\n\treturn listener, nil\n}\n\n// ListenSystem listens on a local address for incoming TCP connections.\n//\n// v2ray:api:beta\nfunc ListenSystem(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.Listener, error) {\n\treturn effectiveListener.Listen(ctx, addr, sockopt)\n}\n\n// ListenSystemPacket listens on a local address for incoming UDP connections.\n//\n// v2ray:api:beta\nfunc ListenSystemPacket(ctx context.Context, addr net.Addr, sockopt *SocketConfig) (net.PacketConn, error) {\n\treturn effectiveListener.ListenPacket(ctx, addr, sockopt)\n}\n"
  },
  {
    "path": "transport/internet/tls/config.go",
    "content": "package tls\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nvar globalSessionCache = tls.NewLRUClientSessionCache(128)\n\nconst exp8357 = \"experiment:8357\"\n\n// ParseCertificate converts a cert.Certificate to Certificate.\nfunc ParseCertificate(c *cert.Certificate) *Certificate {\n\tif c != nil {\n\t\tcertPEM, keyPEM := c.ToPEM()\n\t\treturn &Certificate{\n\t\t\tCertificate: certPEM,\n\t\t\tKey:         keyPEM,\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (c *Config) loadSelfCertPool(usage Certificate_Usage) (*x509.CertPool, error) {\n\troot := x509.NewCertPool()\n\tfor _, cert := range c.Certificate {\n\t\tif cert.Usage == usage {\n\t\t\tif !root.AppendCertsFromPEM(cert.Certificate) {\n\t\t\t\treturn nil, newError(\"failed to append cert\").AtWarning()\n\t\t\t}\n\t\t}\n\t}\n\treturn root, nil\n}\n\n// BuildCertificates builds a list of TLS certificates from proto definition.\nfunc (c *Config) BuildCertificates() []tls.Certificate {\n\tcerts := make([]tls.Certificate, 0, len(c.Certificate))\n\tfor _, entry := range c.Certificate {\n\t\tif entry.Usage != Certificate_ENCIPHERMENT {\n\t\t\tcontinue\n\t\t}\n\t\tkeyPair, err := tls.X509KeyPair(entry.Certificate, entry.Key)\n\t\tif err != nil {\n\t\t\tnewError(\"ignoring invalid X509 key pair\").Base(err).AtWarning().WriteToLog()\n\t\t\tcontinue\n\t\t}\n\t\tcerts = append(certs, keyPair)\n\t}\n\treturn certs\n}\n\nfunc isCertificateExpired(c *tls.Certificate) bool {\n\tif c.Leaf == nil && len(c.Certificate) > 0 {\n\t\tif pc, err := x509.ParseCertificate(c.Certificate[0]); err == nil {\n\t\t\tc.Leaf = pc\n\t\t}\n\t}\n\n\t// If leaf is not there, the certificate is probably not used yet. We trust user to provide a valid certificate.\n\treturn c.Leaf != nil && c.Leaf.NotAfter.Before(time.Now().Add(time.Minute*2))\n}\n\nfunc issueCertificate(rawCA *Certificate, domain string) (*tls.Certificate, error) {\n\tparent, err := cert.ParseCertificate(rawCA.Certificate, rawCA.Key)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse raw certificate\").Base(err)\n\t}\n\tnewCert, err := cert.Generate(parent, cert.CommonName(domain), cert.DNSNames(domain))\n\tif err != nil {\n\t\treturn nil, newError(\"failed to generate new certificate for \", domain).Base(err)\n\t}\n\tnewCertPEM, newKeyPEM := newCert.ToPEM()\n\tcert, err := tls.X509KeyPair(newCertPEM, newKeyPEM)\n\treturn &cert, err\n}\n\nfunc (c *Config) getCustomCA() []*Certificate {\n\tcerts := make([]*Certificate, 0, len(c.Certificate))\n\tfor _, certificate := range c.Certificate {\n\t\tif certificate.Usage == Certificate_AUTHORITY_ISSUE {\n\t\t\tcerts = append(certs, certificate)\n\t\t}\n\t}\n\treturn certs\n}\n\nfunc getGetCertificateFunc(c *tls.Config, ca []*Certificate) func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {\n\tvar access sync.RWMutex\n\n\treturn func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {\n\t\tdomain := hello.ServerName\n\t\tcertExpired := false\n\n\t\taccess.RLock()\n\t\tcertificate, found := c.NameToCertificate[domain]\n\t\taccess.RUnlock()\n\n\t\tif found {\n\t\t\tif !isCertificateExpired(certificate) {\n\t\t\t\treturn certificate, nil\n\t\t\t}\n\t\t\tcertExpired = true\n\t\t}\n\n\t\tif certExpired {\n\t\t\tnewCerts := make([]tls.Certificate, 0, len(c.Certificates))\n\n\t\t\taccess.Lock()\n\t\t\tfor _, certificate := range c.Certificates {\n\t\t\t\tcert := certificate\n\t\t\t\tif !isCertificateExpired(&cert) {\n\t\t\t\t\tnewCerts = append(newCerts, cert)\n\t\t\t\t} else if cert.Leaf != nil {\n\t\t\t\t\texpTime := cert.Leaf.NotAfter.Format(time.RFC3339)\n\t\t\t\t\tnewError(\"old certificate for \", domain, \" (expire on \", expTime, \") discard\").AtInfo().WriteToLog()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.Certificates = newCerts\n\t\t\taccess.Unlock()\n\t\t}\n\n\t\tvar issuedCertificate *tls.Certificate\n\n\t\t// Create a new certificate from existing CA if possible\n\t\tfor _, rawCert := range ca {\n\t\t\tif rawCert.Usage == Certificate_AUTHORITY_ISSUE {\n\t\t\t\tnewCert, err := issueCertificate(rawCert, domain)\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to issue new certificate for \", domain).Base(err).WriteToLog()\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tparsed, err := x509.ParseCertificate(newCert.Certificate[0])\n\t\t\t\tif err == nil {\n\t\t\t\t\tnewCert.Leaf = parsed\n\t\t\t\t\texpTime := parsed.NotAfter.Format(time.RFC3339)\n\t\t\t\t\tnewError(\"new certificate for \", domain, \" (expire on \", expTime, \") issued\").AtInfo().WriteToLog()\n\t\t\t\t} else {\n\t\t\t\t\tnewError(\"failed to parse new certificate for \", domain).Base(err).WriteToLog()\n\t\t\t\t}\n\n\t\t\t\taccess.Lock()\n\t\t\t\tc.Certificates = append(c.Certificates, *newCert)\n\t\t\t\tissuedCertificate = &c.Certificates[len(c.Certificates)-1]\n\t\t\t\taccess.Unlock()\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif issuedCertificate == nil {\n\t\t\treturn nil, newError(\"failed to create a new certificate for \", domain)\n\t\t}\n\n\t\taccess.Lock()\n\t\tc.BuildNameToCertificate()\n\t\taccess.Unlock()\n\n\t\treturn issuedCertificate, nil\n\t}\n}\n\nfunc (c *Config) IsExperiment8357() bool {\n\treturn strings.HasPrefix(c.ServerName, exp8357)\n}\n\nfunc (c *Config) parseServerName() string {\n\tif c.IsExperiment8357() {\n\t\treturn c.ServerName[len(exp8357):]\n\t}\n\n\treturn c.ServerName\n}\n\nfunc (c *Config) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {\n\tif c.PinnedPeerCertificateChainSha256 != nil {\n\t\thashValue := GenerateCertChainHash(rawCerts)\n\t\tfor _, v := range c.PinnedPeerCertificateChainSha256 {\n\t\t\tif hmac.Equal(hashValue, v) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn newError(\"peer cert is unrecognized: \", base64.StdEncoding.EncodeToString(hashValue))\n\t}\n\treturn nil\n}\n\ntype alwaysFlushWriter struct {\n\tfile *os.File\n}\n\nfunc (a *alwaysFlushWriter) Write(p []byte) (n int, err error) {\n\tn, err = a.file.Write(p)\n\ta.file.Sync()\n\treturn n, err\n}\n\n// GetTLSConfig converts this Config into tls.Config.\nfunc (c *Config) GetTLSConfig(opts ...Option) *tls.Config {\n\troot, err := c.getCertPool()\n\tif err != nil {\n\t\tnewError(\"failed to load system root certificate\").AtError().Base(err).WriteToLog()\n\t}\n\n\tif c == nil {\n\t\treturn &tls.Config{\n\t\t\tClientSessionCache:     globalSessionCache,\n\t\t\tRootCAs:                root,\n\t\t\tInsecureSkipVerify:     false,\n\t\t\tNextProtos:             nil,\n\t\t\tSessionTicketsDisabled: true,\n\t\t}\n\t}\n\n\tclientRoot, err := c.loadSelfCertPool(Certificate_AUTHORITY_VERIFY_CLIENT)\n\tif err != nil {\n\t\tnewError(\"failed to load client root certificate\").AtError().Base(err).WriteToLog()\n\t}\n\n\tconfig := &tls.Config{\n\t\tClientSessionCache:     globalSessionCache,\n\t\tRootCAs:                root,\n\t\tInsecureSkipVerify:     c.AllowInsecure,\n\t\tNextProtos:             c.NextProtocol,\n\t\tSessionTicketsDisabled: !c.EnableSessionResumption,\n\t\tVerifyPeerCertificate:  c.verifyPeerCert,\n\t\tClientCAs:              clientRoot,\n\t}\n\n\tif c.AllowInsecureIfPinnedPeerCertificate && c.PinnedPeerCertificateChainSha256 != nil {\n\t\tconfig.InsecureSkipVerify = true\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(config)\n\t}\n\n\tconfig.Certificates = c.BuildCertificates()\n\tconfig.BuildNameToCertificate()\n\n\tcaCerts := c.getCustomCA()\n\tif len(caCerts) > 0 {\n\t\tconfig.GetCertificate = getGetCertificateFunc(config, caCerts)\n\t}\n\n\tif sn := c.parseServerName(); len(sn) > 0 {\n\t\tconfig.ServerName = sn\n\t}\n\n\tif len(config.NextProtos) == 0 {\n\t\tconfig.NextProtos = []string{\"h2\", \"http/1.1\"}\n\t}\n\n\tif c.VerifyClientCertificate {\n\t\tconfig.ClientAuth = tls.RequireAndVerifyClientCert\n\t}\n\n\tswitch c.MinVersion {\n\tcase Config_TLS1_0:\n\t\tconfig.MinVersion = tls.VersionTLS10\n\tcase Config_TLS1_1:\n\t\tconfig.MinVersion = tls.VersionTLS11\n\tcase Config_TLS1_2:\n\t\tconfig.MinVersion = tls.VersionTLS12\n\tcase Config_TLS1_3:\n\t\tconfig.MinVersion = tls.VersionTLS13\n\t}\n\n\tswitch c.MaxVersion {\n\tcase Config_TLS1_0:\n\t\tconfig.MaxVersion = tls.VersionTLS10\n\tcase Config_TLS1_1:\n\t\tconfig.MaxVersion = tls.VersionTLS11\n\tcase Config_TLS1_2:\n\t\tconfig.MaxVersion = tls.VersionTLS12\n\tcase Config_TLS1_3:\n\t\tconfig.MaxVersion = tls.VersionTLS13\n\t}\n\n\tif len(c.EchConfig) > 0 || len(c.Ech_DOHserver) > 0 {\n\t\terr := ApplyECH(c, config) //nolint: staticcheck\n\t\tif err != nil {            //nolint: staticcheck\n\t\t\tnewError(\"unable to set ECH\").AtError().Base(err).WriteToLog()\n\t\t}\n\t}\n\n\tif len(c.Ciphersuites) > 0 {\n\t\tconfig.CipherSuites = make([]uint16, 0, len(c.Ciphersuites))\n\t\tfor _, cs := range c.Ciphersuites {\n\t\t\tconfig.CipherSuites = append(config.CipherSuites, uint16(cs))\n\t\t}\n\t}\n\n\treturn config\n}\n\n// Option for building TLS config.\ntype Option func(*tls.Config)\n\n// WithDestination sets the server name in TLS config.\nfunc WithDestination(dest net.Destination) Option {\n\treturn func(config *tls.Config) {\n\t\tif config.ServerName == \"\" {\n\t\t\tswitch dest.Address.Family() {\n\t\t\tcase net.AddressFamilyDomain:\n\t\t\t\tconfig.ServerName = dest.Address.Domain()\n\t\t\tcase net.AddressFamilyIPv4, net.AddressFamilyIPv6:\n\t\t\t\tconfig.ServerName = dest.Address.IP().String()\n\t\t\t}\n\t\t}\n\t}\n}\n\n// WithNextProto sets the ALPN values in TLS config.\nfunc WithNextProto(protocol ...string) Option {\n\treturn func(config *tls.Config) {\n\t\tif len(config.NextProtos) == 0 {\n\t\t\tconfig.NextProtos = protocol\n\t\t}\n\t}\n}\n\n// ConfigFromStreamSettings fetches Config from stream settings. Nil if not found.\nfunc ConfigFromStreamSettings(settings *internet.MemoryStreamConfig) *Config {\n\tif settings == nil {\n\t\treturn nil\n\t}\n\tif settings.SecuritySettings == nil {\n\t\treturn nil\n\t}\n\t// Fail close for unknown TLS settings type.\n\t// For TLS Clients, Security Engine should be used, instead of this.\n\tconfig := settings.SecuritySettings.(*Config)\n\treturn config\n}\n"
  },
  {
    "path": "transport/internet/tls/config.pb.go",
    "content": "package tls\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Certificate_Usage int32\n\nconst (\n\tCertificate_ENCIPHERMENT            Certificate_Usage = 0\n\tCertificate_AUTHORITY_VERIFY        Certificate_Usage = 1\n\tCertificate_AUTHORITY_ISSUE         Certificate_Usage = 2\n\tCertificate_AUTHORITY_VERIFY_CLIENT Certificate_Usage = 3\n)\n\n// Enum value maps for Certificate_Usage.\nvar (\n\tCertificate_Usage_name = map[int32]string{\n\t\t0: \"ENCIPHERMENT\",\n\t\t1: \"AUTHORITY_VERIFY\",\n\t\t2: \"AUTHORITY_ISSUE\",\n\t\t3: \"AUTHORITY_VERIFY_CLIENT\",\n\t}\n\tCertificate_Usage_value = map[string]int32{\n\t\t\"ENCIPHERMENT\":            0,\n\t\t\"AUTHORITY_VERIFY\":        1,\n\t\t\"AUTHORITY_ISSUE\":         2,\n\t\t\"AUTHORITY_VERIFY_CLIENT\": 3,\n\t}\n)\n\nfunc (x Certificate_Usage) Enum() *Certificate_Usage {\n\tp := new(Certificate_Usage)\n\t*p = x\n\treturn p\n}\n\nfunc (x Certificate_Usage) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Certificate_Usage) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_tls_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Certificate_Usage) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_tls_config_proto_enumTypes[0]\n}\n\nfunc (x Certificate_Usage) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Certificate_Usage.Descriptor instead.\nfunc (Certificate_Usage) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_tls_config_proto_rawDescGZIP(), []int{0, 0}\n}\n\ntype Config_TLSVersion int32\n\nconst (\n\tConfig_Default Config_TLSVersion = 0\n\tConfig_TLS1_0  Config_TLSVersion = 1\n\tConfig_TLS1_1  Config_TLSVersion = 2\n\tConfig_TLS1_2  Config_TLSVersion = 3\n\tConfig_TLS1_3  Config_TLSVersion = 4\n)\n\n// Enum value maps for Config_TLSVersion.\nvar (\n\tConfig_TLSVersion_name = map[int32]string{\n\t\t0: \"Default\",\n\t\t1: \"TLS1_0\",\n\t\t2: \"TLS1_1\",\n\t\t3: \"TLS1_2\",\n\t\t4: \"TLS1_3\",\n\t}\n\tConfig_TLSVersion_value = map[string]int32{\n\t\t\"Default\": 0,\n\t\t\"TLS1_0\":  1,\n\t\t\"TLS1_1\":  2,\n\t\t\"TLS1_2\":  3,\n\t\t\"TLS1_3\":  4,\n\t}\n)\n\nfunc (x Config_TLSVersion) Enum() *Config_TLSVersion {\n\tp := new(Config_TLSVersion)\n\t*p = x\n\treturn p\n}\n\nfunc (x Config_TLSVersion) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Config_TLSVersion) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_tls_config_proto_enumTypes[1].Descriptor()\n}\n\nfunc (Config_TLSVersion) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_tls_config_proto_enumTypes[1]\n}\n\nfunc (x Config_TLSVersion) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Config_TLSVersion.Descriptor instead.\nfunc (Config_TLSVersion) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_tls_config_proto_rawDescGZIP(), []int{1, 0}\n}\n\ntype Certificate struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// TLS certificate in x509 format.\n\tCertificate []byte `protobuf:\"bytes,1,opt,name=Certificate,proto3\" json:\"Certificate,omitempty\"`\n\t// TLS key in x509 format.\n\tKey             []byte            `protobuf:\"bytes,2,opt,name=Key,proto3\" json:\"Key,omitempty\"`\n\tUsage           Certificate_Usage `protobuf:\"varint,3,opt,name=usage,proto3,enum=v2ray.core.transport.internet.tls.Certificate_Usage\" json:\"usage,omitempty\"`\n\tCertificateFile string            `protobuf:\"bytes,96001,opt,name=certificate_file,json=certificateFile,proto3\" json:\"certificate_file,omitempty\"`\n\tKeyFile         string            `protobuf:\"bytes,96002,opt,name=key_file,json=keyFile,proto3\" json:\"key_file,omitempty\"`\n\tunknownFields   protoimpl.UnknownFields\n\tsizeCache       protoimpl.SizeCache\n}\n\nfunc (x *Certificate) Reset() {\n\t*x = Certificate{}\n\tmi := &file_transport_internet_tls_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Certificate) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Certificate) ProtoMessage() {}\n\nfunc (x *Certificate) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tls_config_proto_msgTypes[0]\n\tif 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 Certificate.ProtoReflect.Descriptor instead.\nfunc (*Certificate) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tls_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Certificate) GetCertificate() []byte {\n\tif x != nil {\n\t\treturn x.Certificate\n\t}\n\treturn nil\n}\n\nfunc (x *Certificate) GetKey() []byte {\n\tif x != nil {\n\t\treturn x.Key\n\t}\n\treturn nil\n}\n\nfunc (x *Certificate) GetUsage() Certificate_Usage {\n\tif x != nil {\n\t\treturn x.Usage\n\t}\n\treturn Certificate_ENCIPHERMENT\n}\n\nfunc (x *Certificate) GetCertificateFile() string {\n\tif x != nil {\n\t\treturn x.CertificateFile\n\t}\n\treturn \"\"\n}\n\nfunc (x *Certificate) GetKeyFile() string {\n\tif x != nil {\n\t\treturn x.KeyFile\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// Whether or not to allow self-signed certificates.\n\tAllowInsecure bool `protobuf:\"varint,1,opt,name=allow_insecure,json=allowInsecure,proto3\" json:\"allow_insecure,omitempty\"`\n\t// List of certificates to be served on server.\n\tCertificate []*Certificate `protobuf:\"bytes,2,rep,name=certificate,proto3\" json:\"certificate,omitempty\"`\n\t// Override server name.\n\tServerName string `protobuf:\"bytes,3,opt,name=server_name,json=serverName,proto3\" json:\"server_name,omitempty\"`\n\t// Lists of string as ALPN values.\n\tNextProtocol []string `protobuf:\"bytes,4,rep,name=next_protocol,json=nextProtocol,proto3\" json:\"next_protocol,omitempty\"`\n\t// Whether or not to enable session (ticket) resumption.\n\tEnableSessionResumption bool `protobuf:\"varint,5,opt,name=enable_session_resumption,json=enableSessionResumption,proto3\" json:\"enable_session_resumption,omitempty\"`\n\t// If true, root certificates on the system will not be loaded for\n\t// verification.\n\tDisableSystemRoot bool `protobuf:\"varint,6,opt,name=disable_system_root,json=disableSystemRoot,proto3\" json:\"disable_system_root,omitempty\"`\n\t// @Document A pinned certificate chain sha256 hash.\n\t// @Document If the server's hash does not match this value, the connection will be aborted.\n\t// @Document This value replace allow_insecure.\n\t// @Critical\n\tPinnedPeerCertificateChainSha256 [][]byte `protobuf:\"bytes,7,rep,name=pinned_peer_certificate_chain_sha256,json=pinnedPeerCertificateChainSha256,proto3\" json:\"pinned_peer_certificate_chain_sha256,omitempty\"`\n\t// If true, the client is required to present a certificate.\n\tVerifyClientCertificate bool `protobuf:\"varint,8,opt,name=verify_client_certificate,json=verifyClientCertificate,proto3\" json:\"verify_client_certificate,omitempty\"`\n\t// Minimum TLS version to support.\n\tMinVersion Config_TLSVersion `protobuf:\"varint,9,opt,name=min_version,json=minVersion,proto3,enum=v2ray.core.transport.internet.tls.Config_TLSVersion\" json:\"min_version,omitempty\"`\n\t// Maximum TLS version to support.\n\tMaxVersion Config_TLSVersion `protobuf:\"varint,10,opt,name=max_version,json=maxVersion,proto3,enum=v2ray.core.transport.internet.tls.Config_TLSVersion\" json:\"max_version,omitempty\"`\n\t// Whether or not to allow self-signed certificates when pinned_peer_certificate_chain_sha256 is present.\n\tAllowInsecureIfPinnedPeerCertificate bool `protobuf:\"varint,11,opt,name=allow_insecure_if_pinned_peer_certificate,json=allowInsecureIfPinnedPeerCertificate,proto3\" json:\"allow_insecure_if_pinned_peer_certificate,omitempty\"`\n\t// ECH Config in bytes format\n\tEchConfig []byte `protobuf:\"bytes,16,opt,name=ech_config,json=echConfig,proto3\" json:\"ech_config,omitempty\"`\n\t// DOH server to query HTTPS record for ECH\n\tEch_DOHserver string `protobuf:\"bytes,17,opt,name=ech_DOHserver,json=echDOHserver,proto3\" json:\"ech_DOHserver,omitempty\"`\n\t// domain to query for https record\n\tEchQueryDomain string `protobuf:\"bytes,18,opt,name=ech_query_domain,json=echQueryDomain,proto3\" json:\"ech_query_domain,omitempty\"`\n\t// cipher suites to to be offered or accepted.\n\t// This is an developer option.\n\tCiphersuites  []uint32 `protobuf:\"varint,19,rep,packed,name=ciphersuites,proto3\" json:\"ciphersuites,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_tls_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tls_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tls_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetAllowInsecure() bool {\n\tif x != nil {\n\t\treturn x.AllowInsecure\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetCertificate() []*Certificate {\n\tif x != nil {\n\t\treturn x.Certificate\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetServerName() string {\n\tif x != nil {\n\t\treturn x.ServerName\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetNextProtocol() []string {\n\tif x != nil {\n\t\treturn x.NextProtocol\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetEnableSessionResumption() bool {\n\tif x != nil {\n\t\treturn x.EnableSessionResumption\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetDisableSystemRoot() bool {\n\tif x != nil {\n\t\treturn x.DisableSystemRoot\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetPinnedPeerCertificateChainSha256() [][]byte {\n\tif x != nil {\n\t\treturn x.PinnedPeerCertificateChainSha256\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetVerifyClientCertificate() bool {\n\tif x != nil {\n\t\treturn x.VerifyClientCertificate\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetMinVersion() Config_TLSVersion {\n\tif x != nil {\n\t\treturn x.MinVersion\n\t}\n\treturn Config_Default\n}\n\nfunc (x *Config) GetMaxVersion() Config_TLSVersion {\n\tif x != nil {\n\t\treturn x.MaxVersion\n\t}\n\treturn Config_Default\n}\n\nfunc (x *Config) GetAllowInsecureIfPinnedPeerCertificate() bool {\n\tif x != nil {\n\t\treturn x.AllowInsecureIfPinnedPeerCertificate\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetEchConfig() []byte {\n\tif x != nil {\n\t\treturn x.EchConfig\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetEch_DOHserver() string {\n\tif x != nil {\n\t\treturn x.Ech_DOHserver\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetEchQueryDomain() string {\n\tif x != nil {\n\t\treturn x.EchQueryDomain\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetCiphersuites() []uint32 {\n\tif x != nil {\n\t\treturn x.Ciphersuites\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_tls_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tls_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"#transport/internet/tls/config.proto\\x12!v2ray.core.transport.internet.tls\\x1a common/protoext/extensions.proto\\\"\\xd8\\x02\\n\" +\n\t\"\\vCertificate\\x12 \\n\" +\n\t\"\\vCertificate\\x18\\x01 \\x01(\\fR\\vCertificate\\x12\\x10\\n\" +\n\t\"\\x03Key\\x18\\x02 \\x01(\\fR\\x03Key\\x12J\\n\" +\n\t\"\\x05usage\\x18\\x03 \\x01(\\x0e24.v2ray.core.transport.internet.tls.Certificate.UsageR\\x05usage\\x12>\\n\" +\n\t\"\\x10certificate_file\\x18\\x81\\xee\\x05 \\x01(\\tB\\x11\\x82\\xb5\\x18\\r\\\"\\vCertificateR\\x0fcertificateFile\\x12&\\n\" +\n\t\"\\bkey_file\\x18\\x82\\xee\\x05 \\x01(\\tB\\t\\x82\\xb5\\x18\\x05\\\"\\x03KeyR\\akeyFile\\\"a\\n\" +\n\t\"\\x05Usage\\x12\\x10\\n\" +\n\t\"\\fENCIPHERMENT\\x10\\x00\\x12\\x14\\n\" +\n\t\"\\x10AUTHORITY_VERIFY\\x10\\x01\\x12\\x13\\n\" +\n\t\"\\x0fAUTHORITY_ISSUE\\x10\\x02\\x12\\x1b\\n\" +\n\t\"\\x17AUTHORITY_VERIFY_CLIENT\\x10\\x03\\\"\\xc4\\a\\n\" +\n\t\"\\x06Config\\x12-\\n\" +\n\t\"\\x0eallow_insecure\\x18\\x01 \\x01(\\bB\\x06\\x82\\xb5\\x18\\x02(\\x01R\\rallowInsecure\\x12P\\n\" +\n\t\"\\vcertificate\\x18\\x02 \\x03(\\v2..v2ray.core.transport.internet.tls.CertificateR\\vcertificate\\x12\\x1f\\n\" +\n\t\"\\vserver_name\\x18\\x03 \\x01(\\tR\\n\" +\n\t\"serverName\\x12#\\n\" +\n\t\"\\rnext_protocol\\x18\\x04 \\x03(\\tR\\fnextProtocol\\x12:\\n\" +\n\t\"\\x19enable_session_resumption\\x18\\x05 \\x01(\\bR\\x17enableSessionResumption\\x12.\\n\" +\n\t\"\\x13disable_system_root\\x18\\x06 \\x01(\\bR\\x11disableSystemRoot\\x12N\\n\" +\n\t\"$pinned_peer_certificate_chain_sha256\\x18\\a \\x03(\\fR pinnedPeerCertificateChainSha256\\x12:\\n\" +\n\t\"\\x19verify_client_certificate\\x18\\b \\x01(\\bR\\x17verifyClientCertificate\\x12U\\n\" +\n\t\"\\vmin_version\\x18\\t \\x01(\\x0e24.v2ray.core.transport.internet.tls.Config.TLSVersionR\\n\" +\n\t\"minVersion\\x12U\\n\" +\n\t\"\\vmax_version\\x18\\n\" +\n\t\" \\x01(\\x0e24.v2ray.core.transport.internet.tls.Config.TLSVersionR\\n\" +\n\t\"maxVersion\\x12W\\n\" +\n\t\")allow_insecure_if_pinned_peer_certificate\\x18\\v \\x01(\\bR$allowInsecureIfPinnedPeerCertificate\\x12\\x1d\\n\" +\n\t\"\\n\" +\n\t\"ech_config\\x18\\x10 \\x01(\\fR\\techConfig\\x12#\\n\" +\n\t\"\\rech_DOHserver\\x18\\x11 \\x01(\\tR\\fechDOHserver\\x12(\\n\" +\n\t\"\\x10ech_query_domain\\x18\\x12 \\x01(\\tR\\x0eechQueryDomain\\x12\\\"\\n\" +\n\t\"\\fciphersuites\\x18\\x13 \\x03(\\rR\\fciphersuites\\\"I\\n\" +\n\t\"\\n\" +\n\t\"TLSVersion\\x12\\v\\n\" +\n\t\"\\aDefault\\x10\\x00\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06TLS1_0\\x10\\x01\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06TLS1_1\\x10\\x02\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06TLS1_2\\x10\\x03\\x12\\n\" +\n\t\"\\n\" +\n\t\"\\x06TLS1_3\\x10\\x04:\\x17\\x82\\xb5\\x18\\x13\\n\" +\n\t\"\\bsecurity\\x12\\x03tls\\x90\\xff)\\x01B\\x84\\x01\\n\" +\n\t\"%com.v2ray.core.transport.internet.tlsP\\x01Z5github.com/v2fly/v2ray-core/v5/transport/internet/tls\\xaa\\x02!V2Ray.Core.Transport.Internet.Tlsb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tls_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tls_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tls_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tls_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tls_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tls_config_proto_rawDesc), len(file_transport_internet_tls_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tls_config_proto_rawDescData\n}\n\nvar file_transport_internet_tls_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)\nvar file_transport_internet_tls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_tls_config_proto_goTypes = []any{\n\t(Certificate_Usage)(0), // 0: v2ray.core.transport.internet.tls.Certificate.Usage\n\t(Config_TLSVersion)(0), // 1: v2ray.core.transport.internet.tls.Config.TLSVersion\n\t(*Certificate)(nil),    // 2: v2ray.core.transport.internet.tls.Certificate\n\t(*Config)(nil),         // 3: v2ray.core.transport.internet.tls.Config\n}\nvar file_transport_internet_tls_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.tls.Certificate.usage:type_name -> v2ray.core.transport.internet.tls.Certificate.Usage\n\t2, // 1: v2ray.core.transport.internet.tls.Config.certificate:type_name -> v2ray.core.transport.internet.tls.Certificate\n\t1, // 2: v2ray.core.transport.internet.tls.Config.min_version:type_name -> v2ray.core.transport.internet.tls.Config.TLSVersion\n\t1, // 3: v2ray.core.transport.internet.tls.Config.max_version:type_name -> v2ray.core.transport.internet.tls.Config.TLSVersion\n\t4, // [4:4] is the sub-list for method output_type\n\t4, // [4:4] is the sub-list for method input_type\n\t4, // [4:4] is the sub-list for extension type_name\n\t4, // [4:4] is the sub-list for extension extendee\n\t0, // [0:4] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_tls_config_proto_init() }\nfunc file_transport_internet_tls_config_proto_init() {\n\tif File_transport_internet_tls_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tls_config_proto_rawDesc), len(file_transport_internet_tls_config_proto_rawDesc)),\n\t\t\tNumEnums:      2,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tls_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tls_config_proto_depIdxs,\n\t\tEnumInfos:         file_transport_internet_tls_config_proto_enumTypes,\n\t\tMessageInfos:      file_transport_internet_tls_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tls_config_proto = out.File\n\tfile_transport_internet_tls_config_proto_goTypes = nil\n\tfile_transport_internet_tls_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tls/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tls;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tls\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\";\noption java_package = \"com.v2ray.core.transport.internet.tls\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Certificate {\n  // TLS certificate in x509 format.\n  bytes Certificate = 1;\n\n  // TLS key in x509 format.\n  bytes Key = 2;\n\n  enum Usage {\n    ENCIPHERMENT = 0;\n    AUTHORITY_VERIFY = 1;\n    AUTHORITY_ISSUE = 2;\n    AUTHORITY_VERIFY_CLIENT = 3;\n  }\n\n  Usage usage = 3;\n\n  string certificate_file = 96001 [(v2ray.core.common.protoext.field_opt).convert_time_read_file_into = \"Certificate\"];\n  string key_file = 96002 [(v2ray.core.common.protoext.field_opt).convert_time_read_file_into = \"Key\"];\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"security\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"tls\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  // Whether or not to allow self-signed certificates.\n  bool allow_insecure = 1 [(v2ray.core.common.protoext.field_opt).forbidden = true];\n\n  // List of certificates to be served on server.\n  repeated Certificate certificate = 2;\n\n  // Override server name.\n  string server_name = 3;\n\n  // Lists of string as ALPN values.\n  repeated string next_protocol = 4;\n\n  // Whether or not to enable session (ticket) resumption.\n  bool enable_session_resumption = 5;\n\n  // If true, root certificates on the system will not be loaded for\n  // verification.\n  bool disable_system_root = 6;\n\n  /* @Document A pinned certificate chain sha256 hash.\n     @Document If the server's hash does not match this value, the connection will be aborted.\n     @Document This value replace allow_insecure.\n     @Critical\n  */\n  repeated bytes pinned_peer_certificate_chain_sha256 = 7;\n\n  // If true, the client is required to present a certificate.\n  bool verify_client_certificate = 8;\n\n  enum TLSVersion {\n    Default = 0;\n    TLS1_0 = 1;\n    TLS1_1 = 2;\n    TLS1_2 = 3;\n    TLS1_3 = 4;\n  }\n\n  // Minimum TLS version to support.\n  TLSVersion min_version = 9;\n\n  // Maximum TLS version to support.\n  TLSVersion max_version = 10;\n\n  // Whether or not to allow self-signed certificates when pinned_peer_certificate_chain_sha256 is present.\n  bool allow_insecure_if_pinned_peer_certificate = 11;\n\n  // ECH Config in bytes format\n  bytes ech_config = 16;\n\n  // DOH server to query HTTPS record for ECH\n  string ech_DOHserver = 17;\n\n  // domain to query for https record\n  string ech_query_domain = 18;\n\n  // cipher suites to to be offered or accepted.\n  // This is an developer option.\n  repeated uint32 ciphersuites = 19;\n}\n"
  },
  {
    "path": "transport/internet/tls/config_other.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage tls\n\nimport (\n\t\"crypto/x509\"\n\t\"sync\"\n)\n\ntype rootCertsCache struct {\n\tsync.Mutex\n\tpool *x509.CertPool\n}\n\nfunc (c *rootCertsCache) load() (*x509.CertPool, error) {\n\tc.Lock()\n\tdefer c.Unlock()\n\n\tif c.pool != nil {\n\t\treturn c.pool, nil\n\t}\n\n\tpool, err := x509.SystemCertPool()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.pool = pool\n\treturn pool, nil\n}\n\nvar rootCerts rootCertsCache\n\nfunc (c *Config) getCertPool() (*x509.CertPool, error) {\n\tif c.DisableSystemRoot {\n\t\treturn c.loadSelfCertPool(Certificate_AUTHORITY_VERIFY)\n\t}\n\n\tif len(c.Certificate) == 0 {\n\t\treturn rootCerts.load()\n\t}\n\n\tpool, err := x509.SystemCertPool()\n\tif err != nil {\n\t\treturn nil, newError(\"system root\").AtWarning().Base(err)\n\t}\n\tfor _, cert := range c.Certificate {\n\t\tif !pool.AppendCertsFromPEM(cert.Certificate) {\n\t\t\treturn nil, newError(\"append cert to root\").AtWarning().Base(err)\n\t\t}\n\t}\n\treturn pool, err\n}\n"
  },
  {
    "path": "transport/internet/tls/config_test.go",
    "content": "package tls_test\n\nimport (\n\tgotls \"crypto/tls\"\n\t\"crypto/x509\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc TestCertificateIssuing(t *testing.T) {\n\tcertificate := ParseCertificate(cert.MustGenerate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageCertSign)))\n\tcertificate.Usage = Certificate_AUTHORITY_ISSUE\n\n\tc := &Config{\n\t\tCertificate: []*Certificate{\n\t\t\tcertificate,\n\t\t},\n\t}\n\n\ttlsConfig := c.GetTLSConfig()\n\tv2rayCert, err := tlsConfig.GetCertificate(&gotls.ClientHelloInfo{\n\t\tServerName: \"www.v2fly.org\",\n\t})\n\tcommon.Must(err)\n\n\tx509Cert, err := x509.ParseCertificate(v2rayCert.Certificate[0])\n\tcommon.Must(err)\n\tif !x509Cert.NotAfter.After(time.Now()) {\n\t\tt.Error(\"NotAfter: \", x509Cert.NotAfter)\n\t}\n}\n\nfunc TestExpiredCertificate(t *testing.T) {\n\tcaCert := cert.MustGenerate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageCertSign))\n\texpiredCert := cert.MustGenerate(caCert, cert.NotAfter(time.Now().Add(time.Minute*-2)), cert.CommonName(\"www.v2fly.org\"), cert.DNSNames(\"www.v2fly.org\"))\n\n\tcertificate := ParseCertificate(caCert)\n\tcertificate.Usage = Certificate_AUTHORITY_ISSUE\n\n\tcertificate2 := ParseCertificate(expiredCert)\n\n\tc := &Config{\n\t\tCertificate: []*Certificate{\n\t\t\tcertificate,\n\t\t\tcertificate2,\n\t\t},\n\t}\n\n\ttlsConfig := c.GetTLSConfig()\n\tv2rayCert, err := tlsConfig.GetCertificate(&gotls.ClientHelloInfo{\n\t\tServerName: \"www.v2fly.org\",\n\t})\n\tcommon.Must(err)\n\n\tx509Cert, err := x509.ParseCertificate(v2rayCert.Certificate[0])\n\tcommon.Must(err)\n\tif !x509Cert.NotAfter.After(time.Now()) {\n\t\tt.Error(\"NotAfter: \", x509Cert.NotAfter)\n\t}\n}\n\nfunc TestInsecureCertificates(t *testing.T) {\n\tc := &Config{}\n\n\ttlsConfig := c.GetTLSConfig()\n\tif len(tlsConfig.CipherSuites) > 0 {\n\t\tt.Fatal(\"Unexpected tls cipher suites list: \", tlsConfig.CipherSuites)\n\t}\n}\n\nfunc BenchmarkCertificateIssuing(b *testing.B) {\n\tcertificate := ParseCertificate(cert.MustGenerate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageCertSign)))\n\tcertificate.Usage = Certificate_AUTHORITY_ISSUE\n\n\tc := &Config{\n\t\tCertificate: []*Certificate{\n\t\t\tcertificate,\n\t\t},\n\t}\n\n\ttlsConfig := c.GetTLSConfig()\n\tlenCerts := len(tlsConfig.Certificates)\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _ = tlsConfig.GetCertificate(&gotls.ClientHelloInfo{\n\t\t\tServerName: \"www.v2fly.org\",\n\t\t})\n\t\tdelete(tlsConfig.NameToCertificate, \"www.v2fly.org\")\n\t\ttlsConfig.Certificates = tlsConfig.Certificates[:lenCerts]\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tls/config_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage tls\n\nimport \"crypto/x509\"\n\nfunc (c *Config) getCertPool() (*x509.CertPool, error) {\n\tif c.DisableSystemRoot {\n\t\treturn c.loadSelfCertPool(Certificate_AUTHORITY_VERIFY)\n\t}\n\n\treturn nil, nil\n}\n"
  },
  {
    "path": "transport/internet/tls/ech.go",
    "content": "//go:build go1.23\n// +build go1.23\n\npackage tls\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/miekg/dns\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc ApplyECH(c *Config, config *tls.Config) error {\n\tvar ECHConfig []byte\n\tvar err error\n\tvar domain string\n\n\tif len(c.EchConfig) > 0 {\n\t\tECHConfig = c.EchConfig\n\t} else { // ECH config > DOH lookup\n\t\tif c.EchQueryDomain == \"\" {\n\t\t\tdomain = config.ServerName\n\t\t} else {\n\t\t\tdomain = c.EchQueryDomain\n\t\t}\n\t\taddr := net.ParseAddress(domain)\n\t\tif !addr.Family().IsDomain() {\n\t\t\treturn newError(\"Using DOH for ECH needs SNI\")\n\t\t}\n\t\tECHConfig, err = QueryRecord(addr.Domain(), c.Ech_DOHserver)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tconfig.EncryptedClientHelloConfigList = ECHConfig\n\treturn nil\n}\n\ntype record struct {\n\trecord []byte\n\texpire time.Time\n}\n\nvar (\n\tdnsCache = make(map[string]record)\n\tmutex    sync.RWMutex\n)\n\nfunc QueryRecord(domain string, server string) ([]byte, error) {\n\tmutex.Lock()\n\trec, found := dnsCache[domain]\n\tif found && rec.expire.After(time.Now()) {\n\t\tmutex.Unlock()\n\t\treturn rec.record, nil\n\t}\n\tmutex.Unlock()\n\n\tnewError(\"Trying to query ECH config for domain: \", domain, \" with ECH server: \", server).AtDebug().WriteToLog()\n\trecord, ttl, err := dohQuery(server, domain)\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\n\tif ttl < 600 {\n\t\tttl = 600\n\t}\n\n\tmutex.Lock()\n\tdefer mutex.Unlock()\n\trec.record = record\n\trec.expire = time.Now().Add(time.Second * time.Duration(ttl))\n\tdnsCache[domain] = rec\n\treturn record, nil\n}\n\nfunc dohQuery(server string, domain string) ([]byte, uint32, error) {\n\tm := new(dns.Msg)\n\tm.SetQuestion(dns.Fqdn(domain), dns.TypeHTTPS)\n\tm.Id = 0\n\tmsg, err := m.Pack()\n\tif err != nil {\n\t\treturn []byte{}, 0, err\n\t}\n\ttr := &http.Transport{\n\t\tIdleConnTimeout:   90 * time.Second,\n\t\tForceAttemptHTTP2: true,\n\t\tDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\t\tdest, err := net.ParseDestination(network + \":\" + addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconn, err := internet.DialSystem(ctx, dest, nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn conn, nil\n\t\t},\n\t}\n\tclient := &http.Client{\n\t\tTimeout:   5 * time.Second,\n\t\tTransport: tr,\n\t}\n\treq, err := http.NewRequest(\"POST\", server, bytes.NewReader(msg))\n\tif err != nil {\n\t\treturn []byte{}, 0, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/dns-message\")\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn []byte{}, 0, err\n\t}\n\tdefer resp.Body.Close()\n\trespBody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn []byte{}, 0, err\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn []byte{}, 0, newError(\"query failed with response code:\", resp.StatusCode)\n\t}\n\trespMsg := new(dns.Msg)\n\terr = respMsg.Unpack(respBody)\n\tif err != nil {\n\t\treturn []byte{}, 0, err\n\t}\n\tif len(respMsg.Answer) > 0 {\n\t\tfor _, answer := range respMsg.Answer {\n\t\t\tif https, ok := answer.(*dns.HTTPS); ok && https.Hdr.Name == dns.Fqdn(domain) {\n\t\t\t\tfor _, v := range https.Value {\n\t\t\t\t\tif echConfig, ok := v.(*dns.SVCBECHConfig); ok {\n\t\t\t\t\t\tnewError(context.Background(), \"Get ECH config:\", echConfig.String(), \" TTL:\", respMsg.Answer[0].Header().Ttl).AtDebug().WriteToLog()\n\t\t\t\t\t\treturn echConfig.ECH, answer.Header().Ttl, nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn []byte{}, 0, newError(\"no ech record found\")\n}\n"
  },
  {
    "path": "transport/internet/tls/ech_go122.go",
    "content": "//go:build !go1.23\n// +build !go1.23\n\npackage tls\n\nimport (\n\t\"crypto/tls\"\n)\n\nfunc ApplyECH(c *Config, config *tls.Config) error { //nolint: staticcheck\n\treturn newError(\"using ECH require go 1.23 or higher\")\n}\n"
  },
  {
    "path": "transport/internet/tls/engine.go",
    "content": "package tls\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n)\n\ntype Engine struct {\n\tconfig *Config\n}\n\nfunc (e *Engine) Client(conn net.Conn, opts ...security.Option) (security.Conn, error) {\n\tvar options []Option\n\tfor _, v := range opts {\n\t\tswitch s := v.(type) {\n\t\tcase security.OptionWithALPN:\n\t\t\toptions = append(options, WithNextProto(s.ALPNs...))\n\t\tcase security.OptionWithDestination:\n\t\t\toptions = append(options, WithDestination(s.Dest))\n\t\tdefault:\n\t\t\treturn nil, newError(\"unknown option\")\n\t\t}\n\t}\n\ttlsConn := Client(conn, e.config.GetTLSConfig(options...))\n\treturn tlsConn, nil\n}\n\nfunc NewTLSSecurityEngineFromConfig(config *Config) (security.Engine, error) {\n\treturn &Engine{config: config}, nil\n}\n"
  },
  {
    "path": "transport/internet/tls/errors.generated.go",
    "content": "package tls\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tls/pin.go",
    "content": "package tls\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/base64\"\n\t\"encoding/pem\"\n)\n\nfunc CalculatePEMCertChainSHA256Hash(certContent []byte) string {\n\tvar certChain [][]byte\n\tfor {\n\t\tblock, remain := pem.Decode(certContent)\n\t\tif block == nil {\n\t\t\tbreak\n\t\t}\n\t\tcertChain = append(certChain, block.Bytes)\n\t\tcertContent = remain\n\t}\n\tcertChainHash := GenerateCertChainHash(certChain)\n\tcertChainHashB64 := base64.StdEncoding.EncodeToString(certChainHash)\n\treturn certChainHashB64\n}\n\nfunc GenerateCertChainHash(rawCerts [][]byte) []byte {\n\tvar hashValue []byte\n\tfor _, certValue := range rawCerts {\n\t\tout := sha256.Sum256(certValue)\n\t\tif hashValue == nil {\n\t\t\thashValue = out[:]\n\t\t} else {\n\t\t\tnewHashValue := sha256.Sum256(append(hashValue, out[:]...))\n\t\t\thashValue = newHashValue[:]\n\t\t}\n\t}\n\treturn hashValue\n}\n"
  },
  {
    "path": "transport/internet/tls/pin_test.go",
    "content": "package tls\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCalculateCertHash(t *testing.T) {\n\t/* This is used to make sure that the hash signature generated is consistent\n\t   Do NOT change this test to suit your modification.\n\t*/\n\tconst CertBundle = `\n-----BEGIN CERTIFICATE-----\nMIIFJjCCBA6gAwIBAgISBL8FgUdEcVYEjdMkTZPgC3ocMA0GCSqGSIb3DQEBCwUA\nMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\nEwJSMzAeFw0yMTAzMjkwMTM2MzlaFw0yMTA2MjcwMTM2MzlaMBsxGTAXBgNVBAMT\nEHNlY3VyZS5ra2Rldi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQDOF/j+s7rHaDMXdhYjffoOFjNZb7n3sCuvubI3qOcgJmr1WPlCEry50KoY8FaB\nIF2HstMIZceN4NoUK7mr3WAvsQTA47uBfuhp+XQmAQW0T/fYD+XbvxtCENEin+xm\nJsvTKZLTKbE08E964J4H+1sBmueP6rvy2Wt95z0XkqoQiikpmLE87WdltQcATvVX\nqqrL64hV0nN4Hdi2Bv1cQ92aR7lZGj8jiQRtTj8y5Ah3Gk3fPoao+yI7gnzembqo\nfddePzz/u8iEuvYAsIYZKn9bbS7rkYoJazL2/xiDZR7usn0SomzmM6lGXDD3FF4b\nlyTkLYwgFVgbGWoz1+eOHD5BAgMBAAGjggJLMIICRzAOBgNVHQ8BAf8EBAMCBaAw\nHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYD\nVR0OBBYEFOPRdApL8XENLXDuU3oPisykGyp+MB8GA1UdIwQYMBaAFBQusxe3WFbL\nrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0cDov\nL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5jci5v\ncmcvMBsGA1UdEQQUMBKCEHNlY3VyZS5ra2Rldi5vcmcwTAYDVR0gBEUwQzAIBgZn\ngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5s\nZXRzZW5jcnlwdC5vcmcwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQD2XJQv0Xcw\nIhRUGAgwlFaO400TGTO/3wwvIAvMTvFk4wAAAXh71yBGAAAEAwBGMEQCIDmziDOn\nehPY2KoAFX8fPWiCm4EBTbGJXBWF1LCotPJBAiBLSCg+krXvbyoABnTm8knv0hbG\n/ZOk8LV6qpw9VoQwGwB3AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kT\nAAABeHvXIIAAAAQDAEgwRgIhAOkeKc52wR3n5QWZfa3zbbicMMSQrTGbQ+1fHNs7\nSsRvAiEAqbflDx1nZRsTA22FfNYfgF6v5Z3/svjiTleWSQad4WswDQYJKoZIhvcN\nAQELBQADggEBAEj8tg+Agf5sNBM9CvjeXbA0fkpGDaQzXEkwefAea5vPgKoGiWSN\npHDkyr0i7+mqa7cMXhmmo20V0/+QDv0nrsCw8pgJuviC3GvK6agT6WfkXM2djJuo\nosPeXOL9KEF/ATv0EyM5tr9TIoRSSYQoRhuqEdg3Dz9Ii8GXR5HhbYr6Cd7gwNHS\nkYeivKDmgv31GHb4twPSE9LZ/U+56lNVvSbJ4csupIF3GnxnxrFSmijYNOPoM6mj\ntzY45d4mjPs0fKCFKSsVM6YT0tX4NwIKsOaeQg30WLtRyDwYm6ma/a/UUUS0FloZ\n2/p85glOgzownfoRjzTbqHu8ewtMd6Apc0E=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIEZTCCA02gAwIBAgIQQAF1BIMUpMghjISpDBbN3zANBgkqhkiG9w0BAQsFADA/\nMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\nDkRTVCBSb290IENBIFgzMB4XDTIwMTAwNzE5MjE0MFoXDTIxMDkyOTE5MjE0MFow\nMjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxCzAJBgNVBAMT\nAlIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuwIVKMz2oJTTDxLs\njVWSw/iC8ZmmekKIp10mqrUrucVMsa+Oa/l1yKPXD0eUFFU1V4yeqKI5GfWCPEKp\nTm71O8Mu243AsFzzWTjn7c9p8FoLG77AlCQlh/o3cbMT5xys4Zvv2+Q7RVJFlqnB\nU840yFLuta7tj95gcOKlVKu2bQ6XpUA0ayvTvGbrZjR8+muLj1cpmfgwF126cm/7\ngcWt0oZYPRfH5wm78Sv3htzB2nFd1EbjzK0lwYi8YGd1ZrPxGPeiXOZT/zqItkel\n/xMY6pgJdz+dU/nPAeX1pnAXFK9jpP+Zs5Od3FOnBv5IhR2haa4ldbsTzFID9e1R\noYvbFQIDAQABo4IBaDCCAWQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E\nBAMCAYYwSwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5p\nZGVudHJ1c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTE\np7Gkeyxx+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEE\nAYLfEwEBATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0\nLmNvbS9EU1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYf\nr52LFMLGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0B\nAQsFAAOCAQEA2UzgyfWEiDcx27sT4rP8i2tiEmxYt0l+PAK3qB8oYevO4C5z70kH\nejWEHx2taPDY/laBL21/WKZuNTYQHHPD5b1tXgHXbnL7KqC401dk5VvCadTQsvd8\nS8MXjohyc9z9/G2948kLjmE6Flh9dDYrVYA9x2O+hEPGOaEOa1eePynBgPayvUfL\nqjBstzLhWVQLGAkXXmNs+5ZnPBxzDJOLxhF2JIbeQAcH5H0tZrUlo5ZYyOqA7s9p\nO5b85o3AM/OJ+CktFBQtfvBhcJVd9wvlwPsk+uyOy2HI7mNxKKgsBTt375teA2Tw\nUdHkhVNcsAKX1H7GNNLOEADksd86wuoXvg==\n-----END CERTIFICATE-----\n`\n\tt.Run(\"bundle\", func(t *testing.T) {\n\t\thash := CalculatePEMCertChainSHA256Hash([]byte(CertBundle))\n\t\tassert.Equal(t, \"WF65fBkgltadMnXryOMZ6TEYeV4d5Q0uu4SGXGZ0RjI=\", hash)\n\t})\n\tconst Single = `-----BEGIN CERTIFICATE-----\nMIIFJjCCBA6gAwIBAgISBL8FgUdEcVYEjdMkTZPgC3ocMA0GCSqGSIb3DQEBCwUA\nMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\nEwJSMzAeFw0yMTAzMjkwMTM2MzlaFw0yMTA2MjcwMTM2MzlaMBsxGTAXBgNVBAMT\nEHNlY3VyZS5ra2Rldi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQDOF/j+s7rHaDMXdhYjffoOFjNZb7n3sCuvubI3qOcgJmr1WPlCEry50KoY8FaB\nIF2HstMIZceN4NoUK7mr3WAvsQTA47uBfuhp+XQmAQW0T/fYD+XbvxtCENEin+xm\nJsvTKZLTKbE08E964J4H+1sBmueP6rvy2Wt95z0XkqoQiikpmLE87WdltQcATvVX\nqqrL64hV0nN4Hdi2Bv1cQ92aR7lZGj8jiQRtTj8y5Ah3Gk3fPoao+yI7gnzembqo\nfddePzz/u8iEuvYAsIYZKn9bbS7rkYoJazL2/xiDZR7usn0SomzmM6lGXDD3FF4b\nlyTkLYwgFVgbGWoz1+eOHD5BAgMBAAGjggJLMIICRzAOBgNVHQ8BAf8EBAMCBaAw\nHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYD\nVR0OBBYEFOPRdApL8XENLXDuU3oPisykGyp+MB8GA1UdIwQYMBaAFBQusxe3WFbL\nrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0cDov\nL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5jci5v\ncmcvMBsGA1UdEQQUMBKCEHNlY3VyZS5ra2Rldi5vcmcwTAYDVR0gBEUwQzAIBgZn\ngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5s\nZXRzZW5jcnlwdC5vcmcwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQD2XJQv0Xcw\nIhRUGAgwlFaO400TGTO/3wwvIAvMTvFk4wAAAXh71yBGAAAEAwBGMEQCIDmziDOn\nehPY2KoAFX8fPWiCm4EBTbGJXBWF1LCotPJBAiBLSCg+krXvbyoABnTm8knv0hbG\n/ZOk8LV6qpw9VoQwGwB3AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kT\nAAABeHvXIIAAAAQDAEgwRgIhAOkeKc52wR3n5QWZfa3zbbicMMSQrTGbQ+1fHNs7\nSsRvAiEAqbflDx1nZRsTA22FfNYfgF6v5Z3/svjiTleWSQad4WswDQYJKoZIhvcN\nAQELBQADggEBAEj8tg+Agf5sNBM9CvjeXbA0fkpGDaQzXEkwefAea5vPgKoGiWSN\npHDkyr0i7+mqa7cMXhmmo20V0/+QDv0nrsCw8pgJuviC3GvK6agT6WfkXM2djJuo\nosPeXOL9KEF/ATv0EyM5tr9TIoRSSYQoRhuqEdg3Dz9Ii8GXR5HhbYr6Cd7gwNHS\nkYeivKDmgv31GHb4twPSE9LZ/U+56lNVvSbJ4csupIF3GnxnxrFSmijYNOPoM6mj\ntzY45d4mjPs0fKCFKSsVM6YT0tX4NwIKsOaeQg30WLtRyDwYm6ma/a/UUUS0FloZ\n2/p85glOgzownfoRjzTbqHu8ewtMd6Apc0E=\n-----END CERTIFICATE-----\n`\n\tt.Run(\"single\", func(t *testing.T) {\n\t\thash := CalculatePEMCertChainSHA256Hash([]byte(Single))\n\t\tassert.Equal(t, \"FW3SVMCL6um2wVltOdgJ3DpI82aredw83YoCblkMkVM=\", hash)\n\t})\n}\n"
  },
  {
    "path": "transport/internet/tls/tls.go",
    "content": "package tls\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nvar _ buf.Writer = (*Conn)(nil)\n\ntype Conn struct {\n\t*tls.Conn\n}\n\nfunc (c *Conn) GetConnectionApplicationProtocol() (string, error) {\n\tif err := c.Handshake(); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn c.ConnectionState().NegotiatedProtocol, nil\n}\n\nfunc (c *Conn) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tmb = buf.Compact(mb)\n\tmb, err := buf.WriteMultiBuffer(c, mb)\n\tbuf.ReleaseMulti(mb)\n\treturn err\n}\n\nfunc (c *Conn) HandshakeAddress() net.Address {\n\tif err := c.Handshake(); err != nil {\n\t\treturn nil\n\t}\n\tstate := c.ConnectionState()\n\tif state.ServerName == \"\" {\n\t\treturn nil\n\t}\n\treturn net.ParseAddress(state.ServerName)\n}\n\n// Client initiates a TLS client handshake on the given connection.\nfunc Client(c net.Conn, config *tls.Config) *Conn {\n\ttlsConn := tls.Client(c, config)\n\treturn &Conn{Conn: tlsConn}\n}\n\n/*\nfunc copyConfig(c *tls.Config) *utls.Config {\n\treturn &utls.Config{\n\t\tNextProtos:         c.NextProtos,\n\t\tServerName:         c.ServerName,\n\t\tInsecureSkipVerify: c.InsecureSkipVerify,\n\t\tMinVersion:         utls.VersionTLS12,\n\t\tMaxVersion:         utls.VersionTLS12,\n\t}\n}\n\nfunc UClient(c net.Conn, config *tls.Config) net.Conn {\n\tuConfig := copyConfig(config)\n\treturn utls.Client(c, uConfig)\n}\n*/\n\n// Server initiates a TLS server handshake on the given connection.\nfunc Server(c net.Conn, config *tls.Config) net.Conn {\n\ttlsConn := tls.Server(c, config)\n\treturn &Conn{Conn: tlsConn}\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewTLSSecurityEngineFromConfig(config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tls/utls/config.pb.go",
    "content": "package utls\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\ttls \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 ForcedALPN int32\n\nconst (\n\tForcedALPN_TRANSPORT_PREFERENCE_TAKE_PRIORITY ForcedALPN = 0\n\tForcedALPN_NO_ALPN                            ForcedALPN = 1\n\tForcedALPN_UTLS_PRESET                        ForcedALPN = 2\n)\n\n// Enum value maps for ForcedALPN.\nvar (\n\tForcedALPN_name = map[int32]string{\n\t\t0: \"TRANSPORT_PREFERENCE_TAKE_PRIORITY\",\n\t\t1: \"NO_ALPN\",\n\t\t2: \"UTLS_PRESET\",\n\t}\n\tForcedALPN_value = map[string]int32{\n\t\t\"TRANSPORT_PREFERENCE_TAKE_PRIORITY\": 0,\n\t\t\"NO_ALPN\":                            1,\n\t\t\"UTLS_PRESET\":                        2,\n\t}\n)\n\nfunc (x ForcedALPN) Enum() *ForcedALPN {\n\tp := new(ForcedALPN)\n\t*p = x\n\treturn p\n}\n\nfunc (x ForcedALPN) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (ForcedALPN) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_transport_internet_tls_utls_config_proto_enumTypes[0].Descriptor()\n}\n\nfunc (ForcedALPN) Type() protoreflect.EnumType {\n\treturn &file_transport_internet_tls_utls_config_proto_enumTypes[0]\n}\n\nfunc (x ForcedALPN) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use ForcedALPN.Descriptor instead.\nfunc (ForcedALPN) EnumDescriptor() ([]byte, []int) {\n\treturn file_transport_internet_tls_utls_config_proto_rawDescGZIP(), []int{0}\n}\n\ntype Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tTlsConfig     *tls.Config            `protobuf:\"bytes,1,opt,name=tls_config,json=tlsConfig,proto3\" json:\"tls_config,omitempty\"`\n\tImitate       string                 `protobuf:\"bytes,2,opt,name=imitate,proto3\" json:\"imitate,omitempty\"`\n\tNoSNI         bool                   `protobuf:\"varint,3,opt,name=noSNI,proto3\" json:\"noSNI,omitempty\"`\n\tForceAlpn     ForcedALPN             `protobuf:\"varint,4,opt,name=force_alpn,json=forceAlpn,proto3,enum=v2ray.core.transport.internet.tls.utls.ForcedALPN\" json:\"force_alpn,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_tls_utls_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tls_utls_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tls_utls_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetTlsConfig() *tls.Config {\n\tif x != nil {\n\t\treturn x.TlsConfig\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetImitate() string {\n\tif x != nil {\n\t\treturn x.Imitate\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetNoSNI() bool {\n\tif x != nil {\n\t\treturn x.NoSNI\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetForceAlpn() ForcedALPN {\n\tif x != nil {\n\t\treturn x.ForceAlpn\n\t}\n\treturn ForcedALPN_TRANSPORT_PREFERENCE_TAKE_PRIORITY\n}\n\nvar File_transport_internet_tls_utls_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tls_utls_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"(transport/internet/tls/utls/config.proto\\x12&v2ray.core.transport.internet.tls.utls\\x1a common/protoext/extensions.proto\\x1a#transport/internet/tls/config.proto\\\"\\xef\\x01\\n\" +\n\t\"\\x06Config\\x12H\\n\" +\n\t\"\\n\" +\n\t\"tls_config\\x18\\x01 \\x01(\\v2).v2ray.core.transport.internet.tls.ConfigR\\ttlsConfig\\x12\\x18\\n\" +\n\t\"\\aimitate\\x18\\x02 \\x01(\\tR\\aimitate\\x12\\x14\\n\" +\n\t\"\\x05noSNI\\x18\\x03 \\x01(\\bR\\x05noSNI\\x12Q\\n\" +\n\t\"\\n\" +\n\t\"force_alpn\\x18\\x04 \\x01(\\x0e22.v2ray.core.transport.internet.tls.utls.ForcedALPNR\\tforceAlpn:\\x18\\x82\\xb5\\x18\\x14\\n\" +\n\t\"\\bsecurity\\x12\\x04utls\\x90\\xff)\\x01*R\\n\" +\n\t\"\\n\" +\n\t\"ForcedALPN\\x12&\\n\" +\n\t\"\\\"TRANSPORT_PREFERENCE_TAKE_PRIORITY\\x10\\x00\\x12\\v\\n\" +\n\t\"\\aNO_ALPN\\x10\\x01\\x12\\x0f\\n\" +\n\t\"\\vUTLS_PRESET\\x10\\x02B\\x93\\x01\\n\" +\n\t\"*com.v2ray.core.transport.internet.tls.utlsP\\x01Z:github.com/v2fly/v2ray-core/v5/transport/internet/tls/utls\\xaa\\x02&V2Ray.Core.Transport.Internet.Tls.UTlsb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tls_utls_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tls_utls_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tls_utls_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tls_utls_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tls_utls_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tls_utls_config_proto_rawDesc), len(file_transport_internet_tls_utls_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tls_utls_config_proto_rawDescData\n}\n\nvar file_transport_internet_tls_utls_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_transport_internet_tls_utls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_tls_utls_config_proto_goTypes = []any{\n\t(ForcedALPN)(0),    // 0: v2ray.core.transport.internet.tls.utls.ForcedALPN\n\t(*Config)(nil),     // 1: v2ray.core.transport.internet.tls.utls.Config\n\t(*tls.Config)(nil), // 2: v2ray.core.transport.internet.tls.Config\n}\nvar file_transport_internet_tls_utls_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.transport.internet.tls.utls.Config.tls_config:type_name -> v2ray.core.transport.internet.tls.Config\n\t0, // 1: v2ray.core.transport.internet.tls.utls.Config.force_alpn:type_name -> v2ray.core.transport.internet.tls.utls.ForcedALPN\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_tls_utls_config_proto_init() }\nfunc file_transport_internet_tls_utls_config_proto_init() {\n\tif File_transport_internet_tls_utls_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tls_utls_config_proto_rawDesc), len(file_transport_internet_tls_utls_config_proto_rawDesc)),\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tls_utls_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tls_utls_config_proto_depIdxs,\n\t\tEnumInfos:         file_transport_internet_tls_utls_config_proto_enumTypes,\n\t\tMessageInfos:      file_transport_internet_tls_utls_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tls_utls_config_proto = out.File\n\tfile_transport_internet_tls_utls_config_proto_goTypes = nil\n\tfile_transport_internet_tls_utls_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tls/utls/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tls.utls;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tls.UTls\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tls/utls\";\noption java_package = \"com.v2ray.core.transport.internet.tls.utls\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"transport/internet/tls/config.proto\";\n\nenum ForcedALPN{\n  TRANSPORT_PREFERENCE_TAKE_PRIORITY = 0;\n  NO_ALPN = 1;\n  UTLS_PRESET = 2;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"security\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"utls\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  v2ray.core.transport.internet.tls.Config tls_config = 1;\n  string imitate = 2;\n  bool noSNI = 3;\n  ForcedALPN force_alpn = 4;\n}"
  },
  {
    "path": "transport/internet/tls/utls/errors.generated.go",
    "content": "package utls\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tls/utls/nameMapper.go",
    "content": "package utls\n\nimport utls \"github.com/refraction-networking/utls\"\n\nvar clientHelloIDMap = map[string]*utls.ClientHelloID{\n\t\"randomized\":        &utls.HelloRandomized,\n\t\"randomizedalpn\":    &utls.HelloRandomizedALPN,\n\t\"randomizednoalpn\":  &utls.HelloRandomizedNoALPN,\n\t\"firefox_auto\":      &utls.HelloFirefox_Auto,\n\t\"firefox_55\":        &utls.HelloFirefox_55,\n\t\"firefox_56\":        &utls.HelloFirefox_56,\n\t\"firefox_63\":        &utls.HelloFirefox_63,\n\t\"firefox_65\":        &utls.HelloFirefox_65,\n\t\"firefox_99\":        &utls.HelloFirefox_99,\n\t\"firefox_102\":       &utls.HelloFirefox_102,\n\t\"firefox_105\":       &utls.HelloFirefox_105,\n\t\"chrome_auto\":       &utls.HelloChrome_Auto,\n\t\"chrome_58\":         &utls.HelloChrome_58,\n\t\"chrome_62\":         &utls.HelloChrome_62,\n\t\"chrome_70\":         &utls.HelloChrome_70,\n\t\"chrome_72\":         &utls.HelloChrome_72,\n\t\"chrome_83\":         &utls.HelloChrome_83,\n\t\"chrome_87\":         &utls.HelloChrome_87,\n\t\"chrome_96\":         &utls.HelloChrome_96,\n\t\"chrome_100\":        &utls.HelloChrome_100,\n\t\"chrome_102\":        &utls.HelloChrome_102,\n\t\"ios_auto\":          &utls.HelloIOS_Auto,\n\t\"ios_11_1\":          &utls.HelloIOS_11_1,\n\t\"ios_12_1\":          &utls.HelloIOS_12_1,\n\t\"ios_13\":            &utls.HelloIOS_13,\n\t\"ios_14\":            &utls.HelloIOS_14,\n\t\"android_11_okhttp\": &utls.HelloAndroid_11_OkHttp,\n\t\"edge_auto\":         &utls.HelloEdge_Auto,\n\t\"edge_85\":           &utls.HelloEdge_85,\n\t\"edge_106\":          &utls.HelloEdge_106,\n\t\"safari_auto\":       &utls.HelloSafari_Auto,\n\t\"safari_16_0\":       &utls.HelloSafari_16_0,\n\t\"360_auto\":          &utls.Hello360_Auto,\n\t\"360_7_5\":           &utls.Hello360_7_5,\n\t\"360_11_0\":          &utls.Hello360_11_0,\n\t\"qq_auto\":           &utls.HelloQQ_Auto,\n\t\"qq_11_1\":           &utls.HelloQQ_11_1,\n}\n\nfunc nameToUTLSPreset(name string) (*utls.ClientHelloID, error) {\n\tpreset, ok := clientHelloIDMap[name]\n\tif !ok {\n\t\treturn nil, newError(\"unknown preset name\")\n\t}\n\treturn preset, nil\n}\n"
  },
  {
    "path": "transport/internet/tls/utls/utls.go",
    "content": "package utls\n\nimport (\n\t\"context\"\n\tsystls \"crypto/tls\"\n\n\tutls \"github.com/refraction-networking/utls\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc NewUTLSSecurityEngineFromConfig(config *Config) (security.Engine, error) {\n\tif config.TlsConfig == nil {\n\t\treturn nil, newError(\"mandatory field tls_config is not specified\")\n\t}\n\treturn &Engine{config: config}, nil\n}\n\ntype Engine struct {\n\tconfig *Config\n}\n\nfunc (e Engine) Client(conn net.Conn, opts ...security.Option) (security.Conn, error) {\n\tvar options []tls.Option\n\tfor _, v := range opts {\n\t\tswitch s := v.(type) {\n\t\tcase security.OptionWithALPN:\n\t\t\tif e.config.ForceAlpn == ForcedALPN_TRANSPORT_PREFERENCE_TAKE_PRIORITY {\n\t\t\t\toptions = append(options, tls.WithNextProto(s.ALPNs...))\n\t\t\t}\n\t\tcase security.OptionWithDestination:\n\t\t\toptions = append(options, tls.WithDestination(s.Dest))\n\t\tdefault:\n\t\t\treturn nil, newError(\"unknown option\")\n\t\t}\n\t}\n\ttlsConfig := e.config.TlsConfig.GetTLSConfig(options...)\n\tutlsConfig, err := uTLSConfigFromTLSConfig(tlsConfig)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to generate utls config from tls config\").Base(err)\n\t}\n\n\tpreset, err := nameToUTLSPreset(e.config.Imitate)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to get utls preset from name\").Base(err)\n\t}\n\n\tutlsClientConn := utls.UClient(conn, utlsConfig, *preset)\n\n\tif e.config.NoSNI {\n\t\terr = utlsClientConn.RemoveSNIExtension()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to remove server name indication from utls client hello\").Base(err)\n\t\t}\n\t}\n\n\terr = utlsClientConn.BuildHandshakeState()\n\tif err != nil {\n\t\treturn nil, newError(\"unable to build utls handshake state\").Base(err)\n\t}\n\n\t// ALPN is necessary for protocols like websocket to work. The uTLS setting may be overwritten on call into\n\t// BuildHandshakeState, so we need to check the original tls settings.\n\tif tlsConfig.NextProtos != nil {\n\t\tfor n, v := range utlsClientConn.Extensions {\n\t\t\tif aplnExtension, ok := v.(*utls.ALPNExtension); ok {\n\t\t\t\tif e.config.ForceAlpn == ForcedALPN_TRANSPORT_PREFERENCE_TAKE_PRIORITY {\n\t\t\t\t\taplnExtension.AlpnProtocols = tlsConfig.NextProtos\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif e.config.ForceAlpn == ForcedALPN_NO_ALPN {\n\t\t\t\t\tutlsClientConn.Extensions = append(utlsClientConn.Extensions[:n], utlsClientConn.Extensions[n+1:]...)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\terr = utlsClientConn.BuildHandshakeState()\n\tif err != nil {\n\t\treturn nil, newError(\"unable to build utls handshake state after modification\").Base(err)\n\t}\n\n\terr = utlsClientConn.Handshake()\n\tif err != nil {\n\t\treturn nil, newError(\"unable to finish utls handshake\").Base(err)\n\t}\n\treturn uTLSClientConnection{utlsClientConn}, nil\n}\n\ntype uTLSClientConnection struct {\n\t*utls.UConn\n}\n\nfunc (u uTLSClientConnection) GetConnectionApplicationProtocol() (string, error) {\n\tif err := u.Handshake(); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn u.ConnectionState().NegotiatedProtocol, nil\n}\n\nfunc uTLSConfigFromTLSConfig(config *systls.Config) (*utls.Config, error) { // nolint: unparam\n\tuconfig := &utls.Config{\n\t\tRand:                  config.Rand,\n\t\tTime:                  config.Time,\n\t\tRootCAs:               config.RootCAs,\n\t\tNextProtos:            config.NextProtos,\n\t\tServerName:            config.ServerName,\n\t\tVerifyPeerCertificate: config.VerifyPeerCertificate,\n\t\tInsecureSkipVerify:    config.InsecureSkipVerify,\n\t\tClientAuth:            utls.ClientAuthType(config.ClientAuth),\n\t\tClientCAs:             config.ClientCAs,\n\t}\n\treturn uconfig, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewUTLSSecurityEngineFromConfig(config.(*Config))\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/data.pb.go",
    "content": "package tlsmirror\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 EnrollmentConfirmationReq struct {\n\tstate                            protoimpl.MessageState `protogen:\"open.v1\"`\n\tServerIdentifier                 []byte                 `protobuf:\"bytes,1,opt,name=server_identifier,json=serverIdentifier,proto3\" json:\"server_identifier,omitempty\"`\n\tCarrierTlsConnectionClientRandom []byte                 `protobuf:\"bytes,2,opt,name=carrier_tls_connection_client_random,json=carrierTlsConnectionClientRandom,proto3\" json:\"carrier_tls_connection_client_random,omitempty\"`\n\tCarrierTlsConnectionServerRandom []byte                 `protobuf:\"bytes,3,opt,name=carrier_tls_connection_server_random,json=carrierTlsConnectionServerRandom,proto3\" json:\"carrier_tls_connection_server_random,omitempty\"`\n\tClientIdentifier                 []byte                 `protobuf:\"bytes,4,opt,name=client_identifier,json=clientIdentifier,proto3\" json:\"client_identifier,omitempty\"` // Implicated\n\tReplyAddressTag                  []byte                 `protobuf:\"bytes,5,opt,name=reply_address_tag,json=replyAddressTag,proto3\" json:\"reply_address_tag,omitempty\"`\n\tunknownFields                    protoimpl.UnknownFields\n\tsizeCache                        protoimpl.SizeCache\n}\n\nfunc (x *EnrollmentConfirmationReq) Reset() {\n\t*x = EnrollmentConfirmationReq{}\n\tmi := &file_transport_internet_tlsmirror_data_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *EnrollmentConfirmationReq) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*EnrollmentConfirmationReq) ProtoMessage() {}\n\nfunc (x *EnrollmentConfirmationReq) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_data_proto_msgTypes[0]\n\tif 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 EnrollmentConfirmationReq.ProtoReflect.Descriptor instead.\nfunc (*EnrollmentConfirmationReq) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_data_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *EnrollmentConfirmationReq) GetServerIdentifier() []byte {\n\tif x != nil {\n\t\treturn x.ServerIdentifier\n\t}\n\treturn nil\n}\n\nfunc (x *EnrollmentConfirmationReq) GetCarrierTlsConnectionClientRandom() []byte {\n\tif x != nil {\n\t\treturn x.CarrierTlsConnectionClientRandom\n\t}\n\treturn nil\n}\n\nfunc (x *EnrollmentConfirmationReq) GetCarrierTlsConnectionServerRandom() []byte {\n\tif x != nil {\n\t\treturn x.CarrierTlsConnectionServerRandom\n\t}\n\treturn nil\n}\n\nfunc (x *EnrollmentConfirmationReq) GetClientIdentifier() []byte {\n\tif x != nil {\n\t\treturn x.ClientIdentifier\n\t}\n\treturn nil\n}\n\nfunc (x *EnrollmentConfirmationReq) GetReplyAddressTag() []byte {\n\tif x != nil {\n\t\treturn x.ReplyAddressTag\n\t}\n\treturn nil\n}\n\ntype EnrollmentConfirmationResp struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tEnrolled      bool                   `protobuf:\"varint,1,opt,name=enrolled,proto3\" json:\"enrolled,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *EnrollmentConfirmationResp) Reset() {\n\t*x = EnrollmentConfirmationResp{}\n\tmi := &file_transport_internet_tlsmirror_data_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *EnrollmentConfirmationResp) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*EnrollmentConfirmationResp) ProtoMessage() {}\n\nfunc (x *EnrollmentConfirmationResp) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_data_proto_msgTypes[1]\n\tif 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 EnrollmentConfirmationResp.ProtoReflect.Descriptor instead.\nfunc (*EnrollmentConfirmationResp) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_data_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *EnrollmentConfirmationResp) GetEnrolled() bool {\n\tif x != nil {\n\t\treturn x.Enrolled\n\t}\n\treturn false\n}\n\nvar File_transport_internet_tlsmirror_data_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tlsmirror_data_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"'transport/internet/tlsmirror/data.proto\\x12'v2ray.core.transport.internet.tlsmirror\\\"\\xc1\\x02\\n\" +\n\t\"\\x19EnrollmentConfirmationReq\\x12+\\n\" +\n\t\"\\x11server_identifier\\x18\\x01 \\x01(\\fR\\x10serverIdentifier\\x12N\\n\" +\n\t\"$carrier_tls_connection_client_random\\x18\\x02 \\x01(\\fR carrierTlsConnectionClientRandom\\x12N\\n\" +\n\t\"$carrier_tls_connection_server_random\\x18\\x03 \\x01(\\fR carrierTlsConnectionServerRandom\\x12+\\n\" +\n\t\"\\x11client_identifier\\x18\\x04 \\x01(\\fR\\x10clientIdentifier\\x12*\\n\" +\n\t\"\\x11reply_address_tag\\x18\\x05 \\x01(\\fR\\x0freplyAddressTag\\\"8\\n\" +\n\t\"\\x1aEnrollmentConfirmationResp\\x12\\x1a\\n\" +\n\t\"\\benrolled\\x18\\x01 \\x01(\\bR\\benrolledB\\x96\\x01\\n\" +\n\t\"+com.v2ray.core.transport.internet.tlsmirrorP\\x01Z;github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\\xaa\\x02'V2Ray.Core.Transport.Internet.Tlsmirrorb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tlsmirror_data_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tlsmirror_data_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tlsmirror_data_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tlsmirror_data_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tlsmirror_data_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_data_proto_rawDesc), len(file_transport_internet_tlsmirror_data_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tlsmirror_data_proto_rawDescData\n}\n\nvar file_transport_internet_tlsmirror_data_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_tlsmirror_data_proto_goTypes = []any{\n\t(*EnrollmentConfirmationReq)(nil),  // 0: v2ray.core.transport.internet.tlsmirror.EnrollmentConfirmationReq\n\t(*EnrollmentConfirmationResp)(nil), // 1: v2ray.core.transport.internet.tlsmirror.EnrollmentConfirmationResp\n}\nvar file_transport_internet_tlsmirror_data_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_transport_internet_tlsmirror_data_proto_init() }\nfunc file_transport_internet_tlsmirror_data_proto_init() {\n\tif File_transport_internet_tlsmirror_data_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_data_proto_rawDesc), len(file_transport_internet_tlsmirror_data_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tlsmirror_data_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tlsmirror_data_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_tlsmirror_data_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tlsmirror_data_proto = out.File\n\tfile_transport_internet_tlsmirror_data_proto_goTypes = nil\n\tfile_transport_internet_tlsmirror_data_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/data.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tlsmirror;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tlsmirror\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\";\noption java_package = \"com.v2ray.core.transport.internet.tlsmirror\";\noption java_multiple_files = true;\n\n\nmessage EnrollmentConfirmationReq{\n  bytes server_identifier = 1;\n  bytes carrier_tls_connection_client_random = 2;\n  bytes carrier_tls_connection_server_random = 3;\n  bytes client_identifier = 4; // Implicated\n  bytes reply_address_tag = 5;\n}\nmessage EnrollmentConfirmationResp{\n  bool enrolled = 1;\n}"
  },
  {
    "path": "transport/internet/tlsmirror/httponconnection/errors.generated.go",
    "content": "package httponconnection\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/httponconnection/singleconnhttp.go",
    "content": "package httponconnection\n\nimport (\n\t\"bufio\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"golang.org/x/net/http2\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype HttpRequestTransport interface {\n\thttp.RoundTripper\n}\n\nfunc newHTTPRequestTransportH1(conn net.Conn) HttpRequestTransport {\n\treturn &httpRequestTransportH1{\n\t\tconn:      conn,\n\t\tbufReader: bufio.NewReader(conn),\n\t}\n}\n\ntype httpRequestTransportH1 struct {\n\tconn      net.Conn\n\tbufReader *bufio.Reader\n}\n\nfunc (h *httpRequestTransportH1) RoundTrip(req *http.Request) (*http.Response, error) {\n\treq.Proto = \"HTTP/1.1\"\n\treq.ProtoMajor = 1\n\treq.ProtoMinor = 1\n\n\terr := req.Write(h.conn)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn http.ReadResponse(h.bufReader, req)\n}\n\nfunc newHTTPRequestTransportH2(conn net.Conn) HttpRequestTransport {\n\ttransport := &http2.Transport{}\n\tclientConn, err := transport.NewClientConn(conn)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &httpRequestTransportH2{\n\t\ttransport:        transport,\n\t\tclientConnection: clientConn,\n\t}\n}\n\ntype httpRequestTransportH2 struct {\n\ttransport        *http2.Transport\n\tclientConnection *http2.ClientConn\n}\n\nfunc (h *httpRequestTransportH2) RoundTrip(request *http.Request) (*http.Response, error) {\n\trequest.ProtoMajor = 2\n\trequest.ProtoMinor = 0\n\n\tresponse, err := h.clientConnection.RoundTrip(request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn response, nil\n}\n\nfunc newSingleConnectionHTTPTransport(conn net.Conn, alpn string) (HttpRequestTransport, error) {\n\tswitch alpn {\n\tcase \"h2\":\n\t\treturn newHTTPRequestTransportH2(conn), nil\n\tcase \"http/1.1\", \"\":\n\t\treturn newHTTPRequestTransportH1(conn), nil\n\tdefault:\n\t\treturn nil, newError(\"unknown alpn: \" + alpn).AtWarning()\n\t}\n}\n\nfunc NewSingleConnectionHTTPTransport(conn net.Conn, alpn string) (HttpRequestTransport, error) {\n\treturn newSingleConnectionHTTPTransport(conn, alpn)\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/interface.go",
    "content": "package tlsmirror\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n)\n\ntype TLSRecord struct {\n\tRecordType            byte\n\tLegacyProtocolVersion [2]byte\n\tRecordLength          uint16\n\tFragment              []byte\n\n\t// Annotations are used to store additional information about the record. Never sent over the wire.\n\tInsertedMessage bool\n}\n\ntype RecordReader interface {\n\tReadNextRecord(rejectProfile PartialTLSRecordRejectProfile) (*TLSRecord, error)\n}\n\ntype RecordWriter interface {\n\tWriteRecord(record *TLSRecord) error\n}\n\ntype Peeker interface {\n\tPeek(n int) ([]byte, error)\n}\n\ntype PartialTLSRecordRejectProfile interface {\n\tTestIfReject(record *TLSRecord, readyFields int) error\n}\n\ntype MessageHook func(message *TLSRecord) (drop bool, ok error)\n\ntype ExplicitNonceDetection func(cipherSuite uint16) bool\n\ntype InsertableTLSConn interface {\n\tcommon.Closable\n\tGetHandshakeRandom() ([]byte, []byte, error)\n\tInsertC2SMessage(message *TLSRecord) error\n\tInsertS2CMessage(message *TLSRecord) error\n\tGetApplicationDataExplicitNonceReservedOverheadHeaderLength() (int, error)\n}\n\nconst TrafficGeneratorManagedConnectionContextKey = \"TrafficGeneratorManagedConnection-ku63HMMD-kduCPhr8-DN4y6WEa\"\n\ntype TrafficGeneratorManagedConnection interface {\n\tRecallTrafficGenerator() error\n\tWaitConnectionReady() context.Context\n\tIsConnectionInvalidated() bool\n}\n\ntype ConnectionEnrollmentConfirmation interface {\n\tVerifyConnectionEnrollment(req *EnrollmentConfirmationReq) (*EnrollmentConfirmationResp, error)\n}\n\nconst EnrollmentVerificationControlConnectionPostfix = \".tlsmirror-controlconnection.v2fly.arpa\"\n\ntype InsertableTLSConnForEnrollment interface {\n\tInsertableTLSConnEnrollmentEventReceiver\n}\n\ntype InsertableTLSConnEnrollmentEventReceiver interface {\n\tConnectionEnrollmentConfirmation\n}\n\ntype RemoveConnectionFunc func() error\n\ntype ConnectionEnrollmentConfirmationProcessor interface {\n\tConnectionEnrollmentConfirmation\n\tAddConnection(ctx context.Context, clientRandom, ServerRandom []byte, conn InsertableTLSConnForEnrollment) (RemoveConnectionFunc, error)\n}\n\ntype ConnectionEnrollmentConfirmationClientInstanceConfig struct {\n\tDefaultOutboundTag string\n}\n\ntype ConnectionEnrollmentConfirmationClientInstanceConfigReceiver interface {\n\tOnConnectionEnrollmentConfirmationClientInstanceConfigReady(ConnectionEnrollmentConfirmationClientInstanceConfig)\n}\n\ntype ConnectionEnrollmentConfirmationServerInstanceConfig struct {\n\tEnrollmentProcessor ConnectionEnrollmentConfirmationProcessor\n}\n\ntype ConnectionEnrollmentConfirmationServerInstanceConfigReceiver interface {\n\tOnConnectionEnrollmentConfirmationServerInstanceConfigReady(ConnectionEnrollmentConfirmationServerInstanceConfig)\n}\n\ntype ConnectionLoopbackPrevention struct {\n\tKey string\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorbase/base.go",
    "content": "package mirrorbase\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorbase/conn.go",
    "content": "package mirrorbase\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcommon\"\n)\n\n// NewMirroredTLSConn creates a new mirrored TLS connection.\n// No stable interface\nfunc NewMirroredTLSConn(ctx context.Context, clientConn net.Conn,\n\tserverConn net.Conn, onC2SMessage, onS2CMessage tlsmirror.MessageHook,\n\tclosable common.Closable, explicitNonceDetection tlsmirror.ExplicitNonceDetection,\n\tonC2SMessageTx, onS2CMessageTx tlsmirror.MessageHook,\n) tlsmirror.InsertableTLSConn {\n\texplicitNonceDetectionReady, explicitNonceDetectionOver := context.WithCancel(ctx)\n\tc := &conn{\n\t\tctx:                         ctx,\n\t\tclientConn:                  clientConn,\n\t\tserverConn:                  serverConn,\n\t\tc2sInsert:                   make(chan *tlsmirror.TLSRecord, 100),\n\t\ts2cInsert:                   make(chan *tlsmirror.TLSRecord, 100),\n\t\tOnC2SMessage:                onC2SMessage,\n\t\tOnS2CMessage:                onS2CMessage,\n\t\texplicitNonceDetection:      explicitNonceDetection,\n\t\texplicitNonceDetectionReady: explicitNonceDetectionReady,\n\t\texplicitNonceDetectionOver:  explicitNonceDetectionOver,\n\t\tOnC2SMessageTx:              onC2SMessageTx,\n\t\tOnS2CMessageTx:              onS2CMessageTx,\n\t}\n\tc.ctx, c.done = context.WithCancel(ctx)\n\tgo c.c2sWorker()\n\tgo c.s2cWorker()\n\tgo func() {\n\t\t<-c.ctx.Done()\n\t\tif closable != nil {\n\t\t\tclosable.Close()\n\t\t}\n\t\tc.clientConn.Close()\n\t\tc.serverConn.Close()\n\t}()\n\treturn c\n}\n\ntype conn struct {\n\tctx  context.Context\n\tdone context.CancelFunc\n\n\tclientConn net.Conn\n\tserverConn net.Conn\n\n\tOnC2SMessage           tlsmirror.MessageHook\n\tOnS2CMessage           tlsmirror.MessageHook\n\texplicitNonceDetection tlsmirror.ExplicitNonceDetection\n\n\tOnC2SMessageTx tlsmirror.MessageHook\n\tOnS2CMessageTx tlsmirror.MessageHook\n\n\tc2sInsert chan *tlsmirror.TLSRecord\n\ts2cInsert chan *tlsmirror.TLSRecord\n\n\tisClientRandomReady bool\n\tClientRandom        [32]byte\n\tisServerRandomReady bool\n\tServerRandom        [32]byte\n\n\ttls12ExplicitNonce               *bool\n\texplicitNonceDetectionReady      context.Context\n\texplicitNonceDetectionOver       context.CancelFunc\n\tc2sExplicitNonceCounterGenerator crypto.BytesGenerator\n\ts2cExplicitNonceCounterGenerator crypto.BytesGenerator\n}\n\nfunc (c *conn) GetHandshakeRandom() ([]byte, []byte, error) {\n\t// TODO: the value of c.isClientRandomReady, c.isServerRandomReady, c.ClientRandom, c.ServerRandom has incorrect memory consistency assumptions.\n\tif !c.isClientRandomReady || !c.isServerRandomReady {\n\t\treturn nil, nil, newError(\"client random or server random not ready\")\n\t}\n\treturn c.ClientRandom[:], c.ServerRandom[:], nil\n}\n\nfunc (c *conn) Close() error {\n\tc.done()\n\treturn nil\n}\n\nfunc (c *conn) InsertC2SMessage(message *tlsmirror.TLSRecord) error {\n\tduplicatedRecord := mirrorcommon.DuplicateRecord(*message)\n\tc.c2sInsert <- &duplicatedRecord\n\treturn nil\n}\n\nfunc (c *conn) InsertS2CMessage(message *tlsmirror.TLSRecord) error {\n\tduplicatedRecord := mirrorcommon.DuplicateRecord(*message)\n\tc.s2cInsert <- &duplicatedRecord\n\treturn nil\n}\n\ntype bufPeeker struct {\n\tbuffer []byte\n}\n\nfunc (b *bufPeeker) Peek(n int) ([]byte, error) {\n\tif len(b.buffer) < n {\n\t\treturn nil, newError(\"not enough data\")\n\t}\n\treturn b.buffer[:n], nil\n}\n\ntype readerWithInitialData struct {\n\tinitialData []byte\n\tinnerReader io.Reader\n}\n\nfunc (r *readerWithInitialData) initialDataDrained() bool {\n\treturn len(r.initialData) == 0\n}\n\nfunc (r *readerWithInitialData) Read(p []byte) (n int, err error) {\n\tif len(r.initialData) > 0 {\n\t\tn = copy(p, r.initialData)\n\t\tr.initialData = r.initialData[n:]\n\t\treturn n, nil\n\t}\n\treturn r.innerReader.Read(p)\n}\n\nfunc (c *conn) c2sWorker() {\n\tc2sHandshake, handshakeReminder, c2sReminderData, err := c.captureHandshake(c.clientConn, c.serverConn)\n\tif err != nil {\n\t\tc.done()\n\t\treturn\n\t}\n\t_ = c2sHandshake\n\t_ = handshakeReminder\n\t_ = c2sReminderData\n\tserverConnectionWriter := bufio.NewWriter(c.serverConn)\n\t_, err = io.Copy(serverConnectionWriter, bytes.NewReader(handshakeReminder))\n\tif err != nil {\n\t\tc.done()\n\t\tnewError(\"failed to copy handshake reminder\").Base(err).AtWarning().WriteToLog()\n\t\treturn\n\t}\n\n\tclientHello, err := mirrorcommon.UnpackTLSClientHello(c2sHandshake.Fragment)\n\tif err != nil {\n\t\tc.done()\n\t\tnewError(\"failed to unpack client hello\").Base(err).AtWarning().WriteToLog()\n\t\treturn\n\t}\n\tc.ClientRandom = clientHello.ClientRandom\n\tc.isClientRandomReady = true\n\n\tclientSocketReader := &readerWithInitialData{initialData: c2sReminderData, innerReader: c.clientConn}\n\tclientSocket := bufio.NewReaderSize(clientSocketReader, 65536)\n\n\trecordReader := mirrorcommon.NewTLSRecordStreamReader(clientSocket)\n\trecordWriter := mirrorcommon.NewTLSRecordStreamWriter(serverConnectionWriter)\n\tif len(c2sReminderData) == 0 {\n\t\terr := serverConnectionWriter.Flush()\n\t\tif err != nil {\n\t\t\tc.done()\n\t\t\tnewError(\"failed to flush server connection writer\").Base(err).AtWarning().WriteToLog()\n\t\t\treturn\n\t\t}\n\t}\n\tgo func() {\n\t\tfor c.ctx.Err() == nil {\n\t\t\tvar record *tlsmirror.TLSRecord\n\t\t\tselect {\n\t\t\tcase <-c.ctx.Done():\n\t\t\t\treturn\n\t\t\tcase record = <-c.c2sInsert:\n\t\t\t\t// implicit memory consistency synchronization capture read for c.tls12ExplicitNonce\n\t\t\t}\n\n\t\t\t// memory consistency synchronization for value c.tls12ExplicitNonce is required!!!\n\t\t\tif *c.tls12ExplicitNonce {\n\t\t\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_application_data ||\n\t\t\t\t\trecord.RecordType == mirrorcommon.TLSRecord_RecordType_alert {\n\t\t\t\t\tif len(record.Fragment) >= 8 {\n\t\t\t\t\t\tnonce := c.c2sExplicitNonceCounterGenerator()\n\t\t\t\t\t\tcopy(record.Fragment, nonce)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif c.OnC2SMessageTx != nil {\n\t\t\t\tdrop, err := c.OnC2SMessageTx(record)\n\t\t\t\tif err != nil {\n\t\t\t\t\tc.done()\n\t\t\t\t\tnewError(\"failed to process C2S message\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif drop {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\terr := recordWriter.WriteRecord(record, false)\n\t\t\tif err != nil {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"failed to write C2S message\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_alert {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"alert sent, ending copy\").AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\texplicitNonceSessionAndChangeCipherSpecWasLastMessage := false\n\tfor c.ctx.Err() == nil {\n\t\trecord, err := recordReader.ReadNextRecord()\n\t\tif err != nil {\n\t\t\tc.done()\n\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\tnewError(\"failed to read TLS record\").Base(err).AtWarning().WriteToLog()\n\t\t\treturn\n\t\t}\n\n\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_change_cipher_spec {\n\t\t\t// implicit memory consistency synchronization capture read for c.tls12ExplicitNonce\n\t\t\tif c.explicitNonceDetectionReady.Err() == nil {\n\t\t\t\tc.done()\n\t\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\t\tnewError(\"received client to server change cipher spec before server hello\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// memory consistency synchronization for value c.tls12ExplicitNonce is required!!!\n\t\t\tif *c.tls12ExplicitNonce {\n\t\t\t\texplicitNonceSessionAndChangeCipherSpecWasLastMessage = true\n\t\t\t}\n\t\t}\n\n\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_handshake &&\n\t\t\texplicitNonceSessionAndChangeCipherSpecWasLastMessage {\n\t\t\t// verify if the first 8 bytes are 0x00\n\t\t\tif len(record.Fragment) < 8 || !bytes.Equal(record.Fragment[:8],\n\t\t\t\t[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) {\n\t\t\t\tnewError(\"unexpected explicit nonce header at tls 12 finish\").AtWarning().WriteToLog()\n\t\t\t\tc.done()\n\t\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tc.c2sExplicitNonceCounterGenerator = reverseBytesGeneratorByteOrder(crypto.GenerateIncreasingNonce([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}))\n\t\t}\n\n\t\tif c.OnC2SMessage != nil {\n\t\t\tdrop, err := c.OnC2SMessage(record)\n\t\t\tif err != nil {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"failed to process C2S message\").Base(err).AtWarning().WriteToLog()\n\t\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif drop {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tduplicatedRecord := mirrorcommon.DuplicateRecord(*record)\n\t\tc.c2sInsert <- &duplicatedRecord\n\t}\n\tdrainCopy(c.serverConn, nil, c.clientConn)\n}\n\nfunc (c *conn) s2cWorker() {\n\t// TODO: stick packets together, if they arrived so\n\ts2cHandshake, handshakeReminder, s2cReminderData, err := c.captureHandshake(c.serverConn, c.clientConn)\n\tif err != nil {\n\t\tc.done()\n\t\treturn\n\t}\n\t_ = s2cHandshake\n\t_ = handshakeReminder\n\t_ = s2cReminderData\n\n\tclientConnectionWriter := bufio.NewWriter(c.clientConn)\n\n\t_, err = io.Copy(clientConnectionWriter, bytes.NewReader(handshakeReminder))\n\tif err != nil {\n\t\tc.done()\n\t\tnewError(\"failed to copy handshake reminder\").Base(err).AtWarning().WriteToLog()\n\t\treturn\n\t}\n\n\tserverHello, err := mirrorcommon.UnpackTLSServerHello(s2cHandshake.Fragment)\n\tif err != nil {\n\t\tc.done()\n\t\tnewError(\"failed to unpack server hello\").Base(err).AtWarning().WriteToLog()\n\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\treturn\n\t}\n\tc.ServerRandom = serverHello.ServerRandom\n\tc.isServerRandomReady = true\n\n\tisTLS12ExplicitNonce := c.explicitNonceDetection(serverHello.CipherSuite)\n\tc.tls12ExplicitNonce = &isTLS12ExplicitNonce\n\t// implicit memory consistency synchronization release write for c.tls12ExplicitNonce\n\tc.explicitNonceDetectionOver()\n\n\t_, err = c.OnS2CMessage(&s2cHandshake)\n\tif err != nil {\n\t\tnewError(\"failed to process S2C server hello message\").Base(err).AtWarning().WriteToLog()\n\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\tc.done()\n\t\treturn\n\t}\n\n\tserverSocketReader := &readerWithInitialData{initialData: s2cReminderData, innerReader: c.serverConn}\n\tserverSocket := bufio.NewReaderSize(serverSocketReader, 65536)\n\trecordReader := mirrorcommon.NewTLSRecordStreamReader(serverSocket)\n\trecordWriter := mirrorcommon.NewTLSRecordStreamWriter(clientConnectionWriter)\n\n\tif len(s2cReminderData) == 0 {\n\t\terr := clientConnectionWriter.Flush()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to flush client connection writer\").Base(err).AtWarning().WriteToLog()\n\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\tc.done()\n\t\t\treturn\n\t\t}\n\t}\n\tgo func() {\n\t\tfor c.ctx.Err() == nil {\n\t\t\tvar record *tlsmirror.TLSRecord\n\t\t\tselect {\n\t\t\tcase <-c.ctx.Done():\n\t\t\t\treturn\n\t\t\tcase record = <-c.s2cInsert:\n\t\t\t\t// implicit memory consistency synchronization capture read for c.tls12ExplicitNonce\n\t\t\t}\n\t\t\t// memory consistency synchronization for value c.tls12ExplicitNonce is required!!!\n\t\t\tif *c.tls12ExplicitNonce {\n\t\t\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_application_data ||\n\t\t\t\t\trecord.RecordType == mirrorcommon.TLSRecord_RecordType_alert {\n\t\t\t\t\tif len(record.Fragment) >= 8 {\n\t\t\t\t\t\tnonce := c.s2cExplicitNonceCounterGenerator()\n\t\t\t\t\t\tcopy(record.Fragment, nonce)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif c.OnS2CMessageTx != nil {\n\t\t\t\tdrop, err := c.OnS2CMessageTx(record)\n\t\t\t\tif err != nil {\n\t\t\t\t\tc.done()\n\t\t\t\t\tnewError(\"failed to process S2C message\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif drop {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\terr := recordWriter.WriteRecord(record, false)\n\t\t\tif err != nil {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"failed to write S2C message\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_alert {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"alert sent, ending copy\").AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\texplicitNonceSessionAndChangeCipherSpecWasLastMessage := false\n\tfor c.ctx.Err() == nil {\n\t\trecord, err := recordReader.ReadNextRecord()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to read TLS record\").Base(err).AtWarning().WriteToLog()\n\t\t\tc.done()\n\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\treturn\n\t\t}\n\n\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_change_cipher_spec {\n\t\t\tif *c.tls12ExplicitNonce {\n\t\t\t\texplicitNonceSessionAndChangeCipherSpecWasLastMessage = true\n\t\t\t}\n\t\t}\n\n\t\tif record.RecordType == mirrorcommon.TLSRecord_RecordType_handshake &&\n\t\t\texplicitNonceSessionAndChangeCipherSpecWasLastMessage {\n\t\t\t// verify if the first 8 bytes are 0x00\n\t\t\tif len(record.Fragment) < 8 || !bytes.Equal(record.Fragment[:8],\n\t\t\t\t[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) {\n\t\t\t\tnewError(\"unexpected explicit nonce header at tls 12 finish\").AtWarning().WriteToLog()\n\t\t\t\tc.done()\n\t\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tc.s2cExplicitNonceCounterGenerator = reverseBytesGeneratorByteOrder(crypto.GenerateIncreasingNonce([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}))\n\t\t}\n\n\t\tif c.OnS2CMessage != nil {\n\t\t\tdrop, err := c.OnS2CMessage(record)\n\t\t\tif err != nil {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"failed to process S2C message\").Base(err).AtWarning().WriteToLog()\n\t\t\t\tdrainCopy(c.clientConn, nil, c.serverConn)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif drop {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tduplicatedRecord := mirrorcommon.DuplicateRecord(*record)\n\t\tc.s2cInsert <- &duplicatedRecord\n\t}\n\tdrainCopy(c.clientConn, nil, c.serverConn)\n}\n\nfunc drainCopy(dst io.Writer, initData []byte, src io.Reader) {\n\tif initData != nil {\n\t\t_, err := io.Copy(dst, bytes.NewReader(initData))\n\t\tif err != nil {\n\t\t\tnewError(\"failed to drain copy\").Base(err).AtWarning().WriteToLog()\n\t\t}\n\t}\n\t_, err := io.Copy(dst, src)\n\tif err != nil {\n\t\tnewError(\"failed to drain copy\").Base(err).AtWarning().WriteToLog()\n\t}\n}\n\ntype rejectionDecisionMaker struct{}\n\nfunc (r *rejectionDecisionMaker) TestIfReject(record *tlsmirror.TLSRecord, readyFields int) error {\n\tif readyFields >= 1 {\n\t\tif record.RecordType != mirrorcommon.TLSRecord_RecordType_handshake {\n\t\t\treturn newError(\"unexpected record type\").AtWarning()\n\t\t}\n\t}\n\tif readyFields >= 2 {\n\t\tswitch record.LegacyProtocolVersion[0] {\n\t\tcase 0x01:\n\t\tcase 0x02:\n\t\tcase 0x03:\n\t\t\tif record.LegacyProtocolVersion[1] > 0x03 {\n\t\t\t\treturn newError(\"unexpected minor protocol version\").AtWarning()\n\t\t\t}\n\t\tdefault:\n\t\t\treturn newError(\"unexpected major protocol version\").AtWarning()\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (c *conn) captureHandshake(sourceConn, mirrorConn net.Conn) (handshake tlsmirror.TLSRecord, handshakeReminder, rest []byte, reterr error) {\n\tvar readBuffer [65536]byte\n\tvar nextRead int\n\tfor c.ctx.Err() == nil {\n\t\tn, err := sourceConn.Read(readBuffer[nextRead:])\n\t\tif err != nil {\n\t\t\tc.done()\n\t\t\treterr = newError(\"failed to read from source connection\").Base(err).AtWarning()\n\t\t\treturn handshake, nil, nil, reterr\n\t\t}\n\t\thandshakeRejectionDecisionMaker := &rejectionDecisionMaker{}\n\t\tresult, tryAgainLen, processed, err := mirrorcommon.PeekTLSRecord(&bufPeeker{buffer: readBuffer[:nextRead+n]}, handshakeRejectionDecisionMaker)\n\t\tif processed == 0 {\n\t\t\tif tryAgainLen == 0 {\n\t\t\t\t// TODO: directly copy\n\t\t\t\tdrainCopy(mirrorConn, readBuffer[:nextRead+n], sourceConn)\n\t\t\t\tc.done()\n\t\t\t\treterr = newError(\"failed to peek tls record\").Base(err).AtWarning()\n\t\t\t\treturn handshake, nil, nil, reterr\n\t\t\t}\n\t\t\t_, err = io.Copy(mirrorConn, bytes.NewReader(readBuffer[nextRead:nextRead+n]))\n\t\t\tif err != nil {\n\t\t\t\tc.done()\n\t\t\t\tnewError(\"failed to copy to server connection\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn handshake, nil, nil, reterr\n\t\t\t}\n\t\t\tnextRead += n\n\t\t} else {\n\t\t\t// Parse the client hello\n\t\t\tif result.RecordType != mirrorcommon.TLSRecord_RecordType_handshake {\n\t\t\t\tc.done()\n\t\t\t\treterr = newError(\"unexpected record type\").AtWarning()\n\t\t\t\treturn handshake, nil, nil, reterr\n\t\t\t}\n\t\t\thandshake = result\n\t\t\thandshakeReminder = readBuffer[nextRead:processed]\n\t\t\trest = readBuffer[processed : nextRead+n]\n\t\t\treturn handshake, handshakeReminder, rest, nil\n\t\t}\n\t}\n\treterr = newError(\"context is done\")\n\treturn handshake, nil, nil, reterr\n}\n\nfunc (c *conn) GetApplicationDataExplicitNonceReservedOverheadHeaderLength() (int, error) {\n\tif c.tls12ExplicitNonce == nil {\n\t\treturn 0, newError(\"explicit nonce info is not ready\")\n\t}\n\tif *c.tls12ExplicitNonce {\n\t\treturn 8, nil\n\t}\n\treturn 0, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorbase/crypto.go",
    "content": "package mirrorbase\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\nfunc reverseBytesGeneratorByteOrder(generator crypto.BytesGenerator) crypto.BytesGenerator {\n\tvar reverseResult [8]byte\n\treturn func() []byte {\n\t\tresult := generator()\n\t\tif len(result) != 8 {\n\t\t\tpanic(\"reverseBytesGeneratorByteOrder requires a generator that returns exactly 8 bytes\")\n\t\t}\n\t\tfor i := 0; i < 8; i++ {\n\t\t\treverseResult[i] = result[7-i]\n\t\t}\n\t\treturn reverseResult[:]\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorbase/crypto_test.go",
    "content": "package mirrorbase\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\nfunc TestTLS12ExplicitNonceGeneration(t *testing.T) {\n\tgenerator := reverseBytesGeneratorByteOrder(crypto.GenerateIncreasingNonce([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}))\n\n\tfirstValue := generator()\n\tif diff := cmp.Diff(firstValue, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}); diff != \"\" {\n\t\tt.Errorf(\"Unexpected first value: %s\", diff)\n\t}\n\n\tsecondValue := generator()\n\tif diff := cmp.Diff(secondValue, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}); diff != \"\" {\n\t\tt.Errorf(\"Unexpected second value: %s\", diff)\n\t}\n\n\tthirdValue := generator()\n\tif diff := cmp.Diff(thirdValue, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}); diff != \"\" {\n\t\tt.Errorf(\"Unexpected third value: %s\", diff)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorbase/errors.generated.go",
    "content": "package mirrorbase\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcommon/handshake.go",
    "content": "package mirrorcommon\n\nimport (\n\t\"bytes\"\n\n\t\"github.com/v2fly/struc\"\n)\n\ntype TLSClientHello struct {\n\tHandshakeType uint8\n\tLength        [3]byte\n\tVersion       uint16\n\tClientRandom  [32]byte\n\n\t// There are other entries, however we do not need them yet\n}\n\nfunc UnpackTLSClientHello(data []byte) (TLSClientHello, error) {\n\tvar clientHello TLSClientHello\n\terr := struc.Unpack(bytes.NewReader(data), &clientHello)\n\treturn clientHello, err\n}\n\ntype TLSServerHello struct {\n\tHandshakeType   uint8\n\tLength          [3]byte\n\tVersion         uint16\n\tServerRandom    [32]byte\n\tSessionIDLength uint8 `struc:\"sizeof=SessionID\"`\n\tSessionID       []byte\n\tCipherSuite     uint16\n\n\t// There are other entries, however we do not need them yet\n}\n\nfunc UnpackTLSServerHello(data []byte) (TLSServerHello, error) {\n\tvar serverHello TLSServerHello\n\terr := struc.Unpack(bytes.NewReader(data), &serverHello)\n\treturn serverHello, err\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcommon/loopback_protect.go",
    "content": "package mirrorcommon\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc SetLoopbackProtectionFlagForContext(ctx context.Context, enrollmentID []byte) context.Context {\n\tloopbackProtectionKey := tlsmirror.ConnectionLoopbackPrevention{Key: string(enrollmentID)}\n\treturn context.WithValue(ctx, loopbackProtectionKey, true)\n}\n\nfunc SetSecondaryLoopbackProtectionFlagForContext(ctx context.Context, enrollmentID []byte) context.Context {\n\tloopbackProtectionKey := tlsmirror.ConnectionLoopbackPrevention{Key: string(enrollmentID)}\n\treturn context.WithValue(ctx, loopbackProtectionKey, false)\n}\n\nfunc IsLoopbackProtectionEnabled(ctx context.Context, enrollmentID []byte) bool {\n\tloopbackProtectionKey := tlsmirror.ConnectionLoopbackPrevention{Key: string(enrollmentID)}\n\tval := ctx.Value(loopbackProtectionKey)\n\tenabled, ok := val.(bool)\n\treturn ok && enabled\n}\n\nfunc IsSecondaryLoopbackProtectionEnabled(ctx context.Context, enrollmentID []byte) bool {\n\tloopbackProtectionKey := tlsmirror.ConnectionLoopbackPrevention{Key: string(enrollmentID)}\n\tval := ctx.Value(loopbackProtectionKey)\n\tenabled, ok := val.(bool)\n\treturn ok && !enabled\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcommon/record.go",
    "content": "package mirrorcommon\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\n// PeekTLSRecord reads a TLS record from peeker.\n// It returns the record, the number of bytes read from peeker, and any error encountered.\n// It does not consume content from peeker, and the content peeked is borrowed from peeker.\nfunc PeekTLSRecord(peeker tlsmirror.Peeker, rejectionProfile tlsmirror.PartialTLSRecordRejectProfile) (result tlsmirror.TLSRecord, tryAgainLength, processed int, err error) {\n\tvar record tlsmirror.TLSRecord\n\theader, err := peeker.Peek(5)\n\tif err != nil {\n\t\treturn record, 0, 0, err\n\t}\n\tif len(header) < 5 {\n\t\treturn record, 5, 0, fmt.Errorf(\"tls: record header too short\")\n\t}\n\trecord.RecordType = header[0]\n\trecord.LegacyProtocolVersion[0] = header[1]\n\trecord.LegacyProtocolVersion[1] = header[2]\n\trecord.RecordLength = uint16(header[3])<<8 | uint16(header[4])\n\tif record.RecordLength > 16384 {\n\t\treturn record, 0, 0, fmt.Errorf(\"tls: record length %d is too large\", record.RecordLength)\n\t}\n\tif rejectionProfile != nil {\n\t\terr = rejectionProfile.TestIfReject(&record, 2)\n\t\tif err != nil {\n\t\t\treturn record, 0, 0, err\n\t\t}\n\t}\n\tfragment, err := peeker.Peek(int(5 + record.RecordLength))\n\tif err != nil {\n\t\treturn record, int(5 + record.RecordLength), 0, err\n\t}\n\tif len(fragment) < 5+int(record.RecordLength) {\n\t\treturn record, int(5 + record.RecordLength), 0, fmt.Errorf(\"tls: record fragment too short\")\n\t}\n\trecord.Fragment = fragment[5:]\n\treturn record, 0, int(5 + record.RecordLength), nil\n}\n\nfunc PackTLSRecord(record tlsmirror.TLSRecord) []byte {\n\tbuf := make([]byte, 5+len(record.Fragment))\n\tbuf[0] = record.RecordType\n\tbuf[1] = record.LegacyProtocolVersion[0]\n\tbuf[2] = record.LegacyProtocolVersion[1]\n\tbuf[3] = byte(record.RecordLength >> 8)\n\tbuf[4] = byte(record.RecordLength)\n\tcopy(buf[5:], record.Fragment)\n\treturn buf\n}\n\nfunc DuplicateRecord(record tlsmirror.TLSRecord) tlsmirror.TLSRecord {\n\tnewRecord := record\n\tnewRecord.Fragment = make([]byte, len(record.Fragment))\n\tcopy(newRecord.Fragment, record.Fragment)\n\treturn newRecord\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcommon/record_consts.go",
    "content": "package mirrorcommon\n\nconst (\n\tTLSRecord_RecordType_application_data   = 23\n\tTLSRecord_RecordType_handshake          = 22\n\tTLSRecord_RecordType_change_cipher_spec = 20\n\tTLSRecord_RecordType_alert              = 21\n)\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcommon/recordstream.go",
    "content": "package mirrorcommon\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewTLSRecordStreamReader(reader *bufio.Reader) *TLSRecordStreamReader {\n\treturn &TLSRecordStreamReader{bufferedReader: reader}\n}\n\ntype TLSRecordStreamReader struct {\n\tbufferedReader *bufio.Reader\n\tconsumedSize   int64\n}\n\nfunc (t *TLSRecordStreamReader) ReadNextRecord() (*tlsmirror.TLSRecord, error) {\n\trecord, tryAgainLength, processedLength, err := PeekTLSRecord(t.bufferedReader, nil)\n\tif err == nil {\n\t\t_, err := t.bufferedReader.Discard(processedLength)\n\t\tt.consumedSize += int64(processedLength)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &record, nil\n\t}\n\n\tif errors.Is(err, io.EOF) {\n\t\treturn nil, err\n\t} else { // nolint: gocritic\n\t\tif tryAgainLength == 0 {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif tryAgainLength > 0 {\n\t\t_, err := t.bufferedReader.Read(make([]byte, tryAgainLength))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\terr = t.bufferedReader.UnreadByte()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn t.ReadNextRecord()\n}\n\nfunc (t *TLSRecordStreamReader) GetConsumedSize() int64 {\n\treturn t.consumedSize\n}\n\nfunc NewTLSRecordStreamWriter(writer *bufio.Writer) *TLSRecordStreamWriter {\n\treturn &TLSRecordStreamWriter{bufferedWriter: writer}\n}\n\ntype TLSRecordStreamWriter struct {\n\tbufferedWriter *bufio.Writer\n}\n\nfunc (t *TLSRecordStreamWriter) WriteRecord(record *tlsmirror.TLSRecord, holdFlush bool) error {\n\t_, err := t.bufferedWriter.Write(PackTLSRecord(*record))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif holdFlush {\n\t\treturn nil\n\t}\n\treturn t.bufferedWriter.Flush()\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/decryptor.go",
    "content": "package mirrorcrypto\n\nimport (\n\t\"crypto/cipher\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\ntype Decryptor struct {\n\tnonceGenerator crypto.BytesGenerator\n\taead           cipher.AEAD\n\tnextNonce      []byte\n}\n\nfunc NewDecryptor(encryptionKey []byte, nonceMask []byte) *Decryptor {\n\twrappedAead := aeadAESGCMTLS13(encryptionKey, nonceMask)\n\treturn &Decryptor{\n\t\tnonceGenerator: generateInitialAEADNonce(),\n\t\taead:           wrappedAead,\n\t}\n}\n\nfunc (d *Decryptor) Open(dst, src []byte) ([]byte, error) {\n\tif d.nextNonce == nil {\n\t\td.nextNonce = d.nonceGenerator()\n\t}\n\tdst, err := d.aead.Open(dst[:0], d.nextNonce, src, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\td.nextNonce = nil\n\treturn dst, nil\n}\n\nfunc (d *Decryptor) NonceSize() int {\n\treturn d.aead.NonceSize()\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/derive_key.go",
    "content": "package mirrorcrypto\n\nimport (\n\t\"crypto/hkdf\"\n\t\"crypto/sha256\"\n)\n\nfunc DeriveEncryptionKey(primaryKey, clientRandom, serverRandom []byte, tag string) ([]byte, []byte, error) {\n\tif len(primaryKey) != 32 {\n\t\treturn nil, nil, newError(\"invalid primary key size: \", len(primaryKey))\n\t}\n\tif len(clientRandom) != 32 {\n\t\treturn nil, nil, newError(\"invalid client random size: \", len(clientRandom))\n\t}\n\tif len(serverRandom) != 32 {\n\t\treturn nil, nil, newError(\"invalid server random size: \", len(serverRandom))\n\t}\n\n\t// Concatenate the primary key, client random, and server random\n\tcombined := append(primaryKey, clientRandom...) // nolint: gocritic\n\tcombined = append(combined, serverRandom...)\n\n\tencryptionKey, err := hkdf.Expand(sha256.New, combined, \"v2ray-sp76YMKM-EkGrFUNL-rTJRJMkU:tlsmirror-encryption\"+tag, 16)\n\tif err != nil {\n\t\treturn nil, nil, newError(\"unable to derive encryption key\").Base(err)\n\t}\n\n\tnonceMask, err := hkdf.Expand(sha256.New, combined, \"v2ray-sp76YMKM-EkGrFUNL-rTJRJMkU:tlsmirror-noncemask\"+tag, 12)\n\tif err != nil {\n\t\treturn nil, nil, newError(\"unable to derive nonce mask\").Base(err)\n\t}\n\n\treturn encryptionKey, nonceMask, nil\n}\n\nfunc DeriveSecondaryKey(primaryKey []byte, tag string) ([]byte, error) {\n\tif len(primaryKey) != 32 {\n\t\treturn nil, newError(\"invalid primary key size: \", len(primaryKey))\n\t}\n\n\t// Use HKDF to derive a secondary key\n\tsecondaryKey, err := hkdf.Expand(sha256.New, primaryKey, \"v2ray-sv77RCEY-e8AhYsbD-BmFC7XRK:tlsmirror-secondary\"+tag, 16)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to derive secondary key\").Base(err)\n\t}\n\n\treturn secondaryKey, nil\n}\n\nfunc DeriveSequenceWatermarkingKey(primaryKey, clientRandom, serverRandom []byte, tag string) ([]byte, []byte, error) {\n\tif len(primaryKey) != 32 {\n\t\treturn nil, nil, newError(\"invalid primary key size: \", len(primaryKey))\n\t}\n\tif len(clientRandom) != 32 {\n\t\treturn nil, nil, newError(\"invalid client random size: \", len(clientRandom))\n\t}\n\tif len(serverRandom) != 32 {\n\t\treturn nil, nil, newError(\"invalid server random size: \", len(serverRandom))\n\t}\n\n\t// Concatenate the primary key, client random, and server random\n\tcombined := append(primaryKey, clientRandom...) // nolint: gocritic\n\tcombined = append(combined, serverRandom...)\n\n\tencryptionKey, err := hkdf.Expand(sha256.New, combined, \"v2ray-xv64FXUU-GxMn8UYz-bTy6UDeE:tlsmirror-sequence-watermark-encryption\"+tag, 32)\n\tif err != nil {\n\t\treturn nil, nil, newError(\"unable to derive encryption key\").Base(err)\n\t}\n\n\tnonceMask, err := hkdf.Expand(sha256.New, combined, \"v2ray-xv64FXUU-GxMn8UYz-bTy6UDeE:tlsmirror-sequence-watermark-noncemask\"+tag, 24)\n\tif err != nil {\n\t\treturn nil, nil, newError(\"unable to derive nonce mask\").Base(err)\n\t}\n\n\treturn encryptionKey, nonceMask, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/encrypter.go",
    "content": "package mirrorcrypto\n\nimport (\n\t\"crypto/cipher\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/crypto\"\n)\n\ntype Encryptor struct {\n\tnonceGenerator crypto.BytesGenerator\n\taead           cipher.AEAD\n}\n\nfunc NewEncryptor(encryptionKey []byte, nonceMask []byte) *Encryptor {\n\twrappedAead := aeadAESGCMTLS13(encryptionKey, nonceMask)\n\treturn &Encryptor{\n\t\tnonceGenerator: generateInitialAEADNonce(),\n\t\taead:           wrappedAead,\n\t}\n}\n\nfunc (e *Encryptor) Seal(dst, src []byte) ([]byte, error) {\n\tnonce := e.nonceGenerator()\n\tdst = e.aead.Seal(dst, nonce, src, nil)\n\treturn dst, nil\n}\n\nfunc (e *Encryptor) NonceSize() int {\n\treturn e.aead.NonceSize()\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/errors.generated.go",
    "content": "package mirrorcrypto\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/mirrorcrypto.go",
    "content": "package mirrorcrypto\n\nimport \"github.com/v2fly/v2ray-core/v5/common/crypto\"\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nfunc generateInitialAEADNonce() crypto.BytesGenerator {\n\treturn crypto.GenerateIncreasingNonce([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/tls_cipher_suites.go",
    "content": "package mirrorcrypto\n\nimport (\n\t\"crypto/cipher\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n)\n\nconst (\n\taeadNonceLength = 12\n)\n\ntype aead interface {\n\tcipher.AEAD\n\n\t// explicitNonceLen returns the number of bytes of explicit nonce\n\t// included in each record. This is eight for older AEADs and\n\t// zero for modern ones.\n\texplicitNonceLen() int\n}\n\n// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce\n// before each call.\ntype xorNonceAEAD struct {\n\tnonceMask [aeadNonceLength]byte\n\taead      cipher.AEAD\n}\n\nfunc (f *xorNonceAEAD) NonceSize() int        { return 8 } // 64-bit sequence number\nfunc (f *xorNonceAEAD) Overhead() int         { return f.aead.Overhead() }\nfunc (f *xorNonceAEAD) explicitNonceLen() int { return 0 }\n\nfunc (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\tresult := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\n\treturn result\n}\n\nfunc (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\tresult, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\n\treturn result, err\n}\n\nfunc aeadChaCha20Poly1305(key, nonceMask []byte) aead {\n\tif len(nonceMask) != aeadNonceLength {\n\t\tpanic(\"tls: internal error: wrong nonce length\")\n\t}\n\taead, err := chacha20poly1305.New(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tret := &xorNonceAEAD{aead: aead}\n\tcopy(ret.nonceMask[:], nonceMask)\n\treturn ret\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorcrypto/tls_cipher_suites_linkname.go",
    "content": "package mirrorcrypto\n\nimport (\n\t\"crypto/cipher\"\n\t_ \"unsafe\"\n)\n\n// This linkname is necessary to avoid duplicating too many internal packages.\n\n//go:linkname aeadAESGCMTLS13 crypto/tls.aeadAESGCMTLS13\nfunc aeadAESGCMTLS13(key, nonceMask []byte) cipher.AEAD\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/cancelContextOnCloseConn.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"context\"\n\t\"net\"\n)\n\nfunc NewCancelContextOnCloseConn(conn net.Conn, done context.CancelFunc) net.Conn {\n\treturn &cancelContextOnCloseConn{\n\t\tConn: conn,\n\t\tdone: done,\n\t}\n}\n\ntype cancelContextOnCloseConn struct {\n\tnet.Conn\n\tdone context.CancelFunc\n}\n\nfunc (c *cancelContextOnCloseConn) Close() error {\n\tc.done()\n\treturn c.Conn.Close()\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/clicommand/enrollmentlink_cli.go",
    "content": "package clicommand\n\nimport (\n\t\"flag\"\n\t\"io\"\n\t\"os\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/all/engineering\"\n\t\"github.com/v2fly/v2ray-core/v5/main/commands/base\"\n\tmirrorenrollment \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\"\n)\n\nvar (\n\tinputPath  *string\n\toutputPath *string\n\tmode       *string\n)\n\n// machine generated\nvar cmdEnrollmentLink = &base.Command{\n\tUsageLine: \"{{.Exec}} engineering tlsmirror-enrollment-link\",\n\tFlag: func() flag.FlagSet {\n\t\tfs := flag.NewFlagSet(\"tlsmirror-enrollment-link\", flag.ExitOnError)\n\t\tinputPath = fs.String(\"c\", \"\", \"input file path (optional, defaults to stdin)\")\n\t\toutputPath = fs.String(\"o\", \"\", \"output file path (default stdout)\")\n\t\tmode = fs.String(\"mode\", \"link\", \"conversion mode: 'link' to convert JSON -> link, 'json' to convert link -> JSON\")\n\t\treturn *fs\n\t}(),\n\tRun: func(cmd *base.Command, args []string) {\n\t\tif err := cmd.Flag.Parse(args); err != nil {\n\t\t\tbase.Fatalf(\"failed to parse flags: %v\", err)\n\t\t}\n\n\t\tvar content []byte\n\t\tvar err error\n\t\tif *inputPath == \"\" {\n\t\t\t// Read from stdin when -c is omitted.\n\t\t\tcontent, err = io.ReadAll(os.Stdin)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"failed to read from stdin: %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\tfd, err := os.Open(*inputPath)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"failed to open input file %q: %v\", *inputPath, err)\n\t\t\t}\n\t\t\tdefer fd.Close()\n\n\t\t\tcontent, err = io.ReadAll(fd)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"failed to read input file %q: %v\", *inputPath, err)\n\t\t\t}\n\t\t}\n\n\t\tvar outBytes []byte\n\t\tswitch *mode {\n\t\tcase \"link\":\n\t\t\t// Expect protobuf JSON for google.protobuf.Any, convert to a data URL link.\n\t\t\tvar any anypb.Any\n\t\t\tif err := protojson.Unmarshal(content, &any); err != nil {\n\t\t\t\tbase.Fatalf(\"failed to unmarshal JSON into google.protobuf.Any: %v\", err)\n\t\t\t}\n\t\t\tlink, err := mirrorenrollment.LinkFromAny(&any)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"failed to create link from Any: %v\", err)\n\t\t\t}\n\t\t\toutBytes = []byte(link)\n\n\t\tcase \"json\":\n\t\t\t// Expect link (data URL or other supported forms), convert to protobuf JSON.\n\t\t\tlink := string(content)\n\t\t\tany, err := mirrorenrollment.AnyFromLink(link)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"failed to parse link into Any: %v\", err)\n\t\t\t}\n\t\t\tb, err := protojson.Marshal(any)\n\t\t\tif err != nil {\n\t\t\t\tbase.Fatalf(\"failed to marshal Any to JSON: %v\", err)\n\t\t\t}\n\t\t\toutBytes = b\n\n\t\tdefault:\n\t\t\tbase.Fatalf(\"unknown mode: %s\", *mode)\n\t\t}\n\n\t\tif *outputPath == \"\" {\n\t\t\tif _, err := os.Stdout.Write(outBytes); err != nil {\n\t\t\t\tbase.Fatalf(\"failed to write output to stdout: %v\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif err := os.WriteFile(*outputPath, outBytes, 0o644); err != nil {\n\t\t\tbase.Fatalf(\"failed to write output file %q: %v\", *outputPath, err)\n\t\t}\n\t},\n}\n\nfunc init() {\n\tengineering.AddCommand(cmdEnrollmentLink)\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/client.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation\"\n)\n\nfunc NewEnrollmentConfirmationClient(\n\tctx context.Context,\n\tconfig *Config,\n\tserverIdentity []byte,\n) (*EnrollmentConfirmationClient, error) {\n\tif ctx == nil {\n\t\treturn nil, newError(\"context cannot be nil\")\n\t}\n\n\tif config == nil {\n\t\treturn nil, newError(\"config cannot be nil\")\n\t}\n\n\tfor _, handler := range config.BootstrapEgressUrl {\n\t\tif handler == \"\" {\n\t\t\treturn nil, newError(\"bootstrap ingress URL cannot be empty\")\n\t\t}\n\t\tanyPb, err := AnyFromLink(handler)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid bootstrap ingress URL\").Base(err).AtError()\n\t\t}\n\t\tif anyPb == nil {\n\t\t\treturn nil, newError(\"bootstrap ingress URL did not produce valid Any\")\n\t\t}\n\t\tconfig.BootstrapEgressConfig = append(config.BootstrapEgressConfig, anyPb)\n\t}\n\n\tecc := &EnrollmentConfirmationClient{\n\t\tctx:            ctx,\n\t\tconfig:         config,\n\t\tserverIdentity: serverIdentity,\n\t}\n\n\tif err := ecc.init(); err != nil {\n\t\treturn nil, newError(\"failed to initialize enrollment confirmation client\").Base(err).AtError()\n\t}\n\n\treturn ecc, nil\n}\n\ntype EnrollmentConfirmationClient struct {\n\tctx context.Context\n\n\tconfig *Config\n\n\tserverIdentity []byte\n\n\tprimaryEnrollmentConfirmationClient    tlsmirror.ConnectionEnrollmentConfirmation\n\tbootstrapEnrollmentConfirmationClients []tlsmirror.ConnectionEnrollmentConfirmation\n}\n\nfunc (c *EnrollmentConfirmationClient) VerifyConnectionEnrollment(req *tlsmirror.EnrollmentConfirmationReq) (*tlsmirror.EnrollmentConfirmationResp, error) {\n\tresp, err := c.primaryEnrollmentConfirmationClient.VerifyConnectionEnrollment(req)\n\tif err == nil {\n\t\tif resp.Enrolled {\n\t\t\tnewError(\"enrollment confirmation verification with primary enrollment successful\").Base(err).WriteToLog()\n\t\t} else {\n\t\t\tnewError(\"enrollment confirmation verification with primary enrollment over, not enrolled\").Base(err).WriteToLog()\n\t\t}\n\t\treturn resp, nil\n\t}\n\tnewError(\"enrollment confirmation verification with primary enrollment failed\").Base(err).WriteToLog()\n\tfor _, bootstrapClient := range c.bootstrapEnrollmentConfirmationClients {\n\t\tresp, err := bootstrapClient.VerifyConnectionEnrollment(req)\n\t\tif err == nil {\n\t\t\tif resp.Enrolled {\n\t\t\t\tnewError(\"enrollment confirmation verification with bootstrap enrollment successful\").Base(err).WriteToLog()\n\t\t\t} else {\n\t\t\t\tnewError(\"enrollment confirmation verification with bootstrap enrollment over, not enrolled\").Base(err).WriteToLog()\n\t\t\t}\n\n\t\t\treturn resp, nil\n\t\t}\n\t\tnewError(\"enrollment confirmation verification with bootstrap enrollment failed\").Base(err).WriteToLog()\n\t}\n\treturn nil, newError(\"all enrollment confirmation clients failed\").Base(err).AtError()\n}\n\nfunc (c *EnrollmentConfirmationClient) init() error {\n\trtt, _, err := httpenrollmentconfirmation.NewClientRoundTripperForEnrollmentConfirmation(\n\t\tfunc(network, addr string) (net.Conn, error) {\n\t\t\ttransportEnvironment := envctx.EnvironmentFromContext(c.ctx).(environment.TransportEnvironment)\n\t\t\tdialer := transportEnvironment.OutboundDialer()\n\t\t\tif dialer == nil {\n\t\t\t\treturn nil, newError(\"no outbound dialer available in transport environment\")\n\t\t\t}\n\t\t\tdest, err := v2net.ParseDestination(addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"failed to parse destination address\").Base(err).AtError()\n\t\t\t}\n\t\t\tdest.Network = v2net.Network_TCP\n\n\t\t\tloopbackProtectedCtx := mirrorcommon.SetLoopbackProtectionFlagForContext(c.ctx, c.serverIdentity)\n\t\t\tprimaryConfirmationOutbound := c.config.PrimaryEgressOutbound\n\t\t\tif primaryConfirmationOutbound == \"\" {\n\t\t\t\tprimaryConfirmationOutbound = transportEnvironment.SelfProxyTag()\n\t\t\t\tloopbackProtectedCtx = mirrorcommon.SetSecondaryLoopbackProtectionFlagForContext(c.ctx, c.serverIdentity)\n\t\t\t}\n\t\t\tconnContext, done := context.WithCancel(loopbackProtectedCtx)\n\t\t\tconn, err := dialer(connContext, dest, primaryConfirmationOutbound)\n\t\t\tif err != nil {\n\t\t\t\tdone()\n\t\t\t\treturn nil, newError(\"failed to dial to destination\").Base(err).AtError()\n\t\t\t}\n\t\t\tcontextLinkedConn := NewCancelContextOnCloseConn(conn, done)\n\t\t\treturn contextLinkedConn, nil\n\t\t}, c.serverIdentity)\n\tif err != nil {\n\t\treturn newError(\"failed to create HTTP round tripper for enrollment confirmation\").Base(err).AtError()\n\t}\n\tc.primaryEnrollmentConfirmationClient, err = httpenrollmentconfirmation.NewHTTPEnrollmentConfirmationClientFromHTTPRoundTripper(rtt)\n\tif err != nil {\n\t\treturn newError(\"failed to create HTTP enrollment confirmation client\").Base(err).AtError()\n\t}\n\n\tfor _, bootstrapEnrollmentConfirmationConfig := range c.config.BootstrapEgressConfig {\n\t\tenrollment, err := serial.GetInstanceOf(bootstrapEnrollmentConfirmationConfig)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get instance of bootstrap enrollment confirmation config\").Base(err).AtError()\n\t\t}\n\n\t\tloopbackProtectedCtx := mirrorcommon.SetLoopbackProtectionFlagForContext(c.ctx, c.serverIdentity)\n\t\tenrollmentInst, err := common.CreateObject(loopbackProtectedCtx, enrollment)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create bootstrap enrollment confirmation config\").Base(err).AtError()\n\t\t}\n\n\t\tenrollmentConfirmation, ok := enrollmentInst.(tlsmirror.ConnectionEnrollmentConfirmation)\n\t\tif !ok {\n\t\t\treturn newError(\"bootstrap enrollment confirmation config is not a valid ConnectionEnrollmentConfirmation\")\n\t\t}\n\n\t\tif configReceiver, ok := enrollmentConfirmation.(tlsmirror.ConnectionEnrollmentConfirmationClientInstanceConfigReceiver); ok {\n\t\t\tconfigReceiver.OnConnectionEnrollmentConfirmationClientInstanceConfigReady(tlsmirror.ConnectionEnrollmentConfirmationClientInstanceConfig{\n\t\t\t\tDefaultOutboundTag: c.config.BootstrapEgressOutbound,\n\t\t\t})\n\t\t}\n\t\tc.bootstrapEnrollmentConfirmationClients = append(c.bootstrapEnrollmentConfirmationClients, enrollmentConfirmation)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/config.pb.go",
    "content": "package mirrorenrollment\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// This will be handled by the TLS Mirror server, the enrollment part only accepts existing connections.\n\tPrimaryIngressOutbound  string       `protobuf:\"bytes,1,opt,name=primary_ingress_outbound,json=primaryIngressOutbound,proto3\" json:\"primary_ingress_outbound,omitempty\"`\n\tPrimaryEgressOutbound   string       `protobuf:\"bytes,2,opt,name=primary_egress_outbound,json=primaryEgressOutbound,proto3\" json:\"primary_egress_outbound,omitempty\"`\n\tBootstrapIngressUrl     []string     `protobuf:\"bytes,3,rep,name=bootstrap_ingress_url,json=bootstrapIngressUrl,proto3\" json:\"bootstrap_ingress_url,omitempty\"`\n\tBootstrapEgressUrl      []string     `protobuf:\"bytes,4,rep,name=bootstrap_egress_url,json=bootstrapEgressUrl,proto3\" json:\"bootstrap_egress_url,omitempty\"`\n\tBootstrapIngressConfig  []*anypb.Any `protobuf:\"bytes,5,rep,name=bootstrap_ingress_config,json=bootstrapIngressConfig,proto3\" json:\"bootstrap_ingress_config,omitempty\"`\n\tBootstrapEgressConfig   []*anypb.Any `protobuf:\"bytes,6,rep,name=bootstrap_egress_config,json=bootstrapEgressConfig,proto3\" json:\"bootstrap_egress_config,omitempty\"`\n\tBootstrapEgressOutbound string       `protobuf:\"bytes,7,opt,name=bootstrap_egress_outbound,json=bootstrapEgressOutbound,proto3\" json:\"bootstrap_egress_outbound,omitempty\"`\n\tunknownFields           protoimpl.UnknownFields\n\tsizeCache               protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Config) GetPrimaryIngressOutbound() string {\n\tif x != nil {\n\t\treturn x.PrimaryIngressOutbound\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetPrimaryEgressOutbound() string {\n\tif x != nil {\n\t\treturn x.PrimaryEgressOutbound\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetBootstrapIngressUrl() []string {\n\tif x != nil {\n\t\treturn x.BootstrapIngressUrl\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetBootstrapEgressUrl() []string {\n\tif x != nil {\n\t\treturn x.BootstrapEgressUrl\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetBootstrapIngressConfig() []*anypb.Any {\n\tif x != nil {\n\t\treturn x.BootstrapIngressConfig\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetBootstrapEgressConfig() []*anypb.Any {\n\tif x != nil {\n\t\treturn x.BootstrapEgressConfig\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetBootstrapEgressOutbound() string {\n\tif x != nil {\n\t\treturn x.BootstrapEgressOutbound\n\t}\n\treturn \"\"\n}\n\nvar File_transport_internet_tlsmirror_mirrorenrollment_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\":transport/internet/tlsmirror/mirrorenrollment/config.proto\\x128v2ray.core.transport.internet.tlsmirror.mirrorenrollment\\x1a common/protoext/extensions.proto\\x1a\\x19google/protobuf/any.proto\\\"\\xba\\x03\\n\" +\n\t\"\\x06Config\\x128\\n\" +\n\t\"\\x18primary_ingress_outbound\\x18\\x01 \\x01(\\tR\\x16primaryIngressOutbound\\x126\\n\" +\n\t\"\\x17primary_egress_outbound\\x18\\x02 \\x01(\\tR\\x15primaryEgressOutbound\\x122\\n\" +\n\t\"\\x15bootstrap_ingress_url\\x18\\x03 \\x03(\\tR\\x13bootstrapIngressUrl\\x120\\n\" +\n\t\"\\x14bootstrap_egress_url\\x18\\x04 \\x03(\\tR\\x12bootstrapEgressUrl\\x12N\\n\" +\n\t\"\\x18bootstrap_ingress_config\\x18\\x05 \\x03(\\v2\\x14.google.protobuf.AnyR\\x16bootstrapIngressConfig\\x12L\\n\" +\n\t\"\\x17bootstrap_egress_config\\x18\\x06 \\x03(\\v2\\x14.google.protobuf.AnyR\\x15bootstrapEgressConfig\\x12:\\n\" +\n\t\"\\x19bootstrap_egress_outbound\\x18\\a \\x01(\\tR\\x17bootstrapEgressOutboundB\\xc9\\x01\\n\" +\n\t\"<com.v2ray.core.transport.internet.tlsmirror.mirrorenrollmentP\\x01ZLgithub.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\\xaa\\x028V2Ray.Core.Transport.Internet.Tlsmirror.MirrorEnrollmentb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDesc), len(file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDescData\n}\n\nvar file_transport_internet_tlsmirror_mirrorenrollment_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_tlsmirror_mirrorenrollment_config_proto_goTypes = []any{\n\t(*Config)(nil),    // 0: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.Config\n\t(*anypb.Any)(nil), // 1: google.protobuf.Any\n}\nvar file_transport_internet_tlsmirror_mirrorenrollment_config_proto_depIdxs = []int32{\n\t1, // 0: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.Config.bootstrap_ingress_config:type_name -> google.protobuf.Any\n\t1, // 1: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.Config.bootstrap_egress_config:type_name -> google.protobuf.Any\n\t2, // [2:2] is the sub-list for method output_type\n\t2, // [2:2] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_tlsmirror_mirrorenrollment_config_proto_init() }\nfunc file_transport_internet_tlsmirror_mirrorenrollment_config_proto_init() {\n\tif File_transport_internet_tlsmirror_mirrorenrollment_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDesc), len(file_transport_internet_tlsmirror_mirrorenrollment_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tlsmirror_mirrorenrollment_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tlsmirror_mirrorenrollment_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_tlsmirror_mirrorenrollment_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tlsmirror_mirrorenrollment_config_proto = out.File\n\tfile_transport_internet_tlsmirror_mirrorenrollment_config_proto_goTypes = nil\n\tfile_transport_internet_tlsmirror_mirrorenrollment_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tlsmirror.mirrorenrollment;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tlsmirror.MirrorEnrollment\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\";\noption java_package = \"com.v2ray.core.transport.internet.tlsmirror.mirrorenrollment\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"google/protobuf/any.proto\";\n\nmessage Config {\n  // This will be handled by the TLS Mirror server, the enrollment part only accepts existing connections.\n  string primary_ingress_outbound = 1;\n\n  string primary_egress_outbound = 2;\n  repeated string bootstrap_ingress_url = 3;\n  repeated string bootstrap_egress_url = 4;\n  repeated google.protobuf.Any bootstrap_ingress_config = 5;\n  repeated google.protobuf.Any bootstrap_egress_config = 6;\n  string bootstrap_egress_outbound = 7;\n}"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/enrollment.go",
    "content": "package mirrorenrollment\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/enrollmentlink.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/proto\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n)\n\nconst (\n\t// MIME type used for enrollment data URLs.\n\tenrollmentDataMIME = \"application/vnd.v2ray.tlsmirror-enrollment\"\n)\n\n// LinkFromAny converts a protobuf Any into a data URL string.\n// The produced link has form:\n// data:application/vnd.v2ray.tlsmirror-enrollment;base64,<base64(payload)>\n// where payload is the marshaled Any message encoded with standard base64 (with padding).\nfunc LinkFromAny(a *anypb.Any) (string, error) {\n\t// Machine generated code\n\tif a == nil {\n\t\treturn \"\", newError(\"nil Any\")\n\t}\n\tb, err := proto.Marshal(a)\n\tif err != nil {\n\t\treturn \"\", newError(\"failed to marshal Any\").Base(err)\n\t}\n\tenc := base64.StdEncoding.EncodeToString(b)\n\tdataURL := \"data:\" + enrollmentDataMIME + \";base64,\" + enc\n\treturn dataURL, nil\n}\n\n// AnyFromLink converts a string link (now primarily a data URL) back to *anypb.Any.\n// Accepted formats (strict): only data URLs matching the exact MIME type and base64 encoding.\nfunc AnyFromLink(link string) (*anypb.Any, error) {\n\t// Machine generated code\n\tif link == \"\" {\n\t\treturn nil, newError(\"empty link\")\n\t}\n\n\t// Must be a data URL.\n\tif !strings.HasPrefix(link, \"data:\") {\n\t\treturn nil, newError(\"input must be a data URL\")\n\t}\n\n\t// Parse and split header and payload at the first comma.\n\tcomma := strings.Index(link, \",\")\n\tif comma == -1 || comma+1 >= len(link) {\n\t\treturn nil, newError(\"invalid data URL: missing payload\")\n\t}\n\n\tmeta := link[len(\"data:\"):comma]\n\tpayload := link[comma+1:]\n\n\t// Meta should be like \"<mime-type>;base64\" possibly with additional params.\n\tmetaParts := strings.Split(meta, \";\")\n\tif len(metaParts) < 2 {\n\t\treturn nil, newError(\"invalid data URL metadata\")\n\t}\n\n\t// First part must match our expected MIME.\n\tif metaParts[0] != enrollmentDataMIME {\n\t\treturn nil, newError(\"unexpected MIME type in data URL: \" + metaParts[0])\n\t}\n\n\t// Ensure \"base64\" is present in parameters.\n\tisBase64 := false\n\tfor _, p := range metaParts[1:] {\n\t\tif p == \"base64\" {\n\t\t\tisBase64 = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !isBase64 {\n\t\treturn nil, newError(\"data URL must be base64 encoded\")\n\t}\n\n\t// No URL parsing/decoding of payload: payload is raw base64.\n\traw, err := base64.StdEncoding.DecodeString(payload)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to base64-decode data URL payload\").Base(err)\n\t}\n\n\tvar any anypb.Any\n\tif err := proto.Unmarshal(raw, &any); err != nil {\n\t\treturn nil, newError(\"failed to unmarshal Any from decoded payload\").Base(err)\n\t}\n\treturn &any, nil\n}\n\n// helper to format an error when newError is not available at call site\nfunc fmtErr(format string, a ...interface{}) error {\n\treturn fmt.Errorf(format, a...)\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/enrollmentlink_test.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/proto\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n)\n\nfunc TestLinkRoundTrip(t *testing.T) {\n\torig := &anypb.Any{\n\t\tTypeUrl: \"type.test/example\",\n\t\tValue:   []byte(\"sample-payload-bytes\"),\n\t}\n\n\tlink, err := LinkFromAny(orig)\n\tif err != nil {\n\t\tt.Fatalf(\"LinkFromAny failed: %v\", err)\n\t}\n\tif !strings.HasPrefix(link, \"data:\") {\n\t\tt.Fatalf(\"expected data URL prefix, got: %s\", link)\n\t}\n\n\tdecoded, err := AnyFromLink(link)\n\tif err != nil {\n\t\tt.Fatalf(\"AnyFromLink failed: %v\", err)\n\t}\n\tif !proto.Equal(decoded, orig) {\n\t\tt.Fatalf(\"decoded Any does not match original.\\nOriginal: %#v\\nDecoded: %#v\", orig, decoded)\n\t}\n}\n\nfunc TestLinkFromAnyProducesValidDataURL(t *testing.T) {\n\torig := &anypb.Any{TypeUrl: \"type.test/inspect\", Value: []byte(\"inspect-bytes\")}\n\tlink, err := LinkFromAny(orig)\n\tif err != nil {\n\t\tt.Fatalf(\"LinkFromAny failed: %v\", err)\n\t}\n\tif !strings.HasPrefix(link, \"data:\") {\n\t\tt.Fatalf(\"expected data URL prefix, got: %s\", link)\n\t}\n\tcomma := strings.Index(link, \",\")\n\tif comma == -1 {\n\t\tt.Fatalf(\"no comma in data URL: %s\", link)\n\t}\n\tmeta := link[len(\"data:\"):comma]\n\tpayload := link[comma+1:]\n\tif !strings.HasPrefix(meta, enrollmentDataMIME) {\n\t\tt.Fatalf(\"unexpected MIME in meta: %s\", meta)\n\t}\n\tif !strings.Contains(meta, \"base64\") {\n\t\tt.Fatalf(\"expected base64 param in meta: %s\", meta)\n\t}\n\n\traw, err := base64.StdEncoding.DecodeString(payload)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to decode payload with std encoding: %v\", err)\n\t}\n\tvar any anypb.Any\n\tif err := proto.Unmarshal(raw, &any); err != nil {\n\t\tt.Fatalf(\"unmarshal payload failed: %v\", err)\n\t}\n\tif !proto.Equal(&any, orig) {\n\t\tt.Fatalf(\"unmarshaled Any does not equal original\\nwant=%v\\ngot=%v\", orig, &any)\n\t}\n}\n\nfunc TestLegacyTLSMirrorScheme(t *testing.T) {\n\torig := &anypb.Any{\n\t\tTypeUrl: \"type.test/legacy\",\n\t\tValue:   []byte(\"legacy-bytes\"),\n\t}\n\tmarshaled, err := proto.Marshal(orig)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to marshal orig Any: %v\", err)\n\t}\n\tenc := base64.RawURLEncoding.EncodeToString(marshaled)\n\tlegacyLink := \"tlsmirror-enrollment:\" + enc\n\n\tif _, err := AnyFromLink(legacyLink); err == nil {\n\t\tt.Fatalf(\"expected AnyFromLink to reject legacy link format, but it succeeded\")\n\t}\n}\n\nfunc TestPlainBase64Input(t *testing.T) {\n\torig := &anypb.Any{\n\t\tTypeUrl: \"type.test/plain\",\n\t\tValue:   []byte(\"plain-bytes\"),\n\t}\n\tmarshaled, err := proto.Marshal(orig)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to marshal orig Any: %v\", err)\n\t}\n\tenc := base64.StdEncoding.EncodeToString(marshaled)\n\t// Pass plain base64 (no scheme) - should be rejected in strict mode\n\tif _, err := AnyFromLink(enc); err == nil {\n\t\tt.Fatalf(\"expected AnyFromLink to reject plain base64 input, but it succeeded\")\n\t}\n}\n\nfunc TestInvalidInput(t *testing.T) {\n\tif _, err := AnyFromLink(\"not-a-valid-base64@@\"); err == nil {\n\t\tt.Fatalf(\"expected error for invalid input, got nil\")\n\t}\n\n\tif _, err := LinkFromAny(nil); err == nil {\n\t\tt.Fatalf(\"expected error for LinkFromAny(nil), got nil\")\n\t}\n}\n\nfunc TestRejectWrongMIME(t *testing.T) {\n\torig := &anypb.Any{TypeUrl: \"type.test/wrongmime\", Value: []byte(\"x\")}\n\tb, _ := proto.Marshal(orig)\n\tenc := base64.StdEncoding.EncodeToString(b)\n\tlink := fmt.Sprintf(\"data:application/octet-stream;base64,%s\", enc)\n\tif _, err := AnyFromLink(link); err == nil {\n\t\tt.Fatalf(\"expected rejection for wrong MIME type, but got success\")\n\t}\n}\n\nfunc TestRejectMissingBase64Param(t *testing.T) {\n\torig := &anypb.Any{TypeUrl: \"type.test/nobase64\", Value: []byte(\"x\")}\n\tb, _ := proto.Marshal(orig)\n\tenc := base64.StdEncoding.EncodeToString(b)\n\tlink := fmt.Sprintf(\"data:%s,%s\", enrollmentDataMIME, enc) // no ;base64\n\tif _, err := AnyFromLink(link); err == nil {\n\t\tt.Fatalf(\"expected rejection for missing base64 param, but got success\")\n\t}\n}\n\nfunc TestAcceptExtraParams(t *testing.T) {\n\torig := &anypb.Any{TypeUrl: \"type.test/params\", Value: []byte(\"p\")}\n\tb, _ := proto.Marshal(orig)\n\tenc := base64.StdEncoding.EncodeToString(b)\n\tlink := fmt.Sprintf(\"data:%s;v=1;base64;foo=bar,%s\", enrollmentDataMIME, enc)\n\tany, err := AnyFromLink(link)\n\tif err != nil {\n\t\tt.Fatalf(\"expected success for extra params, got error: %v\", err)\n\t}\n\tif !proto.Equal(any, orig) {\n\t\tt.Fatalf(\"decoded Any mismatch; want %v got %v\", orig, any)\n\t}\n}\n\nfunc TestRejectNonBase64Payload(t *testing.T) {\n\tlink := \"data:\" + enrollmentDataMIME + \";base64,not-base64-@@@\"\n\tif _, err := AnyFromLink(link); err == nil {\n\t\tt.Fatalf(\"expected error for non-base64 payload, got nil\")\n\t}\n}\n\nfunc TestRejectURLEncodedPayload(t *testing.T) {\n\t// percent-encoded payload\n\torig := &anypb.Any{TypeUrl: \"type.test/urlenc\", Value: []byte(\"url-bytes\")}\n\tb, _ := proto.Marshal(orig)\n\tenc := base64.StdEncoding.EncodeToString(b)\n\t// percent-encode first few chars\n\tpct := \"%\" + enc[:2] + enc[2:]\n\tlink := fmt.Sprintf(\"data:%s;base64,%s\", enrollmentDataMIME, pct)\n\tif _, err := AnyFromLink(link); err == nil {\n\t\tt.Fatalf(\"expected rejection for percent-encoded payload, got success\")\n\t}\n}\n\nfunc TestCaseSensitiveMIME(t *testing.T) {\n\torig := &anypb.Any{TypeUrl: \"type.test/case\", Value: []byte(\"c\")}\n\tb, _ := proto.Marshal(orig)\n\tenc := base64.StdEncoding.EncodeToString(b)\n\tlink := fmt.Sprintf(\"data:%s;base64,%s\", strings.ToUpper(enrollmentDataMIME), enc)\n\tif _, err := AnyFromLink(link); err == nil {\n\t\tt.Fatalf(\"expected rejection for case mismatch MIME, got success\")\n\t}\n}\n\nfunc TestLargePayloadRoundTrip(t *testing.T) {\n\t// create a ~100KB payload\n\tsize := 100 * 1024\n\tp := make([]byte, size)\n\tif _, err := rand.Read(p); err != nil {\n\t\tt.Fatalf(\"failed to generate random payload: %v\", err)\n\t}\n\torig := &anypb.Any{TypeUrl: \"type.test/large\", Value: p}\n\tlink, err := LinkFromAny(orig)\n\tif err != nil {\n\t\tt.Fatalf(\"LinkFromAny failed: %v\", err)\n\t}\n\tany, err := AnyFromLink(link)\n\tif err != nil {\n\t\tt.Fatalf(\"AnyFromLink failed for large payload: %v\", err)\n\t}\n\tif !proto.Equal(any, orig) {\n\t\tt.Fatalf(\"large payload mismatch after roundtrip\")\n\t}\n}\n\nfunc TestRejectRawURLEncodingInDataURL(t *testing.T) {\n\torig := &anypb.Any{TypeUrl: \"type.test/rawurl\", Value: []byte(\"raw\")}\n\tb, _ := proto.Marshal(orig)\n\tenc := base64.RawURLEncoding.EncodeToString(b)\n\tlink := fmt.Sprintf(\"data:%s;base64,%s\", enrollmentDataMIME, enc)\n\tif _, err := AnyFromLink(link); err == nil {\n\t\tt.Fatalf(\"expected rejection for raw URL base64 payload, got success\")\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/errors.generated.go",
    "content": "package mirrorenrollment\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation/client.go",
    "content": "package httpenrollmentconfirmation\n\nimport (\n\t\"bytes\"\n\t\"encoding/base32\"\n\t\"io\"\n\t\"net/http\"\n\n\tprotov2 \"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewHTTPEnrollmentConfirmationClientFromHTTPRoundTripper(tripper http.RoundTripper) (tlsmirror.ConnectionEnrollmentConfirmation, error) {\n\tif tripper == nil {\n\t\treturn nil, newError(\"nil tripper\")\n\t}\n\treturn &client{\n\t\thttpRoundTripper: tripper,\n\t}, nil\n}\n\ntype client struct {\n\thttpRoundTripper http.RoundTripper\n}\n\nfunc (c *client) VerifyConnectionEnrollment(req *tlsmirror.EnrollmentConfirmationReq) (*tlsmirror.EnrollmentConfirmationResp, error) {\n\trequestMessage, err := protov2.Marshal(req)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to marshal enrollment confirmation request\").Base(err)\n\t}\n\n\tserverID := base32.NewEncoding(\"0123456789abcdefghijklmnopqrstuv\").WithPadding(base32.NoPadding).EncodeToString(req.ServerIdentifier)\n\n\thttpReq, err := http.NewRequest(\"POST\", \"http://\"+serverID+tlsmirror.EnrollmentVerificationControlConnectionPostfix, bytes.NewReader(requestMessage))\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create HTTP request\").Base(err)\n\t}\n\thttpResp, err := c.httpRoundTripper.RoundTrip(httpReq)\n\tdefer func() {\n\t\tif httpResp != nil && httpResp.Body != nil {\n\t\t\thttpResp.Body.Close()\n\t\t}\n\t}()\n\tif err != nil {\n\t\treturn nil, newError(\"failed to send HTTP request\").Base(err)\n\t}\n\tif httpResp.StatusCode != http.StatusOK {\n\t\treturn nil, newError(\"unexpected HTTP response status: \", httpResp.StatusCode)\n\t}\n\tresponseMessage, err := io.ReadAll(httpResp.Body)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to read HTTP response body\").Base(err)\n\t}\n\tresp := &tlsmirror.EnrollmentConfirmationResp{}\n\tif err := protov2.Unmarshal(responseMessage, resp); err != nil {\n\t\treturn nil, newError(\"failed to unmarshal enrollment confirmation response\").Base(err)\n\t}\n\treturn resp, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation/clientbuilder.go",
    "content": "package httpenrollmentconfirmation\n\nimport (\n\t\"context\"\n\t\"encoding/base32\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/httponconnection\"\n)\n\nfunc NewClientRoundTripperForEnrollmentConfirmation(\n\tdial func(network, addr string) (net.Conn, error),\n\tserverIdentity []byte,\n) (http.RoundTripper, RoundTripperMetadata, error) {\n\tif dial == nil {\n\t\treturn nil, nil, newError(\"nil dial function\")\n\t}\n\tif len(serverIdentity) == 0 {\n\t\treturn nil, nil, newError(\"nil or empty server identity\")\n\t}\n\tcr := &clientRoundtripper{\n\t\tdial:           dial,\n\t\tserverIdentity: serverIdentity,\n\t}\n\treturn cr, cr, nil\n}\n\ntype RoundTripperMetadata interface {\n\tIsCreatingSecondaryNewConnection() bool\n}\n\ntype clientRoundtripper struct {\n\tdial           func(network, addr string) (net.Conn, error)\n\tserverIdentity []byte\n\n\tcurrentConnInnerConn common.Closable\n\tcurrentConn          http.RoundTripper\n\tcurrentConnLock      sync.RWMutex\n\n\tpendingNewConnection int\n\t// DO NOT ATTEMPT TO ACQUIRE ANY LOCK WHILE HOLDING THIS LOCK\n\tpendingNewConnectionLock sync.RWMutex\n}\n\nfunc (c *clientRoundtripper) IsCreatingSecondaryNewConnection() bool {\n\tdefer c.pendingNewConnectionLock.RUnlock()\n\tc.pendingNewConnectionLock.RLock()\n\treturn c.pendingNewConnection >= 1\n}\n\nfunc (c *clientRoundtripper) RoundTrip(request *http.Request) (*http.Response, error) {\n\tif c.IsCreatingSecondaryNewConnection() {\n\t\treturn nil, newError(\"another connection is being established, cannot create a secondary connection\")\n\t}\n\treturn c.roundTrip(request)\n}\n\nfunc (c *clientRoundtripper) roundTrip(request *http.Request) (*http.Response, error) {\n\tc.currentConnLock.RLock()\n\n\tif c.currentConn == nil {\n\t\tc.currentConnLock.RUnlock()\n\t\tc.pendingNewConnectionLock.Lock()\n\t\tc.pendingNewConnection += 1\n\t\tc.pendingNewConnectionLock.Unlock()\n\t\tdecreaseCount := func() {\n\t\t\tc.pendingNewConnectionLock.Lock()\n\t\t\tc.pendingNewConnection -= 1\n\t\t\tc.pendingNewConnectionLock.Unlock()\n\t\t}\n\t\tif err := c.createNewConnection(); err != nil {\n\t\t\tdecreaseCount()\n\t\t\treturn nil, err // Failed to create a new connection\n\t\t}\n\t\tresp, err := c.roundTrip(request)\n\t\tdecreaseCount()\n\t\treturn resp, err\n\t}\n\tdefer c.currentConnLock.RUnlock()\n\n\ttimeoutContext, _ := context.WithTimeout(context.Background(), time.Second*30) //nolint:govet\n\trequest = request.WithContext(timeoutContext)\n\n\tresp, err := c.currentConn.RoundTrip(request)\n\t// Use the current connection to perform the round trip\n\tif err != nil {\n\t\tif resp != nil && resp.Body != nil {\n\t\t\tresp.Body.Close()\n\t\t}\n\n\t\tdefer func() {\n\t\t\tc.currentConnLock.RUnlock()\n\t\t\tc.currentConnLock.Lock()\n\t\t\tif c.currentConn != nil {\n\t\t\t\tc.currentConnInnerConn.Close()\n\t\t\t\tc.currentConnInnerConn = nil\n\t\t\t\tc.currentConn = nil\n\t\t\t}\n\t\t\tc.currentConnLock.Unlock()\n\t\t\tc.currentConnLock.RLock()\n\t\t}()\n\t\treturn nil, newError(\"unable to roundtrip for enrollment verification\").Base(err)\n\t}\n\treturn resp, nil\n}\n\nfunc (c *clientRoundtripper) createNewConnection() error {\n\tc.currentConnLock.Lock()\n\tdefer c.currentConnLock.Unlock()\n\n\tif c.currentConn != nil {\n\t\treturn nil // Connection already exists\n\t}\n\n\tserverID := base32.NewEncoding(\"0123456789abcdefghijklmnopqrstuv\").WithPadding(base32.NoPadding).EncodeToString(c.serverIdentity)\n\tconn, err := c.dial(\"tcp\", serverID+tlsmirror.EnrollmentVerificationControlConnectionPostfix+\":80\")\n\tif err != nil {\n\t\treturn newError(\"failed to dial server: \", err)\n\t}\n\tc.currentConnInnerConn = conn\n\tc.currentConn, err = httponconnection.NewSingleConnectionHTTPTransport(conn, \"h2\")\n\tif err != nil {\n\t\t_ = conn.Close() // Close the connection if transport creation fails\n\t\treturn newError(\"failed to create HTTP transport: \", err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation/enrollment.go",
    "content": "package httpenrollmentconfirmation\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation/errors.generated.go",
    "content": "package httpenrollmentconfirmation\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation/hub.go",
    "content": "package httpenrollmentconfirmation\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"golang.org/x/net/http2\"\n)\n\nfunc NewHTTPConnectionHub(handler http.Handler) *HTTPConnectionHub {\n\treturn &HTTPConnectionHub{\n\t\thandler:  handler,\n\t\th2server: &http2.Server{},\n\t}\n}\n\ntype HTTPConnectionHub struct {\n\thandler  http.Handler\n\th2server *http2.Server\n}\n\nfunc (h *HTTPConnectionHub) ServeConnection(ctx context.Context, conn net.Conn) error {\n\tgo h.h2server.ServeConn(conn, &http2.ServeConnOpts{\n\t\tHandler: h.handler,\n\t})\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation/server.go",
    "content": "package httpenrollmentconfirmation\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"strconv\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewHTTPEnrollmentConfirmationServerFromConnectionEnrollmentConfirmation(confirmation tlsmirror.ConnectionEnrollmentConfirmation) (http.Handler, error) {\n\tif confirmation == nil {\n\t\treturn nil, newError(\"nil confirmation\")\n\t}\n\treturn &server{\n\t\tConnectionEnrollmentConfirmation: confirmation,\n\t}, nil\n}\n\ntype server struct {\n\ttlsmirror.ConnectionEnrollmentConfirmation\n}\n\nfunc (s *server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {\n\trequestBody, err := io.ReadAll(request.Body)\n\tif err != nil {\n\t\thttp.Error(writer, \"failed to read request body: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\treq := &tlsmirror.EnrollmentConfirmationReq{}\n\tif err := proto.Unmarshal(requestBody, req); err != nil {\n\t\thttp.Error(writer, \"failed to unmarshal request: \"+err.Error(), http.StatusBadRequest)\n\t\treturn\n\t}\n\tresp, err := s.VerifyConnectionEnrollment(req)\n\tif err != nil {\n\t\thttp.Error(writer, \"failed to verify connection enrollment: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tresponseBody, err := proto.Marshal(resp)\n\tif err != nil {\n\t\thttp.Error(writer, \"failed to marshal response: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\twriter.Header().Set(\"Content-Type\", \"application/octet-stream\")\n\twriter.Header().Set(\"Content-Length\", strconv.Itoa(len(responseBody)))\n\twriter.WriteHeader(http.StatusOK)\n\tif _, err := writer.Write(responseBody); err != nil {\n\t\thttp.Error(writer, \"failed to write response: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tif flusher, ok := writer.(http.Flusher); ok {\n\t\tflusher.Flush()\n\t} else {\n\t\thttp.Error(writer, \"response writer does not support flushing\", http.StatusInternalServerError)\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/keyderivation.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcrypto\"\n)\n\ntype EnrollmentKey struct {\n\tEnrollmentRequestKey  []byte\n\tEnrollmentResponseKey []byte\n}\n\nfunc DeriveEnrollmentKeyWithClientAndServerRandom(primaryKey []byte, clientRandom []byte, serverRandom []byte) (*EnrollmentKey, error) {\n\trequestKey, responseKey, err := mirrorcrypto.DeriveEncryptionKey(primaryKey, clientRandom, serverRandom,\n\t\t\":connection-enrollment-re78HQNM-CmpRnPbr-PNJVRMhu\")\n\tif err != nil {\n\t\treturn nil, newError(\"failed to derive connection enrollment key\").Base(err).AtError()\n\t}\n\treturn &EnrollmentKey{\n\t\tEnrollmentRequestKey:  requestKey,\n\t\tEnrollmentResponseKey: responseKey,\n\t}, nil\n}\n\nfunc DeriveEnrollmentServerIdentifier(primaryKey []byte) ([]byte, error) {\n\tif len(primaryKey) != 32 {\n\t\treturn nil, newError(\"invalid primary key size: \", len(primaryKey))\n\t}\n\n\t// Use HKDF to derive a secondary key\n\tserverID, err := mirrorcrypto.DeriveSecondaryKey(primaryKey, \":connection-enrollment-server-identifier-av38NNGF-TJvRw7C3-p8KM8yKd\")\n\tif err != nil {\n\t\treturn nil, newError(\"unable to\tserver identifier\").Base(err)\n\t}\n\n\treturn serverID, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/client.go",
    "content": "package roundtripperenrollmentconfirmation\n\nimport (\n\t\"context\"\n\tcsrand \"crypto/rand\"\n\t\"io\"\n\t\"net\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {\n\tif ctx == nil {\n\t\treturn nil, newError(\"context cannot be nil\")\n\t}\n\n\tif config == nil {\n\t\treturn nil, newError(\"config cannot be nil\")\n\t}\n\n\trttClientConfig, err := serial.GetInstanceOf(config.RoundTripperClient)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get instance of RoundTripperClient\").Base(err)\n\t}\n\n\trttClientI, err := common.CreateObject(ctx, rttClientConfig)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create RoundTripperClient\").Base(err)\n\t}\n\n\trttClient, ok := rttClientI.(request.RoundTripperClient)\n\tif !ok {\n\t\treturn nil, newError(\"RoundTripperClient is not a valid request.RoundTripperClient\")\n\t}\n\n\tclientTemporaryIdentifier := make([]byte, 16)\n\tif _, err := csrand.Read(clientTemporaryIdentifier); err != nil {\n\t\treturn nil, newError(\"failed to generate client temporary identifier\").Base(err)\n\t}\n\n\tc := &Client{\n\t\tctx:                       ctx,\n\t\tconfig:                    config,\n\t\trttClient:                 rttClient,\n\t\tclientTemporaryIdentifier: clientTemporaryIdentifier,\n\t}\n\n\trttClient.OnTransportClientAssemblyReady(c)\n\n\treturn c, nil\n}\n\ntype Client struct {\n\tconfig    *ClientConfig\n\trttClient request.RoundTripperClient\n\n\tclientTemporaryIdentifier []byte\n\n\tctx context.Context\n\n\tdefaultOutboundTag string\n}\n\nfunc (c *Client) OnConnectionEnrollmentConfirmationClientInstanceConfigReady(config tlsmirror.ConnectionEnrollmentConfirmationClientInstanceConfig) {\n\tc.defaultOutboundTag = config.DefaultOutboundTag\n}\n\nfunc (c *Client) Dial(ctx context.Context) (net.Conn, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(c.ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.OutboundDialer()\n\tif dialer == nil {\n\t\treturn nil, newError(\"no outbound dialer available in transport environment\")\n\t}\n\tdest, err := v2net.ParseDestination(c.config.Dest)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse destination address\").Base(err).AtError()\n\t}\n\tdest.Network = v2net.Network_TCP\n\tconn, err := dialer(c.ctx, dest, c.config.OutboundTag)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial to destination\").Base(err).AtError()\n\t}\n\tif c.config.SecurityConfig != nil {\n\t\tsecurityConfigSetting, err := serial.GetInstanceOf(c.config.SecurityConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to get security config instance\").Base(err)\n\t\t}\n\t\tsecurityEngine, err := common.CreateObject(c.ctx, securityConfigSetting)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create security engine from security settings\").Base(err)\n\t\t}\n\t\tsecurityEngineTyped, ok := securityEngine.(security.Engine)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"type assertion error when create security engine from security settings\")\n\t\t}\n\t\tconn, err = securityEngineTyped.Client(conn, security.OptionWithDestination{Dest: dest})\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create security protocol client from security engine\").Base(err)\n\t\t}\n\t}\n\treturn conn, nil\n}\n\nfunc (c *Client) Tripper() request.Tripper {\n\treturn c.rttClient\n}\n\nfunc (c *Client) AutoImplDialer() request.Dialer {\n\treturn c\n}\n\nfunc (c *Client) VerifyConnectionEnrollment(req *tlsmirror.EnrollmentConfirmationReq) (*tlsmirror.EnrollmentConfirmationResp, error) {\n\tconnectionTagServerID := req.ServerIdentifier\n\tif c.config.ServerIdentity != nil {\n\t\tconnectionTagServerID = c.config.ServerIdentity\n\t}\n\tvar replyAddressTag [16]byte\n\t_, err := io.ReadFull(csrand.Reader, replyAddressTag[:])\n\tif err != nil {\n\t\treturn nil, newError(\"failed to generate reply address tag\").Base(err)\n\t}\n\n\tconnectionTag := append(replyAddressTag[:], connectionTagServerID...) //nolint:gocritic\n\treq.ClientIdentifier = c.clientTemporaryIdentifier\n\treq.ReplyAddressTag = replyAddressTag[:]\n\twrappedData, err := proto.Marshal(req)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to marshal enrollment confirmation request\").Base(err)\n\t}\n\twreq := request.Request{\n\t\tData:          wrappedData,\n\t\tConnectionTag: connectionTag,\n\t}\n\tresp, err := c.rttClient.RoundTrip(c.ctx, wreq)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to perform round trip\").Base(err)\n\t}\n\tconfirmationResp := &tlsmirror.EnrollmentConfirmationResp{}\n\tif err := proto.Unmarshal(resp.Data, confirmationResp); err != nil {\n\t\treturn nil, newError(\"failed to unmarshal enrollment confirmation response\").Base(err)\n\t}\n\treturn confirmationResp, nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewClient(ctx, config.(*ClientConfig))\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/config.pb.go",
    "content": "package roundtripperenrollmentconfirmation\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\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\tunsafe \"unsafe\"\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 ClientConfig struct {\n\tstate              protoimpl.MessageState `protogen:\"open.v1\"`\n\tRoundTripperClient *anypb.Any             `protobuf:\"bytes,1,opt,name=round_tripper_client,json=roundTripperClient,proto3\" json:\"round_tripper_client,omitempty\"`\n\tSecurityConfig     *anypb.Any             `protobuf:\"bytes,2,opt,name=security_config,json=securityConfig,proto3\" json:\"security_config,omitempty\"`\n\tDest               string                 `protobuf:\"bytes,3,opt,name=dest,proto3\" json:\"dest,omitempty\"`\n\tOutboundTag        string                 `protobuf:\"bytes,4,opt,name=outbound_tag,json=outboundTag,proto3\" json:\"outbound_tag,omitempty\"`\n\tServerIdentity     []byte                 `protobuf:\"bytes,5,opt,name=server_identity,json=serverIdentity,proto3\" json:\"server_identity,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *ClientConfig) Reset() {\n\t*x = ClientConfig{}\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ClientConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ClientConfig) ProtoMessage() {}\n\nfunc (x *ClientConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes[0]\n\tif 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 ClientConfig.ProtoReflect.Descriptor instead.\nfunc (*ClientConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ClientConfig) GetRoundTripperClient() *anypb.Any {\n\tif x != nil {\n\t\treturn x.RoundTripperClient\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetSecurityConfig() *anypb.Any {\n\tif x != nil {\n\t\treturn x.SecurityConfig\n\t}\n\treturn nil\n}\n\nfunc (x *ClientConfig) GetDest() string {\n\tif x != nil {\n\t\treturn x.Dest\n\t}\n\treturn \"\"\n}\n\nfunc (x *ClientConfig) GetOutboundTag() string {\n\tif x != nil {\n\t\treturn x.OutboundTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *ClientConfig) GetServerIdentity() []byte {\n\tif x != nil {\n\t\treturn x.ServerIdentity\n\t}\n\treturn nil\n}\n\ntype ServerInverseRoleConfig struct {\n\tstate              protoimpl.MessageState `protogen:\"open.v1\"`\n\tRoundTripperClient *anypb.Any             `protobuf:\"bytes,1,opt,name=round_tripper_client,json=roundTripperClient,proto3\" json:\"round_tripper_client,omitempty\"`\n\tSecurityConfig     *anypb.Any             `protobuf:\"bytes,2,opt,name=security_config,json=securityConfig,proto3\" json:\"security_config,omitempty\"`\n\tDest               string                 `protobuf:\"bytes,3,opt,name=dest,proto3\" json:\"dest,omitempty\"`\n\tOutboundTag        string                 `protobuf:\"bytes,4,opt,name=outbound_tag,json=outboundTag,proto3\" json:\"outbound_tag,omitempty\"`\n\tServerIdentity     []byte                 `protobuf:\"bytes,5,opt,name=server_identity,json=serverIdentity,proto3\" json:\"server_identity,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *ServerInverseRoleConfig) Reset() {\n\t*x = ServerInverseRoleConfig{}\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerInverseRoleConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerInverseRoleConfig) ProtoMessage() {}\n\nfunc (x *ServerInverseRoleConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes[1]\n\tif 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 ServerInverseRoleConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerInverseRoleConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ServerInverseRoleConfig) GetRoundTripperClient() *anypb.Any {\n\tif x != nil {\n\t\treturn x.RoundTripperClient\n\t}\n\treturn nil\n}\n\nfunc (x *ServerInverseRoleConfig) GetSecurityConfig() *anypb.Any {\n\tif x != nil {\n\t\treturn x.SecurityConfig\n\t}\n\treturn nil\n}\n\nfunc (x *ServerInverseRoleConfig) GetDest() string {\n\tif x != nil {\n\t\treturn x.Dest\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerInverseRoleConfig) GetOutboundTag() string {\n\tif x != nil {\n\t\treturn x.OutboundTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerInverseRoleConfig) GetServerIdentity() []byte {\n\tif x != nil {\n\t\treturn x.ServerIdentity\n\t}\n\treturn nil\n}\n\ntype ServerConfig struct {\n\tstate              protoimpl.MessageState `protogen:\"open.v1\"`\n\tRoundTripperServer *anypb.Any             `protobuf:\"bytes,2,opt,name=round_tripper_server,json=roundTripperServer,proto3\" json:\"round_tripper_server,omitempty\"`\n\tListen             string                 `protobuf:\"bytes,3,opt,name=listen,proto3\" json:\"listen,omitempty\"`\n\tunknownFields      protoimpl.UnknownFields\n\tsizeCache          protoimpl.SizeCache\n}\n\nfunc (x *ServerConfig) Reset() {\n\t*x = ServerConfig{}\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *ServerConfig) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerConfig) ProtoMessage() {}\n\nfunc (x *ServerConfig) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes[2]\n\tif 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 ServerConfig.ProtoReflect.Descriptor instead.\nfunc (*ServerConfig) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ServerConfig) GetRoundTripperServer() *anypb.Any {\n\tif x != nil {\n\t\treturn x.RoundTripperServer\n\t}\n\treturn nil\n}\n\nfunc (x *ServerConfig) GetListen() string {\n\tif x != nil {\n\t\treturn x.Listen\n\t}\n\treturn \"\"\n}\n\nvar File_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"]transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/config.proto\\x12[v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation\\x1a common/protoext/extensions.proto\\x1a\\x19google/protobuf/any.proto\\\"\\xf5\\x01\\n\" +\n\t\"\\fClientConfig\\x12F\\n\" +\n\t\"\\x14round_tripper_client\\x18\\x01 \\x01(\\v2\\x14.google.protobuf.AnyR\\x12roundTripperClient\\x12=\\n\" +\n\t\"\\x0fsecurity_config\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x0esecurityConfig\\x12\\x12\\n\" +\n\t\"\\x04dest\\x18\\x03 \\x01(\\tR\\x04dest\\x12!\\n\" +\n\t\"\\foutbound_tag\\x18\\x04 \\x01(\\tR\\voutboundTag\\x12'\\n\" +\n\t\"\\x0fserver_identity\\x18\\x05 \\x01(\\fR\\x0eserverIdentity\\\"\\x80\\x02\\n\" +\n\t\"\\x17ServerInverseRoleConfig\\x12F\\n\" +\n\t\"\\x14round_tripper_client\\x18\\x01 \\x01(\\v2\\x14.google.protobuf.AnyR\\x12roundTripperClient\\x12=\\n\" +\n\t\"\\x0fsecurity_config\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x0esecurityConfig\\x12\\x12\\n\" +\n\t\"\\x04dest\\x18\\x03 \\x01(\\tR\\x04dest\\x12!\\n\" +\n\t\"\\foutbound_tag\\x18\\x04 \\x01(\\tR\\voutboundTag\\x12'\\n\" +\n\t\"\\x0fserver_identity\\x18\\x05 \\x01(\\fR\\x0eserverIdentity\\\"n\\n\" +\n\t\"\\fServerConfig\\x12F\\n\" +\n\t\"\\x14round_tripper_server\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x12roundTripperServer\\x12\\x16\\n\" +\n\t\"\\x06listen\\x18\\x03 \\x01(\\tR\\x06listenB\\xb2\\x02\\n\" +\n\t\"_com.v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmationP\\x01Zogithub.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation\\xaa\\x02[V2Ray.Core.Transport.Internet.Tlsmirror.MirrorEnrollment.RoundTripperEnrollmentConfirmationb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDesc), len(file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDescData\n}\n\nvar file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_goTypes = []any{\n\t(*ClientConfig)(nil),            // 0: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ClientConfig\n\t(*ServerInverseRoleConfig)(nil), // 1: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ServerInverseRoleConfig\n\t(*ServerConfig)(nil),            // 2: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ServerConfig\n\t(*anypb.Any)(nil),               // 3: google.protobuf.Any\n}\nvar file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ClientConfig.round_tripper_client:type_name -> google.protobuf.Any\n\t3, // 1: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ClientConfig.security_config:type_name -> google.protobuf.Any\n\t3, // 2: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ServerInverseRoleConfig.round_tripper_client:type_name -> google.protobuf.Any\n\t3, // 3: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ServerInverseRoleConfig.security_config:type_name -> google.protobuf.Any\n\t3, // 4: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation.ServerConfig.round_tripper_server:type_name -> google.protobuf.Any\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() {\n\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_init()\n}\nfunc file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_init() {\n\tif File_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDesc), len(file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto = out.File\n\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_goTypes = nil\n\tfile_transport_internet_tlsmirror_mirrorenrollment_roundtripperenrollmentconfirmation_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tlsmirror.MirrorEnrollment.RoundTripperEnrollmentConfirmation\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation\";\noption java_package = \"com.v2ray.core.transport.internet.tlsmirror.mirrorenrollment.roundtripperenrollmentconfirmation\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"google/protobuf/any.proto\";\n\nmessage ClientConfig {\n  google.protobuf.Any round_tripper_client = 1;\n  google.protobuf.Any security_config = 2;\n  string dest = 3;\n  string outbound_tag = 4;\n  bytes server_identity = 5;\n}\n\nmessage ServerInverseRoleConfig {\n  google.protobuf.Any round_tripper_client = 1;\n  google.protobuf.Any security_config = 2;\n  string dest = 3;\n  string outbound_tag = 4;\n  bytes server_identity = 5;\n}\n\nmessage ServerConfig {\n  google.protobuf.Any round_tripper_server = 2;\n  string listen = 3;\n}"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/errors.generated.go",
    "content": "package roundtripperenrollmentconfirmation\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/rttconfirmation.go",
    "content": "package roundtripperenrollmentconfirmation\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/server.go",
    "content": "package roundtripperenrollmentconfirmation\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {\n\ts := &Server{\n\t\tctx:    ctx,\n\t\tconfig: config,\n\t}\n\n\tif err := s.init(); err != nil {\n\t\treturn nil, newError(\"failed to initialize RoundTripperEnrollmentConfirmation server\").Base(err).AtError()\n\t}\n\treturn s, nil\n}\n\ntype Server struct {\n\tconfig              *ServerConfig\n\tctx                 context.Context\n\tenrollmentProcessor tlsmirror.ConnectionEnrollmentConfirmationProcessor\n\trttServer           request.RoundTripperServer\n}\n\nfunc (s *Server) OnConnectionEnrollmentConfirmationServerInstanceConfigReady(config tlsmirror.ConnectionEnrollmentConfirmationServerInstanceConfig) {\n\ts.enrollmentProcessor = config.EnrollmentProcessor\n}\n\nfunc (s *Server) Listen(ctx context.Context) (v2net.Listener, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(s.ctx).(environment.TransportEnvironment)\n\tlistener := transportEnvironment.Listener()\n\taddr, err := v2net.ParseDestination(s.config.Listen)\n\tif err != nil {\n\t\tpanic(newError(\"invalid listen address \" + s.config.Listen).Base(err).AtError())\n\t}\n\tnetaddr := &net.TCPAddr{IP: addr.Address.IP(), Port: int(addr.Port)}\n\tl, err := listener.Listen(s.ctx, netaddr, nil)\n\tif err != nil {\n\t\tpanic(newError(\"failed to listen on \" + s.config.Listen).Base(err).AtError())\n\t}\n\treturn l, nil\n}\n\nfunc (s *Server) OnRoundTrip(ctx context.Context, req request.Request, opts ...request.RoundTripperOption) (resp request.Response, err error) {\n\tenrollmentReq := &tlsmirror.EnrollmentConfirmationReq{}\n\terr = proto.Unmarshal(req.Data, enrollmentReq)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"failed to unmarshal enrollment confirmation request\").Base(err).AtError()\n\t}\n\tenrollmentResp, err := s.enrollmentProcessor.VerifyConnectionEnrollment(enrollmentReq)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"failed to process enrollment confirmation request\").Base(err).AtError()\n\t}\n\trespData, err := proto.Marshal(enrollmentResp)\n\tif err != nil {\n\t\treturn request.Response{}, newError(\"failed to marshal enrollment confirmation response\").Base(err).AtError()\n\t}\n\treturn request.Response{\n\t\tData: respData,\n\t}, nil\n}\n\nfunc (s *Server) TripperReceiver() request.TripperReceiver {\n\treturn s\n}\n\nfunc (s *Server) SessionReceiver() request.SessionReceiver {\n\treturn nil\n}\n\nfunc (s *Server) AutoImplListener() request.Listener {\n\treturn s\n}\n\nfunc (s *Server) init() error {\n\tif s.config == nil {\n\t\treturn newError(\"nil ServerConfig\")\n\t}\n\tif s.config.RoundTripperServer == nil {\n\t\treturn newError(\"nil RoundTripperServer in ServerConfig\")\n\t}\n\tRoundTripperServerConfig, err := serial.GetInstanceOf(s.config.RoundTripperServer)\n\tif err != nil {\n\t\treturn newError(\"failed to get instance of RoundTripperServer\").Base(err).AtError()\n\t}\n\tRoundTripperServerObj, err := common.CreateObject(s.ctx, RoundTripperServerConfig)\n\tif err != nil {\n\t\treturn newError(\"failed to create RoundTripperServer\").Base(err).AtError()\n\t}\n\tRoundTripperServerTyped, ok := RoundTripperServerObj.(request.RoundTripperServer)\n\tif !ok {\n\t\treturn newError(\"RoundTripperServer is not a valid request.RoundTripperServer\")\n\t}\n\ts.rttServer = RoundTripperServerTyped\n\ts.rttServer.OnTransportServerAssemblyReady(s)\n\tif err := s.rttServer.Start(); err != nil {\n\t\treturn newError(\"failed to start RoundTripperServer\").Base(err).AtError()\n\t}\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServer(ctx, config.(*ServerConfig))\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/roundtripperenrollmentconfirmation/serverinverserole.go",
    "content": "package roundtripperenrollmentconfirmation\n\nimport (\n\t\"context\"\n\tcsrand \"crypto/rand\"\n\t\"net\"\n\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\tv2net \"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/request\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewServerInverseRole(ctx context.Context, config *ServerInverseRoleConfig) (*ServerInverseRole, error) {\n\tif ctx == nil {\n\t\treturn nil, newError(\"context cannot be nil\")\n\t}\n\n\tif config == nil {\n\t\treturn nil, newError(\"config cannot be nil\")\n\t}\n\n\trttClientConfig, err := serial.GetInstanceOf(config.RoundTripperClient)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get instance of RoundTripperClient\").Base(err)\n\t}\n\n\trttClientI, err := common.CreateObject(ctx, rttClientConfig)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create RoundTripperClient\").Base(err)\n\t}\n\n\trttClient, ok := rttClientI.(request.RoundTripperClient)\n\tif !ok {\n\t\treturn nil, newError(\"RoundTripperClient is not a valid request.RoundTripperClient\")\n\t}\n\n\tclientTemporaryIdentifier := make([]byte, 16)\n\tif _, err := csrand.Read(clientTemporaryIdentifier); err != nil {\n\t\treturn nil, newError(\"failed to generate client temporary identifier\").Base(err)\n\t}\n\n\tc := &ServerInverseRole{\n\t\tctx:                       ctx,\n\t\tconfig:                    config,\n\t\trttClient:                 rttClient,\n\t\tclientTemporaryIdentifier: clientTemporaryIdentifier,\n\t}\n\n\trttClient.OnTransportClientAssemblyReady(c)\n\n\tgo c.worker(ctx)\n\n\treturn c, nil\n}\n\ntype ServerInverseRole struct {\n\tconfig    *ServerInverseRoleConfig\n\trttClient request.RoundTripperClient\n\n\tclientTemporaryIdentifier []byte\n\n\tctx context.Context\n\n\tdefaultOutboundTag string\n\n\tenrollmentProcessor tlsmirror.ConnectionEnrollmentConfirmationProcessor\n}\n\nfunc (c *ServerInverseRole) worker(ctx context.Context) {\n\tfor ctx.Err() == nil {\n\t\terr := c.pollRemoteForEnrollment(ctx)\n\t\tif err != nil {\n\t\t\tnewError(\"error polling remote for enrollment\").Base(err).AtWarning().WriteToLog()\n\t\t}\n\t}\n\tnewError(\"inverse role server quitted\").AtWarning().WriteToLog()\n}\n\nfunc (c *ServerInverseRole) Dial(ctx context.Context) (net.Conn, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.OutboundDialer()\n\tif dialer == nil {\n\t\treturn nil, newError(\"no outbound dialer available in transport environment\")\n\t}\n\tdest, err := v2net.ParseDestination(c.config.Dest)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to parse destination address\").Base(err).AtError()\n\t}\n\tdest.Network = v2net.Network_TCP\n\tconn, err := dialer(ctx, dest, c.config.OutboundTag)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial to destination\").Base(err).AtError()\n\t}\n\tif c.config.SecurityConfig != nil {\n\t\tsecurityConfigSetting, err := serial.GetInstanceOf(c.config.SecurityConfig)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to get security config instance\").Base(err)\n\t\t}\n\t\tsecurityEngine, err := common.CreateObject(c.ctx, securityConfigSetting)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create security engine from security settings\").Base(err)\n\t\t}\n\t\tsecurityEngineTyped, ok := securityEngine.(security.Engine)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"type assertion error when create security engine from security settings\")\n\t\t}\n\t\tconn, err = securityEngineTyped.Client(conn, security.OptionWithDestination{Dest: dest})\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create security protocol client from security engine\").Base(err)\n\t\t}\n\t}\n\treturn conn, nil\n}\n\nfunc (c *ServerInverseRole) Tripper() request.Tripper {\n\treturn c.rttClient\n}\n\nfunc (c *ServerInverseRole) AutoImplDialer() request.Dialer {\n\treturn c\n}\n\nfunc (s *ServerInverseRole) OnConnectionEnrollmentConfirmationServerInstanceConfigReady(config tlsmirror.ConnectionEnrollmentConfirmationServerInstanceConfig) {\n\ts.enrollmentProcessor = config.EnrollmentProcessor\n}\n\nfunc (s *ServerInverseRole) pollRemoteForEnrollment(ctx context.Context) error {\n\tpollAs := s.config.ServerIdentity\n\treq := request.Request{\n\t\tConnectionTag: pollAs,\n\t}\n\tresp, err := s.rttClient.RoundTrip(ctx, req)\n\tif err != nil {\n\t\treturn newError(\"failed to poll remote for enrollment\").Base(err)\n\t}\n\tif resp.Data == nil {\n\t\treturn newError(\"no enrollment confirmation response received from remote\")\n\t}\n\tenrollmentReq := &tlsmirror.EnrollmentConfirmationReq{}\n\terr = proto.Unmarshal(resp.Data, enrollmentReq)\n\tif err != nil {\n\t\treturn newError(\"failed to unmarshal enrollment confirmation request\").Base(err).AtError()\n\t}\n\tenrollmentResp, err := s.enrollmentProcessor.VerifyConnectionEnrollment(enrollmentReq)\n\tif err != nil {\n\t\treturn newError(\"failed to process enrollment confirmation request\").Base(err).AtError()\n\t}\n\trespData, err := proto.Marshal(enrollmentResp)\n\tif err != nil {\n\t\treturn newError(\"failed to marshal enrollment confirmation response\").Base(err).AtError()\n\t}\n\trespAs := append(s.config.ServerIdentity, enrollmentReq.ReplyAddressTag...) //nolint:gocritic\n\t_, err = s.rttClient.RoundTrip(ctx, request.Request{\n\t\tData:          respData,\n\t\tConnectionTag: respAs,\n\t})\n\tif err != nil {\n\t\treturn newError(\"failed to send enrollment confirmation response back to remote\").Base(err)\n\t}\n\tnewError(\"successfully processed enrollment confirmation request\").AtDebug().WriteToLog()\n\treturn nil\n}\n\nfunc init() {\n\tcommon.Must(common.RegisterConfig((*ServerInverseRoleConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {\n\t\treturn NewServerInverseRole(ctx, config.(*ServerInverseRoleConfig))\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/server.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment/httpenrollmentconfirmation\"\n)\n\nfunc NewEnrollmentConfirmationServer(ctx context.Context, config *Config, enrollmentProcessor tlsmirror.ConnectionEnrollmentConfirmationProcessor) (*EnrollmentConfirmationServer, error) {\n\tif ctx == nil {\n\t\treturn nil, newError(\"context cannot be nil\")\n\t}\n\n\tif config == nil {\n\t\treturn nil, newError(\"config cannot be nil\")\n\t}\n\n\tfor _, handler := range config.BootstrapIngressUrl {\n\t\tif handler == \"\" {\n\t\t\treturn nil, newError(\"bootstrap ingress URL cannot be empty\")\n\t\t}\n\t\tanyPb, err := AnyFromLink(handler)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"invalid bootstrap ingress URL\").Base(err).AtError()\n\t\t}\n\t\tif anyPb == nil {\n\t\t\treturn nil, newError(\"bootstrap ingress URL did not produce valid Any\")\n\t\t}\n\t\tconfig.BootstrapIngressConfig = append(config.BootstrapIngressConfig, anyPb)\n\t}\n\n\tif enrollmentProcessor == nil {\n\t\treturn nil, newError(\"enrollment processor cannot be nil\")\n\t}\n\n\tenrollmentHandler, err := httpenrollmentconfirmation.NewHTTPEnrollmentConfirmationServerFromConnectionEnrollmentConfirmation(enrollmentProcessor)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create HTTP enrollment confirmation server\").Base(err).AtError()\n\t}\n\n\tprimaryIngressConnectionHandler := httpenrollmentconfirmation.NewHTTPConnectionHub(enrollmentHandler)\n\n\ts := &EnrollmentConfirmationServer{\n\t\tctx:                             ctx,\n\t\tconfig:                          config,\n\t\tenrollmentProcessor:             enrollmentProcessor,\n\t\tprimaryIngressConnectionHandler: primaryIngressConnectionHandler,\n\t}\n\n\tif err = s.init(); err != nil {\n\t\treturn nil, newError(\"failed to initialize enrollment confirmation server\").Base(err).AtError()\n\t}\n\n\treturn s, nil\n}\n\ntype EnrollmentConfirmationServer struct {\n\tctx context.Context\n\n\tconfig *Config\n\n\tenrollmentProcessor tlsmirror.ConnectionEnrollmentConfirmationProcessor\n\n\tprimaryIngressConnectionHandler    *httpenrollmentconfirmation.HTTPConnectionHub\n\tbootstrapIngressConnectionHandlers []tlsmirror.ConnectionEnrollmentConfirmationServerInstanceConfigReceiver\n}\n\nfunc (s *EnrollmentConfirmationServer) HandlePrimaryIngressConnection(ctx context.Context, conn net.Conn) error {\n\terr := s.primaryIngressConnectionHandler.ServeConnection(ctx, conn)\n\tif err != nil {\n\t\treturn newError(\"failed to handle primary ingress connection\").Base(err).AtError()\n\t}\n\treturn nil\n}\n\nfunc (s *EnrollmentConfirmationServer) init() error {\n\tfor _, handler := range s.config.BootstrapIngressConfig {\n\t\tbootstrapEnrollmentHandler, err := serial.GetInstanceOf(handler)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to get instance of bootstrap enrollment handler\").Base(err).AtError()\n\t\t}\n\t\tbootstrapEnrollmentHandlerObj, err := common.CreateObject(s.ctx, bootstrapEnrollmentHandler)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create bootstrap enrollment handler\").Base(err).AtError()\n\t\t}\n\t\tbootstrapEnrollmentHandlerObjTyped, ok := bootstrapEnrollmentHandlerObj.(tlsmirror.ConnectionEnrollmentConfirmationServerInstanceConfigReceiver)\n\t\tif !ok {\n\t\t\treturn newError(\"bootstrap enrollment handler is not a valid ConnectionEnrollmentConfirmationServerInstanceConfigReceiver\")\n\t\t}\n\n\t\tbootstrapEnrollmentHandlerObjTyped.OnConnectionEnrollmentConfirmationServerInstanceConfigReady(\n\t\t\ttlsmirror.ConnectionEnrollmentConfirmationServerInstanceConfig{\n\t\t\t\tEnrollmentProcessor: s.enrollmentProcessor,\n\t\t\t})\n\t\ts.bootstrapIngressConnectionHandlers = append(s.bootstrapIngressConnectionHandlers, bootstrapEnrollmentHandlerObjTyped)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/mirrorenrollment/serverenrollmentprocessor.go",
    "content": "package mirrorenrollment\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n)\n\nfunc NewServerEnrollmentProcessor(primaryKey []byte) (tlsmirror.ConnectionEnrollmentConfirmationProcessor, error) {\n\tif len(primaryKey) == 0 {\n\t\treturn nil, newError(\"primary key cannot be empty\")\n\t}\n\n\treturn &serverEnrollmentProcessor{\n\t\tprimaryKey: primaryKey,\n\t}, nil\n}\n\ntype serverEnrollmentProcessor struct {\n\tprimaryKey        []byte\n\tactiveConnections sync.Map\n}\n\nfunc (p *serverEnrollmentProcessor) AddConnection(ctx context.Context, clientRandom, serverRandom []byte, conn tlsmirror.InsertableTLSConnForEnrollment) (tlsmirror.RemoveConnectionFunc, error) {\n\tif conn == nil {\n\t\treturn nil, newError(\"nil InsertableTLSConnForEnrollment\")\n\t}\n\n\tenrollmentKey, err := DeriveEnrollmentKeyWithClientAndServerRandom(p.primaryKey, clientRandom, serverRandom)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to derive enrollment key\").Base(err).AtError()\n\t}\n\n\tif _, loaded := p.activeConnections.LoadOrStore(string(enrollmentKey.EnrollmentRequestKey), conn); loaded {\n\t\treturn nil, newError(\"connection with ID \", enrollmentKey.EnrollmentRequestKey, \" already exists\")\n\t}\n\n\treturn func() error {\n\t\tp.activeConnections.Delete(string(enrollmentKey.EnrollmentRequestKey))\n\t\treturn nil\n\t}, nil\n}\n\nfunc (p *serverEnrollmentProcessor) VerifyConnectionEnrollment(req *tlsmirror.EnrollmentConfirmationReq) (*tlsmirror.EnrollmentConfirmationResp, error) {\n\tif req == nil {\n\t\treturn nil, newError(\"nil EnrollmentConfirmationReq\")\n\t}\n\n\tif req.CarrierTlsConnectionClientRandom == nil || req.CarrierTlsConnectionServerRandom == nil {\n\t\treturn nil, newError(\"missing client or server random in EnrollmentConfirmationReq\")\n\t}\n\n\tenrollmentKey, err := DeriveEnrollmentKeyWithClientAndServerRandom(p.primaryKey,\n\t\treq.CarrierTlsConnectionClientRandom, req.CarrierTlsConnectionServerRandom)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to derive enrollment key\").Base(err).AtError()\n\t}\n\n\tif conn, ok := p.activeConnections.Load(string(enrollmentKey.EnrollmentRequestKey)); ok {\n\t\tinsertableConn, ok := conn.(tlsmirror.InsertableTLSConnForEnrollment)\n\t\tif !ok {\n\t\t\treturn nil, newError(\"connection does not implement InsertableTLSConnForEnrollment\")\n\t\t}\n\n\t\treturn insertableConn.VerifyConnectionEnrollment(req)\n\t}\n\n\treturn &tlsmirror.EnrollmentConfirmationResp{\n\t\tEnrolled: false,\n\t}, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/ciphersuits_lookup.go",
    "content": "package server\n\nfunc newEmptyCipherSuiteLookuper() *ciphersuiteLookuper {\n\treturn &ciphersuiteLookuper{\n\t\tciphersuiteMap: make(map[uint16]bool),\n\t}\n}\n\nfunc newCipherSuiteLookuperFromUint32Array(source []uint32) (*ciphersuiteLookuper, error) {\n\tif len(source) == 0 {\n\t\treturn nil, newError(\"ciphersuite list is empty\")\n\t}\n\tciphersuiteUint16Array := make([]uint16, len(source))\n\tfor i, ciphersuite := range source {\n\t\tif ciphersuite > 0xFFFF {\n\t\t\treturn nil, newError(\"ciphersuite value out of range: \", ciphersuite)\n\t\t}\n\t\tciphersuiteUint16Array[i] = uint16(ciphersuite)\n\t}\n\treturn newCipherSuiteLookuperFromUint16Array(ciphersuiteUint16Array), nil\n}\n\nfunc newCipherSuiteLookuperFromUint16Array(source []uint16) *ciphersuiteLookuper {\n\tciphersuiteMap := make(map[uint16]bool, len(source))\n\tfor _, ciphersuite := range source {\n\t\tciphersuiteMap[ciphersuite] = true\n\t}\n\treturn &ciphersuiteLookuper{\n\t\tciphersuiteMap: ciphersuiteMap,\n\t}\n}\n\ntype ciphersuiteLookuper struct {\n\tciphersuiteMap map[uint16]bool\n}\n\nfunc (l *ciphersuiteLookuper) Lookup(ciphersuite uint16) bool {\n\tif result, ok := l.ciphersuiteMap[ciphersuite]; ok {\n\t\treturn result\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/client.go",
    "content": "package server\n\nimport (\n\t\"context\"\n\tcryptoRand \"crypto/rand\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/golang/protobuf/proto\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorbase\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/tlstrafficgen\"\n)\n\nfunc newPersistentMirrorTLSDialer(ctx context.Context, config *Config, serverAddress net.Destination, overrideSecuritySetting proto.Message) (*persistentMirrorTLSDialer, error) {\n\tpersistentDialer := &persistentMirrorTLSDialer{\n\t\tctx:                        ctx,\n\t\tserverAddress:              serverAddress,\n\t\toverridingSecuritySettings: overrideSecuritySetting,\n\t}\n\n\terr := persistentDialer.init(ctx, config)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to initialize persistent mirror TLS dialer\").Base(err)\n\t}\n\n\treturn persistentDialer, nil\n}\n\ntype persistentMirrorTLSDialer struct {\n\tctx context.Context\n\n\tconfig *Config\n\n\trequestNewConnection func(ctx context.Context) error\n\tincomingConnections  chan net.Conn\n\n\tlistener *OutboundListener\n\toutbound *Outbound\n\n\tserverAddress              net.Destination\n\toverridingSecuritySettings proto.Message\n\n\ttrafficGenerator *tlstrafficgen.TrafficGenerator\n\n\tobm outbound.Manager\n\n\texplicitNonceCiphersuiteLookup *ciphersuiteLookuper\n\n\tenrollmentConfirmationClient *mirrorenrollment.EnrollmentConfirmationClient\n\n\tenrollmentServerIdentifier []byte\n}\n\nfunc (d *persistentMirrorTLSDialer) init(ctx context.Context, config *Config) error {\n\tif err := core.RequireFeatures(ctx, func(om outbound.Manager) {\n\t\td.obm = om\n\t}); err != nil {\n\t\treturn err\n\t}\n\n\td.requestNewConnection = func(ctx context.Context) error {\n\t\treturn nil\n\t}\n\n\td.ctx = ctx\n\td.config = config\n\n\td.incomingConnections = make(chan net.Conn, 4)\n\td.listener = NewOutboundListener()\n\td.outbound = NewOutbound(d.config.CarrierConnectionTag, d.listener)\n\n\tif len(d.config.ExplicitNonceCiphersuites) > 0 {\n\t\tvar err error\n\t\td.explicitNonceCiphersuiteLookup, err = newCipherSuiteLookuperFromUint32Array(d.config.ExplicitNonceCiphersuites)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create explicit nonce ciphersuite lookuper\").Base(err)\n\t\t}\n\t} else {\n\t\td.explicitNonceCiphersuiteLookup = newEmptyCipherSuiteLookuper()\n\t\tnewError(\"no explicit nonce ciphersuites configured, all ciphersuites will be treated as non-explicit nonce\").AtWarning().WriteToLog()\n\t}\n\n\tgo func() {\n\t\terr := d.outbound.Start()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to start outbound listener\").Base(err).AtWarning().WriteToLog()\n\t\t\treturn\n\t\t}\n\n\t\tif err := d.obm.RemoveHandler(context.Background(), d.config.CarrierConnectionTag); err != nil {\n\t\t\tnewError(\"failed to remove existing handler\").WriteToLog()\n\t\t}\n\n\t\terr = d.obm.AddHandler(context.Background(), d.outbound)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to add outbound handler\").Base(err).AtWarning().WriteToLog()\n\t\t\treturn\n\t\t}\n\n\t\tfor {\n\t\t\tvar ctx context.Context\n\t\t\tconn, err := d.listener.Accept()\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif ctxGetter, ok := conn.(connectionContextGetter); ok {\n\t\t\t\tctx = ctxGetter.GetConnectionContext()\n\t\t\t} else {\n\t\t\t\tctx = d.ctx\n\t\t\t\tnewError(\"connection does not implement connectionContextGetter, using default context\").AtError().WriteToLog()\n\t\t\t}\n\t\t\td.handleIncomingCarrierConnection(ctx, conn)\n\t\t}\n\t}()\n\n\tif d.config.EmbeddedTrafficGenerator != nil {\n\t\tif d.overridingSecuritySettings != nil && d.config.EmbeddedTrafficGenerator.SecuritySettings == nil {\n\t\t\td.config.EmbeddedTrafficGenerator.SecuritySettings = serial.ToTypedMessage(d.overridingSecuritySettings)\n\t\t}\n\t\td.trafficGenerator = tlstrafficgen.NewTrafficGenerator(d.ctx, d.config.EmbeddedTrafficGenerator,\n\t\t\td.serverAddress, d.config.CarrierConnectionTag)\n\n\t\td.requestNewConnection = func(ctx context.Context) error {\n\t\t\tgo func() {\n\t\t\t\terr := d.trafficGenerator.GenerateNextTraffic(d.ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to generate next traffic\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t} else {\n\t\t\t\t\tnewError(\"traffic generation request sent\").AtDebug().WriteToLog()\n\t\t\t\t}\n\t\t\t}()\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tif d.config.ConnectionEnrolment != nil {\n\t\tenrollmentServerIdentifier, err := mirrorenrollment.DeriveEnrollmentServerIdentifier(d.config.PrimaryKey)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to derive enrollment server identifier\").Base(err).AtError()\n\t\t}\n\t\td.enrollmentServerIdentifier = enrollmentServerIdentifier\n\t\td.enrollmentConfirmationClient, err = mirrorenrollment.NewEnrollmentConfirmationClient(d.ctx, d.config.ConnectionEnrolment, enrollmentServerIdentifier)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create enrollment confirmation client\").Base(err).AtError()\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (d *persistentMirrorTLSDialer) handleIncomingCarrierConnection(ctx context.Context, conn net.Conn) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(d.ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.OutboundDialer()\n\n\tforwardConn, err := dialer(d.ctx, d.serverAddress, d.config.ForwardTag)\n\tif err != nil {\n\t\tnewError(\"failed to dial to destination\").Base(err).AtWarning().WriteToLog()\n\t\treturn\n\t}\n\n\tvar firstWriteDelay time.Duration\n\tif d.config.DeferInstanceDerivedWriteTime != nil {\n\t\tfirstWriteDelay = time.Duration(d.config.DeferInstanceDerivedWriteTime.BaseNanoseconds)\n\t\tif d.config.DeferInstanceDerivedWriteTime.UniformRandomMultiplierNanoseconds > 0 {\n\t\t\tuniformRandomAdd := big.NewInt(int64(d.config.DeferInstanceDerivedWriteTime.UniformRandomMultiplierNanoseconds))\n\t\t\tuniformRandomAddBigInt, err := cryptoRand.Int(cryptoRand.Reader, uniformRandomAdd)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to generate random delay\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tuniformRandomAddU64 := uint64(uniformRandomAddBigInt.Int64())\n\t\t\tfirstWriteDelay += time.Duration(uniformRandomAddU64)\n\t\t}\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\tcconnState := &clientConnState{\n\t\tctx:                      ctx,\n\t\tdone:                     cancel,\n\t\tlocalAddr:                conn.LocalAddr(),\n\t\tremoteAddr:               conn.RemoteAddr(),\n\t\thandler:                  d.handleIncomingReadyConnection,\n\t\tprimaryKey:               d.config.PrimaryKey,\n\t\treadPipe:                 make(chan []byte, 1),\n\t\tfirstWrite:               true,\n\t\tfirstWriteDelay:          firstWriteDelay,\n\t\ttransportLayerPadding:    d.config.TransportLayerPadding,\n\t\tsequenceWatermarkEnabled: d.config.SequenceWatermarkingEnabled,\n\t}\n\n\tcconnState.mirrorConn = mirrorbase.NewMirroredTLSConn(ctx, conn, forwardConn, cconnState.onC2SMessage, cconnState.onS2CMessage, conn,\n\t\td.explicitNonceCiphersuiteLookup.Lookup, cconnState.onC2SMessageTx, cconnState.onS2CMessageTx)\n}\n\ntype connectionContextGetter interface {\n\tGetConnectionContext() context.Context\n}\n\ntype verifyConnectionEnrollment interface {\n\tVerifyConnectionEnrollmentWithProcessor(connectionEnrollmentConfirmationClient tlsmirror.ConnectionEnrollmentConfirmation) error\n}\n\nfunc (d *persistentMirrorTLSDialer) handleIncomingReadyConnection(conn internet.Connection) {\n\tgo func() {\n\t\tif d.config.ConnectionEnrolment != nil {\n\t\t\tif enrollableConn, ok := conn.(verifyConnectionEnrollment); ok {\n\t\t\t\tif d.enrollmentConfirmationClient != nil {\n\t\t\t\t\terr := enrollableConn.VerifyConnectionEnrollmentWithProcessor(d.enrollmentConfirmationClient)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tnewError(\"failed to verify connection enrollment\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnewError(\"enrollment confirmation client is not set, connection rejected\").AtWarning().WriteToLog()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewError(\"connection does not implement verifyConnectionEnrollment, connection rejected\").AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tvar waitedForReady bool\n\t\tif getter, ok := conn.(connectionContextGetter); ok {\n\t\t\tctx := getter.GetConnectionContext()\n\n\t\t\tif managedConnectionController := ctx.Value(tlsmirror.TrafficGeneratorManagedConnectionContextKey); managedConnectionController != nil {\n\t\t\t\tif controller, ok := managedConnectionController.(tlsmirror.TrafficGeneratorManagedConnection); ok {\n\t\t\t\t\tselect { // nolint: staticcheck\n\t\t\t\t\tcase <-controller.WaitConnectionReady().Done():\n\t\t\t\t\t\twaitedForReady = true\n\t\t\t\t\t\t// TODO: connection might become invalid and never ready, handle this case\n\t\t\t\t\t\tif controller.IsConnectionInvalidated() {\n\t\t\t\t\t\t\tnewError(\"connection is invalidated, skipping\").AtWarning().WriteToLog()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\tcase <-ctx.Done():\n\t\t\t\t\t\treturn\n\t\t\t\t\tcase <-d.ctx.Done():\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\tif !waitedForReady {\n\t\t\tnewError(\"unable to wait for connection ready, please verify your setup\").AtWarning().WriteToLog()\n\t\t}\n\t\td.incomingConnections <- conn\n\t}()\n}\n\nfunc (d *persistentMirrorTLSDialer) Dial(ctx context.Context,\n\tdest net.Destination, settings *internet.MemoryStreamConfig,\n) (internet.Connection, error) {\n\tif len(d.enrollmentServerIdentifier) > 0 {\n\t\tif mirrorcommon.IsLoopbackProtectionEnabled(ctx, d.enrollmentServerIdentifier) {\n\t\t\treturn nil, newError(\"loopback protection: refusing to dial to self\")\n\t\t}\n\t}\n\n\tvar recvConn net.Conn\n\tselect {\n\tcase conn := <-d.incomingConnections:\n\t\trecvConn = conn\n\tdefault:\n\t\terr := d.requestNewConnection(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to request new connection\").Base(err)\n\t\t}\n\t\ttimer := time.NewTimer(10 * time.Second)\n\t\tdefer timer.Stop()\n\t\tselect { // nolint: staticcheck\n\t\tcase conn := <-d.incomingConnections:\n\t\t\trecvConn = conn\n\t\tcase <-timer.C:\n\t\t\treturn nil, newError(\"timeout waiting for incoming connection\")\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, newError(\"context done while waiting for incoming connection\")\n\t\t}\n\t}\n\n\tif recvConn == nil {\n\t\treturn nil, newError(\"failed to receive connection\")\n\t}\n\n\treturn recvConn, nil\n}\n\nfunc Dial(ctx context.Context, dest net.Destination, settings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tdialer, err := transportEnvironment.TransientStorage().Get(ctx, \"persistentDialer\")\n\tif err != nil {\n\t\tvar securitySetting proto.Message\n\t\tif settings.SecurityType != \"\" && settings.SecurityType != \"none\" {\n\t\t\tsecuritySetting = settings.SecuritySettings.(proto.Message)\n\t\t}\n\t\tconfig := settings.ProtocolSettings.(*Config)\n\t\tdetachedContext := core.ToBackgroundDetachedContext(ctx)\n\t\tdialer, err = newPersistentMirrorTLSDialer(detachedContext, config, dest, securitySetting)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to create persistent mirror TLS dialer\").Base(err)\n\t\t}\n\t\terr = transportEnvironment.TransientStorage().Put(ctx, \"persistentDialer\", dialer)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to put persistent dialer\").Base(err)\n\t\t}\n\t}\n\tconn, err := dialer.(*persistentMirrorTLSDialer).Dial(ctx, dest, settings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial\").Base(err)\n\t}\n\treturn conn, nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/client_conn.go",
    "content": "package server\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/cipher\"\n\tgonet \"net\"\n\t\"time\"\n\n\t\"golang.org/x/crypto/chacha20\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcrypto\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\"\n)\n\ntype clientConnState struct {\n\tctx     context.Context\n\tdone    context.CancelFunc\n\thandler internet.ConnHandler\n\n\tmirrorConn tlsmirror.InsertableTLSConn\n\tlocalAddr  net.Addr\n\tremoteAddr net.Addr\n\n\tactivated bool\n\tdecryptor *mirrorcrypto.Decryptor\n\tencryptor *mirrorcrypto.Encryptor\n\n\tprimaryKey []byte\n\n\treadPipe   chan []byte\n\treadBuffer *bytes.Buffer\n\n\tprotocolVersion [2]byte\n\n\tfirstWrite      bool\n\tfirstWriteDelay time.Duration\n\n\ttransportLayerPadding *TransportLayerPadding\n\n\tsequenceWatermarkEnabled                 bool\n\tsequenceWatermarkTx, sequenceWatermarkRx cipher.Stream\n}\n\nfunc (s *clientConnState) GetConnectionContext() context.Context {\n\treturn s.ctx\n}\n\nfunc (s *clientConnState) Read(b []byte) (n int, err error) {\n\tif s.readBuffer != nil {\n\t\tn, _ = s.readBuffer.Read(b)\n\t\tif n > 0 {\n\t\t\treturn n, nil\n\t\t}\n\t\ts.readBuffer = nil\n\t}\n\n\tselect {\n\tcase <-s.ctx.Done():\n\t\treturn 0, s.ctx.Err()\n\tcase data := <-s.readPipe:\n\t\tif s.transportLayerPadding != nil && s.transportLayerPadding.Enabled {\n\t\t\tvar padding int\n\t\t\tdata, padding = Unpack(data)\n\t\t\t_ = padding\n\t\t\tif data == nil {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\t\t}\n\t\ts.readBuffer = bytes.NewBuffer(data)\n\t\tn, err = s.readBuffer.Read(b)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn n, nil\n\t}\n}\n\nfunc (s *clientConnState) Write(b []byte) (n int, err error) {\n\tpayloadSize := len(b)\n\tif s.firstWrite && s.firstWriteDelay > 0 {\n\t\tfirstWriteDelayTimer := time.NewTimer(s.firstWriteDelay)\n\t\tdefer firstWriteDelayTimer.Stop()\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn 0, s.ctx.Err()\n\t\tcase <-firstWriteDelayTimer.C:\n\t\t\ts.firstWrite = false\n\t\t}\n\t}\n\tif s.transportLayerPadding != nil && s.transportLayerPadding.Enabled {\n\t\tb = Pack(bytes.Clone(b), 0)\n\t}\n\terr = s.WriteMessage(b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn = payloadSize\n\treturn n, nil\n}\n\nfunc (s *clientConnState) Close() error {\n\t// TODO: Only recall the connection, not close it.\n\ts.done()\n\treturn nil\n}\n\nfunc (s *clientConnState) LocalAddr() gonet.Addr {\n\treturn s.remoteAddr\n}\n\nfunc (s *clientConnState) RemoteAddr() gonet.Addr {\n\treturn s.remoteAddr\n}\n\nfunc (s *clientConnState) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (s *clientConnState) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (s *clientConnState) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (s *clientConnState) onC2SMessage(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\tif message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data {\n\t\tif s.decryptor == nil {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn false, nil\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tencryptionKey, nonceMask, err := mirrorcrypto.DeriveEncryptionKey(s.primaryKey, clientRandom, serverRandom, \":s2c\")\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to derive C2S encryption key\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\treturn false, nil\n\t\t\t\t}\n\t\t\t\ts.decryptor = mirrorcrypto.NewDecryptor(encryptionKey, nonceMask)\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tencryptionKey, nonceMask, err := mirrorcrypto.DeriveEncryptionKey(s.primaryKey, clientRandom, serverRandom, \":c2s\")\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to derive S2C encryption key\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\treturn false, nil\n\t\t\t\t}\n\t\t\t\ts.encryptor = mirrorcrypto.NewEncryptor(encryptionKey, nonceMask)\n\t\t\t}\n\t\t\ts.protocolVersion = message.LegacyProtocolVersion\n\n\t\t\tif !s.activated {\n\t\t\t\ts.handler(s)\n\t\t\t\ts.activated = true\n\t\t\t}\n\t\t}\n\t}\n\treturn false, ok\n}\n\nfunc (s *clientConnState) onS2CMessage(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\tif s.sequenceWatermarkEnabled {\n\t\tif s.sequenceWatermarkRx != nil {\n\t\t\tif (message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data ||\n\t\t\t\tmessage.RecordType == mirrorcommon.TLSRecord_RecordType_alert) && len(message.Fragment) >= 16 {\n\t\t\t\twatermarkRegion := message.Fragment[len(message.Fragment)-16:]\n\t\t\t\ts.sequenceWatermarkRx.XORKeyStream(watermarkRegion, watermarkRegion)\n\t\t\t}\n\t\t}\n\t}\n\n\tif message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data {\n\t\texplicitNonceReservedOverheadHeaderLength, err := s.mirrorConn.GetApplicationDataExplicitNonceReservedOverheadHeaderLength()\n\t\tif err != nil {\n\t\t\treturn false, newError(\"failed to get explicit nonce reserved overhead header length\").Base(err)\n\t\t}\n\n\t\tif s.encryptor == nil {\n\t\t\treturn false, nil\n\t\t}\n\t\tbuffer := make([]byte, 0, len(message.Fragment)-s.encryptor.NonceSize()-explicitNonceReservedOverheadHeaderLength)\n\t\tbuffer, err = s.decryptor.Open(buffer, message.Fragment[explicitNonceReservedOverheadHeaderLength:])\n\t\tif err != nil {\n\t\t\treturn false, nil\n\t\t}\n\n\t\tif s.sequenceWatermarkEnabled && s.sequenceWatermarkRx == nil {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\tkey, nonce, err := mirrorcrypto.DeriveSequenceWatermarkingKey(s.primaryKey, clientRandom, serverRandom, \":s2c\")\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to derive sequence watermarking key\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\ts.sequenceWatermarkRx, err = chacha20.NewUnauthenticatedCipher(key, nonce)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to create sequence watermarking cipher\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\n\t\ts.readPipe <- buffer\n\t\treturn true, nil\n\t}\n\treturn false, ok\n}\n\nfunc (s *clientConnState) WriteMessage(message []byte) error {\n\texplicitNonceReservedOverheadHeaderLength, err := s.mirrorConn.GetApplicationDataExplicitNonceReservedOverheadHeaderLength()\n\tif err != nil {\n\t\treturn newError(\"failed to get explicit nonce reserved overhead header length\").Base(err)\n\t}\n\tbuffer := make([]byte, explicitNonceReservedOverheadHeaderLength, explicitNonceReservedOverheadHeaderLength+len(message)+s.encryptor.NonceSize())\n\tbuffer, err = s.encryptor.Seal(buffer, message)\n\tif err != nil {\n\t\treturn newError(\"failed to encrypt message\").Base(err)\n\t}\n\trecord := tlsmirror.TLSRecord{\n\t\tRecordType:            mirrorcommon.TLSRecord_RecordType_application_data,\n\t\tLegacyProtocolVersion: s.protocolVersion,\n\t\tRecordLength:          uint16(len(buffer)),\n\t\tFragment:              buffer,\n\t\tInsertedMessage:       true,\n\t}\n\treturn s.mirrorConn.InsertC2SMessage(&record)\n}\n\nfunc (s *clientConnState) VerifyConnectionEnrollmentWithProcessor(connectionEnrollmentConfirmationClient tlsmirror.ConnectionEnrollmentConfirmation) error {\n\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\tif err != nil {\n\t\treturn newError(\"failed to get handshake random\").Base(err).AtWarning()\n\t}\n\n\tenrollmentServerIdentity, err := mirrorenrollment.DeriveEnrollmentServerIdentifier(s.primaryKey)\n\tif err != nil {\n\t\treturn newError(\"failed to derive enrollment server identifier\").Base(err).AtError()\n\t}\n\n\tenrollmentReq := &tlsmirror.EnrollmentConfirmationReq{\n\t\tServerIdentifier:                 enrollmentServerIdentity,\n\t\tCarrierTlsConnectionClientRandom: clientRandom,\n\t\tCarrierTlsConnectionServerRandom: serverRandom,\n\t}\n\tresp, err := connectionEnrollmentConfirmationClient.VerifyConnectionEnrollment(enrollmentReq)\n\tif err != nil {\n\t\treturn newError(\"failed to verify connection enrollment\").Base(err).AtError()\n\t}\n\tif resp == nil {\n\t\treturn newError(\"nil EnrollmentConfirmationResp\")\n\t}\n\tif resp.Enrolled {\n\t\tnewError(\"connection enrolled successfully\").AtInfo().WriteToLog()\n\t} else {\n\t\treturn newError(\"connection enrollment failed\")\n\t}\n\treturn nil\n}\n\nfunc (s *clientConnState) onC2SMessageTx(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\tif s.sequenceWatermarkEnabled {\n\t\tif s.sequenceWatermarkTx != nil {\n\t\t\tif (message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data ||\n\t\t\t\tmessage.RecordType == mirrorcommon.TLSRecord_RecordType_alert) && len(message.Fragment) >= 16 {\n\t\t\t\twatermarkRegion := message.Fragment[len(message.Fragment)-16:]\n\t\t\t\ts.sequenceWatermarkTx.XORKeyStream(watermarkRegion, watermarkRegion)\n\t\t\t}\n\t\t}\n\t\tif message.InsertedMessage && s.sequenceWatermarkTx == nil {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\tkey, nonce, err := mirrorcrypto.DeriveSequenceWatermarkingKey(s.primaryKey, clientRandom, serverRandom, \":c2s\")\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to derive sequence watermarking key\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\ts.sequenceWatermarkTx, err = chacha20.NewUnauthenticatedCipher(key, nonce)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to create sequence watermarking cipher\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc (s *clientConnState) onS2CMessageTx(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\treturn false, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/config.pb.go",
    "content": "package server\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tmirrorenrollment \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\"\n\ttlstrafficgen \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/tlstrafficgen\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 TimeSpec struct {\n\tstate                              protoimpl.MessageState `protogen:\"open.v1\"`\n\tBaseNanoseconds                    uint64                 `protobuf:\"varint,1,opt,name=base_nanoseconds,json=baseNanoseconds,proto3\" json:\"base_nanoseconds,omitempty\"`\n\tUniformRandomMultiplierNanoseconds uint64                 `protobuf:\"varint,2,opt,name=uniform_random_multiplier_nanoseconds,json=uniformRandomMultiplierNanoseconds,proto3\" json:\"uniform_random_multiplier_nanoseconds,omitempty\"`\n\tunknownFields                      protoimpl.UnknownFields\n\tsizeCache                          protoimpl.SizeCache\n}\n\nfunc (x *TimeSpec) Reset() {\n\t*x = TimeSpec{}\n\tmi := &file_transport_internet_tlsmirror_server_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TimeSpec) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TimeSpec) ProtoMessage() {}\n\nfunc (x *TimeSpec) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_server_config_proto_msgTypes[0]\n\tif 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 TimeSpec.ProtoReflect.Descriptor instead.\nfunc (*TimeSpec) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_server_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *TimeSpec) GetBaseNanoseconds() uint64 {\n\tif x != nil {\n\t\treturn x.BaseNanoseconds\n\t}\n\treturn 0\n}\n\nfunc (x *TimeSpec) GetUniformRandomMultiplierNanoseconds() uint64 {\n\tif x != nil {\n\t\treturn x.UniformRandomMultiplierNanoseconds\n\t}\n\treturn 0\n}\n\ntype TransportLayerPadding struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tEnabled       bool                   `protobuf:\"varint,1,opt,name=enabled,proto3\" json:\"enabled,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *TransportLayerPadding) Reset() {\n\t*x = TransportLayerPadding{}\n\tmi := &file_transport_internet_tlsmirror_server_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TransportLayerPadding) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TransportLayerPadding) ProtoMessage() {}\n\nfunc (x *TransportLayerPadding) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_server_config_proto_msgTypes[1]\n\tif 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 TransportLayerPadding.ProtoReflect.Descriptor instead.\nfunc (*TransportLayerPadding) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_server_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *TransportLayerPadding) GetEnabled() bool {\n\tif x != nil {\n\t\treturn x.Enabled\n\t}\n\treturn false\n}\n\ntype Config struct {\n\tstate                         protoimpl.MessageState   `protogen:\"open.v1\"`\n\tForwardAddress                string                   `protobuf:\"bytes,1,opt,name=forward_address,json=forwardAddress,proto3\" json:\"forward_address,omitempty\"`\n\tForwardPort                   uint32                   `protobuf:\"varint,2,opt,name=forward_port,json=forwardPort,proto3\" json:\"forward_port,omitempty\"`\n\tForwardTag                    string                   `protobuf:\"bytes,3,opt,name=forward_tag,json=forwardTag,proto3\" json:\"forward_tag,omitempty\"`\n\tCarrierConnectionTag          string                   `protobuf:\"bytes,4,opt,name=carrier_connection_tag,json=carrierConnectionTag,proto3\" json:\"carrier_connection_tag,omitempty\"`\n\tEmbeddedTrafficGenerator      *tlstrafficgen.Config    `protobuf:\"bytes,5,opt,name=embedded_traffic_generator,json=embeddedTrafficGenerator,proto3\" json:\"embedded_traffic_generator,omitempty\"`\n\tPrimaryKey                    []byte                   `protobuf:\"bytes,6,opt,name=primary_key,json=primaryKey,proto3\" json:\"primary_key,omitempty\"`\n\tExplicitNonceCiphersuites     []uint32                 `protobuf:\"varint,7,rep,packed,name=explicit_nonce_ciphersuites,json=explicitNonceCiphersuites,proto3\" json:\"explicit_nonce_ciphersuites,omitempty\"`\n\tDeferInstanceDerivedWriteTime *TimeSpec                `protobuf:\"bytes,8,opt,name=defer_instance_derived_write_time,json=deferInstanceDerivedWriteTime,proto3\" json:\"defer_instance_derived_write_time,omitempty\"`\n\tTransportLayerPadding         *TransportLayerPadding   `protobuf:\"bytes,9,opt,name=transport_layer_padding,json=transportLayerPadding,proto3\" json:\"transport_layer_padding,omitempty\"`\n\tConnectionEnrolment           *mirrorenrollment.Config `protobuf:\"bytes,10,opt,name=connection_enrolment,json=connectionEnrolment,proto3\" json:\"connection_enrolment,omitempty\"`\n\tSequenceWatermarkingEnabled   bool                     `protobuf:\"varint,11,opt,name=sequence_watermarking_enabled,json=sequenceWatermarkingEnabled,proto3\" json:\"sequence_watermarking_enabled,omitempty\"`\n\tunknownFields                 protoimpl.UnknownFields\n\tsizeCache                     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_tlsmirror_server_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_server_config_proto_msgTypes[2]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_server_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *Config) GetForwardAddress() string {\n\tif x != nil {\n\t\treturn x.ForwardAddress\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetForwardPort() uint32 {\n\tif x != nil {\n\t\treturn x.ForwardPort\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetForwardTag() string {\n\tif x != nil {\n\t\treturn x.ForwardTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetCarrierConnectionTag() string {\n\tif x != nil {\n\t\treturn x.CarrierConnectionTag\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetEmbeddedTrafficGenerator() *tlstrafficgen.Config {\n\tif x != nil {\n\t\treturn x.EmbeddedTrafficGenerator\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetPrimaryKey() []byte {\n\tif x != nil {\n\t\treturn x.PrimaryKey\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetExplicitNonceCiphersuites() []uint32 {\n\tif x != nil {\n\t\treturn x.ExplicitNonceCiphersuites\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetDeferInstanceDerivedWriteTime() *TimeSpec {\n\tif x != nil {\n\t\treturn x.DeferInstanceDerivedWriteTime\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetTransportLayerPadding() *TransportLayerPadding {\n\tif x != nil {\n\t\treturn x.TransportLayerPadding\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetConnectionEnrolment() *mirrorenrollment.Config {\n\tif x != nil {\n\t\treturn x.ConnectionEnrolment\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetSequenceWatermarkingEnabled() bool {\n\tif x != nil {\n\t\treturn x.SequenceWatermarkingEnabled\n\t}\n\treturn false\n}\n\nvar File_transport_internet_tlsmirror_server_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tlsmirror_server_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"0transport/internet/tlsmirror/server/config.proto\\x12.v2ray.core.transport.internet.tlsmirror.server\\x1a common/protoext/extensions.proto\\x1a7transport/internet/tlsmirror/tlstrafficgen/config.proto\\x1a:transport/internet/tlsmirror/mirrorenrollment/config.proto\\\"\\x88\\x01\\n\" +\n\t\"\\bTimeSpec\\x12)\\n\" +\n\t\"\\x10base_nanoseconds\\x18\\x01 \\x01(\\x04R\\x0fbaseNanoseconds\\x12Q\\n\" +\n\t\"%uniform_random_multiplier_nanoseconds\\x18\\x02 \\x01(\\x04R\\\"uniformRandomMultiplierNanoseconds\\\"1\\n\" +\n\t\"\\x15TransportLayerPadding\\x12\\x18\\n\" +\n\t\"\\aenabled\\x18\\x01 \\x01(\\bR\\aenabled\\\"\\xef\\x06\\n\" +\n\t\"\\x06Config\\x12'\\n\" +\n\t\"\\x0fforward_address\\x18\\x01 \\x01(\\tR\\x0eforwardAddress\\x12!\\n\" +\n\t\"\\fforward_port\\x18\\x02 \\x01(\\rR\\vforwardPort\\x12\\x1f\\n\" +\n\t\"\\vforward_tag\\x18\\x03 \\x01(\\tR\\n\" +\n\t\"forwardTag\\x124\\n\" +\n\t\"\\x16carrier_connection_tag\\x18\\x04 \\x01(\\tR\\x14carrierConnectionTag\\x12{\\n\" +\n\t\"\\x1aembedded_traffic_generator\\x18\\x05 \\x01(\\v2=.v2ray.core.transport.internet.tlsmirror.tlstrafficgen.ConfigR\\x18embeddedTrafficGenerator\\x12\\x1f\\n\" +\n\t\"\\vprimary_key\\x18\\x06 \\x01(\\fR\\n\" +\n\t\"primaryKey\\x12>\\n\" +\n\t\"\\x1bexplicit_nonce_ciphersuites\\x18\\a \\x03(\\rR\\x19explicitNonceCiphersuites\\x12\\x82\\x01\\n\" +\n\t\"!defer_instance_derived_write_time\\x18\\b \\x01(\\v28.v2ray.core.transport.internet.tlsmirror.server.TimeSpecR\\x1ddeferInstanceDerivedWriteTime\\x12}\\n\" +\n\t\"\\x17transport_layer_padding\\x18\\t \\x01(\\v2E.v2ray.core.transport.internet.tlsmirror.server.TransportLayerPaddingR\\x15transportLayerPadding\\x12s\\n\" +\n\t\"\\x14connection_enrolment\\x18\\n\" +\n\t\" \\x01(\\v2@.v2ray.core.transport.internet.tlsmirror.mirrorenrollment.ConfigR\\x13connectionEnrolment\\x12B\\n\" +\n\t\"\\x1dsequence_watermarking_enabled\\x18\\v \\x01(\\bR\\x1bsequenceWatermarkingEnabled:'\\x82\\xb5\\x18#\\n\" +\n\t\"\\ttransport\\x12\\ttlsmirror\\x8a\\xff)\\ttlsmirrorB\\xab\\x01\\n\" +\n\t\"2com.v2ray.core.transport.internet.tlsmirror.serverP\\x01ZBgithub.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/server\\xaa\\x02.V2Ray.Core.Transport.Internet.Tlsmirror.Serverb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tlsmirror_server_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tlsmirror_server_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tlsmirror_server_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tlsmirror_server_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tlsmirror_server_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_server_config_proto_rawDesc), len(file_transport_internet_tlsmirror_server_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tlsmirror_server_config_proto_rawDescData\n}\n\nvar file_transport_internet_tlsmirror_server_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_transport_internet_tlsmirror_server_config_proto_goTypes = []any{\n\t(*TimeSpec)(nil),                // 0: v2ray.core.transport.internet.tlsmirror.server.TimeSpec\n\t(*TransportLayerPadding)(nil),   // 1: v2ray.core.transport.internet.tlsmirror.server.TransportLayerPadding\n\t(*Config)(nil),                  // 2: v2ray.core.transport.internet.tlsmirror.server.Config\n\t(*tlstrafficgen.Config)(nil),    // 3: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Config\n\t(*mirrorenrollment.Config)(nil), // 4: v2ray.core.transport.internet.tlsmirror.mirrorenrollment.Config\n}\nvar file_transport_internet_tlsmirror_server_config_proto_depIdxs = []int32{\n\t3, // 0: v2ray.core.transport.internet.tlsmirror.server.Config.embedded_traffic_generator:type_name -> v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Config\n\t0, // 1: v2ray.core.transport.internet.tlsmirror.server.Config.defer_instance_derived_write_time:type_name -> v2ray.core.transport.internet.tlsmirror.server.TimeSpec\n\t1, // 2: v2ray.core.transport.internet.tlsmirror.server.Config.transport_layer_padding:type_name -> v2ray.core.transport.internet.tlsmirror.server.TransportLayerPadding\n\t4, // 3: v2ray.core.transport.internet.tlsmirror.server.Config.connection_enrolment:type_name -> v2ray.core.transport.internet.tlsmirror.mirrorenrollment.Config\n\t4, // [4:4] is the sub-list for method output_type\n\t4, // [4:4] is the sub-list for method input_type\n\t4, // [4:4] is the sub-list for extension type_name\n\t4, // [4:4] is the sub-list for extension extendee\n\t0, // [0:4] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_tlsmirror_server_config_proto_init() }\nfunc file_transport_internet_tlsmirror_server_config_proto_init() {\n\tif File_transport_internet_tlsmirror_server_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_server_config_proto_rawDesc), len(file_transport_internet_tlsmirror_server_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tlsmirror_server_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tlsmirror_server_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_tlsmirror_server_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tlsmirror_server_config_proto = out.File\n\tfile_transport_internet_tlsmirror_server_config_proto_goTypes = nil\n\tfile_transport_internet_tlsmirror_server_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tlsmirror.server;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tlsmirror.Server\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/server\";\noption java_package = \"com.v2ray.core.transport.internet.tlsmirror.server\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\nimport \"transport/internet/tlsmirror/tlstrafficgen/config.proto\";\nimport \"transport/internet/tlsmirror/mirrorenrollment/config.proto\";\n\nmessage TimeSpec {\n  uint64 base_nanoseconds = 1;\n  uint64 uniform_random_multiplier_nanoseconds = 2;\n}\n\nmessage TransportLayerPadding {\n  bool enabled = 1;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"tlsmirror\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = false;\n\n  option (v2ray.core.common.protoext.message_opt).transport_original_name = \"tlsmirror\";\n\n  string forward_address = 1;\n  uint32 forward_port = 2;\n  string forward_tag = 3;\n\n  string carrier_connection_tag = 4;\n\n  v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Config embedded_traffic_generator = 5;\n\n  bytes primary_key = 6;\n\n  repeated uint32 explicit_nonce_ciphersuites = 7;\n\n  TimeSpec defer_instance_derived_write_time = 8;\n\n  TransportLayerPadding transport_layer_padding = 9;\n\n  v2ray.core.transport.internet.tlsmirror.mirrorenrollment.Config connection_enrolment = 10;\n\n  bool sequence_watermarking_enabled = 11;\n\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/conn.go",
    "content": "package server\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/cipher\"\n\t\"net\"\n\t\"time\"\n\n\t\"golang.org/x/crypto/chacha20\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcommon\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorcrypto\"\n)\n\ntype connState struct {\n\tctx     context.Context\n\tdone    context.CancelFunc\n\thandler internet.ConnHandler\n\n\tmirrorConn tlsmirror.InsertableTLSConn\n\tlocalAddr  net.Addr\n\tremoteAddr net.Addr\n\n\tactivated bool\n\tdecryptor *mirrorcrypto.Decryptor\n\tencryptor *mirrorcrypto.Encryptor\n\n\tprimaryKey []byte\n\n\treadPipe   chan []byte\n\treadBuffer *bytes.Buffer\n\n\tprotocolVersion [2]byte\n\n\tfirstWrite      bool\n\tfirstWriteDelay time.Duration\n\n\ttransportLayerPadding *TransportLayerPadding\n\n\tconnectionEnrollmentEnabled           bool\n\tconnectionEnrollmentProcessorEnrolled bool\n\tconnectionEnrollmentProcessor         tlsmirror.ConnectionEnrollmentConfirmationProcessor\n\tconnectionEnrollmentRemover           tlsmirror.RemoveConnectionFunc\n\n\tsequenceWatermarkEnabled                 bool\n\tsequenceWatermarkTx, sequenceWatermarkRx cipher.Stream\n}\n\nfunc (s *connState) VerifyConnectionEnrollment(req *tlsmirror.EnrollmentConfirmationReq) (*tlsmirror.EnrollmentConfirmationResp, error) {\n\treturn &tlsmirror.EnrollmentConfirmationResp{Enrolled: true}, nil\n}\n\nfunc (s *connState) Read(b []byte) (n int, err error) {\n\tif s.readBuffer != nil {\n\t\tn, _ = s.readBuffer.Read(b)\n\t\tif n > 0 {\n\t\t\treturn n, nil\n\t\t}\n\t\ts.readBuffer = nil\n\t}\n\n\tselect {\n\tcase <-s.ctx.Done():\n\t\treturn 0, s.ctx.Err()\n\tcase data := <-s.readPipe:\n\t\tif s.transportLayerPadding != nil && s.transportLayerPadding.Enabled {\n\t\t\tvar padding int\n\t\t\tdata, padding = Unpack(data)\n\t\t\t_ = padding\n\t\t\tif data == nil {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\t\t}\n\t\ts.readBuffer = bytes.NewBuffer(data)\n\t\tn, err = s.readBuffer.Read(b)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn n, nil\n\t}\n}\n\nfunc (s *connState) Write(b []byte) (n int, err error) {\n\tpayloadSize := len(b)\n\tif s.firstWrite && s.firstWriteDelay > 0 {\n\t\tfirstWriteDelayTimer := time.NewTimer(s.firstWriteDelay)\n\t\tdefer firstWriteDelayTimer.Stop()\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn 0, s.ctx.Err()\n\t\tcase <-firstWriteDelayTimer.C:\n\t\t\ts.firstWrite = false\n\t\t}\n\t}\n\tif s.transportLayerPadding != nil && s.transportLayerPadding.Enabled {\n\t\tb = Pack(bytes.Clone(b), 0)\n\t}\n\terr = s.WriteMessage(b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn = payloadSize\n\treturn n, nil\n}\n\nfunc (s *connState) LocalAddr() net.Addr {\n\treturn s.localAddr\n}\n\nfunc (s *connState) RemoteAddr() net.Addr {\n\treturn s.remoteAddr\n}\n\nfunc (s *connState) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (s *connState) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (s *connState) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (s *connState) Close() error {\n\ts.done()\n\tif s.connectionEnrollmentRemover != nil {\n\t\tif err := s.connectionEnrollmentRemover(); err != nil {\n\t\t\tnewError(\"failed to remove connection enrollment\").Base(err).AtWarning().WriteToLog()\n\t\t}\n\t\ts.connectionEnrollmentRemover = nil\n\t}\n\treturn nil\n}\n\nfunc (s *connState) onS2CMessage(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\tif message.RecordType == mirrorcommon.TLSRecord_RecordType_handshake {\n\t\tif s.connectionEnrollmentEnabled && !s.connectionEnrollmentProcessorEnrolled {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn false, nil\n\t\t\t}\n\n\t\t\tremove, err := s.connectionEnrollmentProcessor.AddConnection(s.ctx, clientRandom, serverRandom, s)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to add connection for enrollment\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\ts.connectionEnrollmentRemover = remove\n\t\t\ts.connectionEnrollmentProcessorEnrolled = true\n\t\t\treturn false, nil\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc (s *connState) onC2SMessage(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\tif s.sequenceWatermarkEnabled {\n\t\tif s.sequenceWatermarkRx != nil {\n\t\t\tif (message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data ||\n\t\t\t\tmessage.RecordType == mirrorcommon.TLSRecord_RecordType_alert) && len(message.Fragment) >= 16 {\n\t\t\t\twatermarkRegion := message.Fragment[len(message.Fragment)-16:]\n\t\t\t\ts.sequenceWatermarkRx.XORKeyStream(watermarkRegion, watermarkRegion)\n\t\t\t}\n\t\t}\n\t}\n\n\tif message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data {\n\t\tif s.decryptor == nil {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn false, nil\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tencryptionKey, nonceMask, err := mirrorcrypto.DeriveEncryptionKey(s.primaryKey, clientRandom, serverRandom, \":c2s\")\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to derive C2S encryption key\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\treturn false, nil\n\t\t\t\t}\n\t\t\t\ts.decryptor = mirrorcrypto.NewDecryptor(encryptionKey, nonceMask)\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tencryptionKey, nonceMask, err := mirrorcrypto.DeriveEncryptionKey(s.primaryKey, clientRandom, serverRandom, \":s2c\")\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to derive S2C encryption key\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\treturn false, nil\n\t\t\t\t}\n\t\t\t\ts.encryptor = mirrorcrypto.NewEncryptor(encryptionKey, nonceMask)\n\t\t\t}\n\t\t\ts.protocolVersion = message.LegacyProtocolVersion\n\t\t}\n\n\t\texplicitNonceReservedOverheadHeaderLength, err := s.mirrorConn.GetApplicationDataExplicitNonceReservedOverheadHeaderLength()\n\t\tif err != nil {\n\t\t\treturn false, newError(\"failed to get explicit nonce reserved overhead header length\").Base(err)\n\t\t}\n\n\t\tbuffer := make([]byte, 0, len(message.Fragment)-s.decryptor.NonceSize()-explicitNonceReservedOverheadHeaderLength)\n\t\tbuffer, err = s.decryptor.Open(buffer, message.Fragment[explicitNonceReservedOverheadHeaderLength:])\n\t\tif err != nil {\n\t\t\treturn false, nil\n\t\t}\n\n\t\tif s.sequenceWatermarkEnabled && s.sequenceWatermarkRx == nil {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\tkey, nonce, err := mirrorcrypto.DeriveSequenceWatermarkingKey(s.primaryKey, clientRandom, serverRandom, \":c2s\")\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to derive sequence watermarking key\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\ts.sequenceWatermarkRx, err = chacha20.NewUnauthenticatedCipher(key, nonce)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to create sequence watermarking cipher\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\n\t\tif !s.activated {\n\t\t\ts.handler(s)\n\t\t\ts.activated = true\n\t\t}\n\t\ts.readPipe <- buffer\n\t\treturn true, nil\n\t}\n\treturn false, ok\n}\n\nfunc (s *connState) WriteMessage(message []byte) error {\n\texplicitNonceReservedOverheadHeaderLength, err := s.mirrorConn.GetApplicationDataExplicitNonceReservedOverheadHeaderLength()\n\tif err != nil {\n\t\treturn newError(\"failed to get explicit nonce reserved overhead header length\").Base(err)\n\t}\n\n\tbuffer := make([]byte, explicitNonceReservedOverheadHeaderLength, explicitNonceReservedOverheadHeaderLength+len(message)+s.decryptor.NonceSize())\n\tbuffer, err = s.encryptor.Seal(buffer, message)\n\tif err != nil {\n\t\treturn newError(\"failed to encrypt message\").Base(err)\n\t}\n\trecord := tlsmirror.TLSRecord{\n\t\tRecordType:            mirrorcommon.TLSRecord_RecordType_application_data,\n\t\tLegacyProtocolVersion: s.protocolVersion,\n\t\tRecordLength:          uint16(len(buffer)),\n\t\tFragment:              buffer,\n\t\tInsertedMessage:       true,\n\t}\n\treturn s.mirrorConn.InsertS2CMessage(&record)\n}\n\nfunc (s *connState) onC2SMessageTx(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\treturn false, nil\n}\n\nfunc (s *connState) onS2CMessageTx(message *tlsmirror.TLSRecord) (drop bool, ok error) {\n\tif s.sequenceWatermarkEnabled {\n\t\tif s.sequenceWatermarkTx != nil {\n\t\t\tif (message.RecordType == mirrorcommon.TLSRecord_RecordType_application_data ||\n\t\t\t\tmessage.RecordType == mirrorcommon.TLSRecord_RecordType_alert) && len(message.Fragment) >= 16 {\n\t\t\t\twatermarkRegion := message.Fragment[len(message.Fragment)-16:]\n\t\t\t\ts.sequenceWatermarkTx.XORKeyStream(watermarkRegion, watermarkRegion)\n\t\t\t}\n\t\t}\n\t\tif message.InsertedMessage && s.sequenceWatermarkTx == nil {\n\t\t\tclientRandom, serverRandom, err := s.mirrorConn.GetHandshakeRandom()\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to get handshake random\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\tkey, nonce, err := mirrorcrypto.DeriveSequenceWatermarkingKey(s.primaryKey, clientRandom, serverRandom, \":s2c\")\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to derive sequence watermarking key\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\ts.sequenceWatermarkTx, err = chacha20.NewUnauthenticatedCipher(key, nonce)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to create sequence watermarking cipher\").Base(err).AtError().WriteToLog()\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn false, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/errors.generated.go",
    "content": "package server\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/hub.go",
    "content": "package server\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/transportcommon\"\n)\n\nfunc ListenTLSMirror(ctx context.Context, address net.Address, port net.Port,\n\tstreamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler,\n) (internet.Listener, error) {\n\ttlsMirrorSettings := streamSettings.ProtocolSettings.(*Config)\n\tlistener, err := transportcommon.ListenWithSecuritySettings(ctx, address, port, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to listen TLS mirror\").Base(err)\n\t}\n\n\ttlsMirrorServer, err := NewServer(ctx, listener, tlsMirrorSettings, handler)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to create TLS mirror server\").Base(err)\n\t}\n\n\tgo tlsMirrorServer.accepts()\n\n\treturn tlsMirrorServer, nil\n}\n\nconst protocolName = \"tlsmirror\"\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, ListenTLSMirror))\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/outbound.go",
    "content": "package server\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\nfunc NewOutboundListener() *OutboundListener {\n\treturn &OutboundListener{\n\t\tbuffer: make(chan *connWithContext, 4),\n\t\tdone:   done.New(),\n\t}\n}\n\ntype connWithContext struct {\n\tnet.Conn\n\tctx context.Context\n}\n\nfunc (c *connWithContext) GetConnectionContext() context.Context {\n\treturn c.ctx\n}\n\n// OutboundListener is a net.Listener for listening gRPC connections.\ntype OutboundListener struct {\n\tbuffer chan *connWithContext\n\tdone   *done.Instance\n}\n\nfunc (l *OutboundListener) addWithContext(ctx context.Context, conn net.Conn) {\n\tselect {\n\tcase l.buffer <- &connWithContext{Conn: conn, ctx: ctx}:\n\tcase <-l.done.Wait():\n\t\tconn.Close()\n\tdefault:\n\t\tconn.Close()\n\t}\n}\n\n// Accept implements net.Listener.\nfunc (l *OutboundListener) Accept() (net.Conn, error) {\n\tselect {\n\tcase <-l.done.Wait():\n\t\treturn nil, newError(\"listen closed\")\n\tcase c := <-l.buffer:\n\t\treturn c, nil\n\t}\n}\n\n// Close implement net.Listener.\nfunc (l *OutboundListener) Close() error {\n\tcommon.Must(l.done.Close())\nL:\n\tfor {\n\t\tselect {\n\t\tcase c := <-l.buffer:\n\t\t\tc.Close()\n\t\tdefault:\n\t\t\tbreak L\n\t\t}\n\t}\n\treturn nil\n}\n\n// Addr implements net.Listener.\nfunc (l *OutboundListener) Addr() net.Addr {\n\treturn &net.TCPAddr{\n\t\tIP:   net.IP{0, 0, 0, 0},\n\t\tPort: 0,\n\t}\n}\n\nfunc NewOutbound(tag string, listener *OutboundListener) *Outbound {\n\treturn &Outbound{\n\t\ttag:      tag,\n\t\tlistener: listener,\n\t}\n}\n\n// Outbound is a outbound.Handler that handles gRPC connections.\ntype Outbound struct {\n\ttag      string\n\tlistener *OutboundListener\n\taccess   sync.RWMutex\n\tclosed   bool\n}\n\n// Dispatch implements outbound.Handler.\nfunc (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {\n\tco.access.RLock()\n\n\tif co.closed {\n\t\tcommon.Interrupt(link.Reader)\n\t\tcommon.Interrupt(link.Writer)\n\t\tco.access.RUnlock()\n\t\treturn\n\t}\n\n\tcloseSignal := done.New()\n\tc := net.NewConnection(net.ConnectionInputMulti(link.Writer), net.ConnectionOutputMulti(link.Reader), net.ConnectionOnClose(closeSignal))\n\tco.listener.addWithContext(ctx, c)\n\tco.access.RUnlock()\n\t<-closeSignal.Wait()\n}\n\n// Tag implements outbound.Handler.\nfunc (co *Outbound) Tag() string {\n\treturn co.tag\n}\n\n// Start implements common.Runnable.\nfunc (co *Outbound) Start() error {\n\tco.access.Lock()\n\tco.closed = false\n\tco.access.Unlock()\n\treturn nil\n}\n\n// Close implements common.Closable.\nfunc (co *Outbound) Close() error {\n\tco.access.Lock()\n\tdefer co.access.Unlock()\n\n\tco.closed = true\n\treturn co.listener.Close()\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/padding.go",
    "content": "package server\n\n// this file defines methods to pad packets\n// with a given number of bytes, and to unpack the padding from a padded packet.\n// The packet format is as follows if the desired output length is greater than\n// 4 bytes:\n// | data | padding | data length |\n// The data length is a 32-bit big-endian integer that represents the length of\n// the data in bytes.\n// If the desired output length is 4 bytes or less, the packet format is as\n// follows:\n// | padding |\n// No payload will be included in the packet.\n\nimport \"encoding/binary\"\n\n// Pack pads the given data with the given number of bytes, and appends the\n// length of the data to the end of the data. The returned byte slice\n// contains the padded data.\n// This generates a packet with a length of\n// len(data_OWNERSHIP_RELINQUISHED) + padding + 2\n// @param data_OWNERSHIP_RELINQUISHED - The payload, this reference is consumed and should not be used after this call.\n// @param padding - The number of padding bytes to add to the data.\nfunc Pack(data_OWNERSHIP_RELINQUISHED []byte, paddingLength int) []byte {\n\tdata := append(data_OWNERSHIP_RELINQUISHED, make([]byte, paddingLength)...) //nolint:gocritic\n\tdataLength := len(data_OWNERSHIP_RELINQUISHED)\n\tdata = binary.BigEndian.AppendUint32(data, uint32(dataLength))\n\treturn data\n}\n\n// Pad returns a padding packet of padding length.\n// If the padding length is less than 0, nil is returned.\n// @param padding - The number of padding bytes to add to the data.\nfunc Pad(paddingLength int) []byte {\n\tif assertPaddingLengthIsNotNegative := paddingLength < 0; assertPaddingLengthIsNotNegative {\n\t\treturn nil\n\t}\n\tswitch paddingLength {\n\tcase 0:\n\t\treturn []byte{}\n\tcase 1:\n\t\treturn []byte{0}\n\tcase 2:\n\t\treturn []byte{0, 0}\n\tcase 3:\n\t\treturn []byte{0, 0, 0}\n\tcase 4:\n\t\treturn []byte{0, 0, 0, 0}\n\tdefault:\n\t\treturn append(make([]byte, paddingLength)) //nolint:gocritic, govet, staticcheck\n\t}\n}\n\n// Unpack extracts the data and padding from the given padded data. It\n// returns the data and the number of padding bytes.\n// the data may be nil.\n// @param wrappedData_OWNERSHIP_RELINQUISHED - The packet, this reference is consumed and should not be used after this call.\nfunc Unpack(wrappedData_OWNERSHIP_RELINQUISHED []byte) ([]byte, int) {\n\tdataLength := len(wrappedData_OWNERSHIP_RELINQUISHED)\n\tif dataLength < 4 {\n\t\treturn nil, dataLength\n\t}\n\n\tdataLen := int(binary.BigEndian.Uint32(wrappedData_OWNERSHIP_RELINQUISHED[dataLength-4:]))\n\tif dataLen > len(wrappedData_OWNERSHIP_RELINQUISHED)-4 {\n\t\treturn nil, 0\n\t}\n\tpaddingLength := dataLength - dataLen - 4\n\tif paddingLength < 0 {\n\t\treturn nil, paddingLength\n\t}\n\n\treturn wrappedData_OWNERSHIP_RELINQUISHED[:dataLen], paddingLength\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/server/server.go",
    "content": "package server\n\nimport (\n\tcryptoRand \"crypto/rand\"\n\t\"math/big\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/net/context\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorbase\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/mirrorenrollment\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype Server struct {\n\tconfig *Config\n\n\tlistener net.Listener\n\thandler  internet.ConnHandler\n\n\tctx context.Context\n\n\texplicitNonceCiphersuiteLookup *ciphersuiteLookuper\n\n\tenrollmentConfirmationListener *OutboundListener\n\tenrollmentConfirmationOutbound *Outbound\n\n\tobm outbound.Manager\n\n\tenrollmentConfirmationServer    *mirrorenrollment.EnrollmentConfirmationServer\n\tenrollmentConfirmationProcessor tlsmirror.ConnectionEnrollmentConfirmationProcessor\n}\n\nfunc (s *Server) process(conn net.Conn) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(s.ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.OutboundDialer()\n\n\tport, err := net.PortFromInt(s.config.ForwardPort)\n\tif err != nil {\n\t\tnewError(\"failed to parse port\").Base(err).AtWarning().WriteToLog()\n\t\treturn\n\t}\n\n\taddress := net.ParseAddress(s.config.ForwardAddress)\n\n\tdest := net.TCPDestination(address, port)\n\n\tforwardConn, err := dialer(s.ctx, dest, s.config.ForwardTag)\n\tif err != nil {\n\t\tnewError(\"failed to dial to destination\").Base(err).AtWarning().WriteToLog()\n\t\treturn\n\t}\n\n\ts.accept(conn, forwardConn)\n}\n\nfunc (s *Server) accepts() {\n\tfor {\n\t\tconn, err := s.listener.Accept()\n\t\tif err != nil {\n\t\t\terrStr := err.Error()\n\t\t\tif strings.Contains(errStr, \"closed\") {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnewError(\"failed to accepted raw connections\").Base(err).AtWarning().WriteToLog()\n\t\t\tif strings.Contains(errStr, \"too many\") {\n\t\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tgo s.process(conn)\n\t}\n}\n\nfunc (s *Server) Close() error {\n\tif s.enrollmentConfirmationListener != nil {\n\t\tif err := s.enrollmentConfirmationListener.Close(); err != nil {\n\t\t\tnewError(\"failed to close enrollment confirmation listener\").Base(err).AtWarning().WriteToLog()\n\t\t}\n\t}\n\treturn s.listener.Close()\n}\n\nfunc (s *Server) Addr() net.Addr {\n\treturn s.listener.Addr()\n}\n\nfunc (s *Server) accept(clientConn net.Conn, serverConn net.Conn) {\n\tctx, cancel := context.WithCancel(s.ctx)\n\n\tfirstWriteDelay := time.Duration(0)\n\tif s.config.DeferInstanceDerivedWriteTime != nil {\n\t\tfirstWriteDelay = time.Duration(s.config.DeferInstanceDerivedWriteTime.BaseNanoseconds)\n\t\tif s.config.DeferInstanceDerivedWriteTime.UniformRandomMultiplierNanoseconds > 0 {\n\t\t\tuniformRandomAdd := big.NewInt(int64(s.config.DeferInstanceDerivedWriteTime.UniformRandomMultiplierNanoseconds))\n\t\t\tuniformRandomAddBigInt, err := cryptoRand.Int(cryptoRand.Reader, uniformRandomAdd)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to generate random delay\").Base(err).AtWarning().WriteToLog()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tuniformRandomAddU64 := uint64(uniformRandomAddBigInt.Int64())\n\t\t\tfirstWriteDelay += time.Duration(uniformRandomAddU64)\n\t\t}\n\t}\n\n\tconn := &connState{\n\t\tctx:                      ctx,\n\t\tdone:                     cancel,\n\t\tlocalAddr:                clientConn.LocalAddr(),\n\t\tremoteAddr:               clientConn.RemoteAddr(),\n\t\tprimaryKey:               s.config.PrimaryKey,\n\t\thandler:                  s.onIncomingReadyConnection,\n\t\treadPipe:                 make(chan []byte, 1),\n\t\tfirstWrite:               true,\n\t\tfirstWriteDelay:          firstWriteDelay,\n\t\ttransportLayerPadding:    s.config.TransportLayerPadding,\n\t\tsequenceWatermarkEnabled: s.config.SequenceWatermarkingEnabled,\n\t}\n\n\tif s.config.ConnectionEnrolment != nil {\n\t\tconn.connectionEnrollmentEnabled = true\n\t\tconn.connectionEnrollmentProcessor = s.enrollmentConfirmationProcessor\n\t}\n\n\tconn.mirrorConn = mirrorbase.NewMirroredTLSConn(ctx, clientConn, serverConn, conn.onC2SMessage, conn.onS2CMessage, conn,\n\t\ts.explicitNonceCiphersuiteLookup.Lookup, conn.onC2SMessageTx, conn.onS2CMessageTx)\n}\n\nfunc (s *Server) onIncomingReadyConnection(conn internet.Connection) {\n\tgo s.handler(conn)\n}\n\nfunc (s *Server) init() error {\n\tif err := core.RequireFeatures(s.ctx, func(om outbound.Manager) {\n\t\ts.obm = om\n\t}); err != nil {\n\t\treturn err\n\t}\n\n\tif s.config.ConnectionEnrolment != nil {\n\t\ts.enrollmentConfirmationListener = NewOutboundListener()\n\t\ts.enrollmentConfirmationOutbound = NewOutbound(s.config.ConnectionEnrolment.PrimaryIngressOutbound,\n\t\t\ts.enrollmentConfirmationListener)\n\n\t\tif err := s.enrollmentConfirmationOutbound.Start(); err != nil {\n\t\t\treturn newError(\"failed to start enrollment confirmation outbound\").Base(err).AtWarning()\n\t\t}\n\n\t\tif err := s.obm.RemoveHandler(context.Background(), s.config.ConnectionEnrolment.PrimaryIngressOutbound); err != nil {\n\t\t\tnewError(\"failed to remove existing handler\").Base(err).AtDebug().WriteToLog()\n\t\t}\n\n\t\terr := s.obm.AddHandler(context.Background(), s.enrollmentConfirmationOutbound)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to add outbound handler\").Base(err)\n\t\t}\n\n\t\ts.enrollmentConfirmationProcessor, err = mirrorenrollment.NewServerEnrollmentProcessor(s.config.PrimaryKey)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create enrollment confirmation processor\").Base(err).AtError()\n\t\t}\n\n\t\ts.enrollmentConfirmationServer, err = mirrorenrollment.NewEnrollmentConfirmationServer(s.ctx, s.config.ConnectionEnrolment,\n\t\t\ts.enrollmentConfirmationProcessor)\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to create enrollment confirmation server\").Base(err).AtError()\n\t\t}\n\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tconn, err := s.enrollmentConfirmationListener.Accept()\n\t\t\t\tif err != nil {\n\t\t\t\t\tnewError(\"failed to accept enrollment confirmation connection\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tgo func() {\n\t\t\t\t\tif err := s.enrollmentConfirmationServer.HandlePrimaryIngressConnection(s.ctx, conn); err != nil {\n\t\t\t\t\t\tnewError(\"failed to handle primary ingress connection for enrollment confirmation\").Base(err).AtWarning().WriteToLog()\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 NewServer(ctx context.Context, listener net.Listener, config *Config, handler internet.ConnHandler) (*Server, error) {\n\tvar explicitNonceCiphersuiteLookup *ciphersuiteLookuper\n\tif len(config.ExplicitNonceCiphersuites) > 0 {\n\t\tvar err error\n\t\texplicitNonceCiphersuiteLookup, err = newCipherSuiteLookuperFromUint32Array(config.ExplicitNonceCiphersuites)\n\t\tif err != nil {\n\t\t\tnewError(\"failed to create explicit nonce ciphersuite lookuper\").Base(err).AtWarning().WriteToLog()\n\t\t}\n\t} else {\n\t\texplicitNonceCiphersuiteLookup = newEmptyCipherSuiteLookuper()\n\t\tnewError(\"no explicit nonce ciphersuites configured, all ciphersuites will be treated as non-explicit nonce\").AtWarning().WriteToLog()\n\t}\n\n\ts := &Server{\n\t\tctx:                            ctx,\n\t\tlistener:                       listener,\n\t\tconfig:                         config,\n\t\thandler:                        handler,\n\t\texplicitNonceCiphersuiteLookup: explicitNonceCiphersuiteLookup,\n\t}\n\n\tif err := s.init(); err != nil {\n\t\treturn nil, newError(\"failed to initialize TLS mirror server\").Base(err).AtError()\n\t}\n\n\treturn s, nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/tlstrafficgen/config.pb.go",
    "content": "package tlstrafficgen\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\tunsafe \"unsafe\"\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 TimeSpec struct {\n\tstate                              protoimpl.MessageState `protogen:\"open.v1\"`\n\tBaseNanoseconds                    uint64                 `protobuf:\"varint,1,opt,name=base_nanoseconds,json=baseNanoseconds,proto3\" json:\"base_nanoseconds,omitempty\"`\n\tUniformRandomMultiplierNanoseconds uint64                 `protobuf:\"varint,2,opt,name=uniform_random_multiplier_nanoseconds,json=uniformRandomMultiplierNanoseconds,proto3\" json:\"uniform_random_multiplier_nanoseconds,omitempty\"`\n\tunknownFields                      protoimpl.UnknownFields\n\tsizeCache                          protoimpl.SizeCache\n}\n\nfunc (x *TimeSpec) Reset() {\n\t*x = TimeSpec{}\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TimeSpec) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TimeSpec) ProtoMessage() {}\n\nfunc (x *TimeSpec) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[0]\n\tif 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 TimeSpec.ProtoReflect.Descriptor instead.\nfunc (*TimeSpec) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *TimeSpec) GetBaseNanoseconds() uint64 {\n\tif x != nil {\n\t\treturn x.BaseNanoseconds\n\t}\n\treturn 0\n}\n\nfunc (x *TimeSpec) GetUniformRandomMultiplierNanoseconds() uint64 {\n\tif x != nil {\n\t\treturn x.UniformRandomMultiplierNanoseconds\n\t}\n\treturn 0\n}\n\ntype Header struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tName          string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tValue         string                 `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tValues        []string               `protobuf:\"bytes,3,rep,name=values,proto3\" json:\"values,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Header) Reset() {\n\t*x = Header{}\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\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_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[1]\n\tif 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_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Header) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetValues() []string {\n\tif x != nil {\n\t\treturn x.Values\n\t}\n\treturn nil\n}\n\ntype TransferCandidate struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tWeight        int32                  `protobuf:\"varint,1,opt,name=weight,proto3\" json:\"weight,omitempty\"`\n\tGotoLocation  int64                  `protobuf:\"varint,2,opt,name=goto_location,json=gotoLocation,proto3\" json:\"goto_location,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *TransferCandidate) Reset() {\n\t*x = TransferCandidate{}\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[2]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *TransferCandidate) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TransferCandidate) ProtoMessage() {}\n\nfunc (x *TransferCandidate) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[2]\n\tif 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 TransferCandidate.ProtoReflect.Descriptor instead.\nfunc (*TransferCandidate) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *TransferCandidate) GetWeight() int32 {\n\tif x != nil {\n\t\treturn x.Weight\n\t}\n\treturn 0\n}\n\nfunc (x *TransferCandidate) GetGotoLocation() int64 {\n\tif x != nil {\n\t\treturn x.GotoLocation\n\t}\n\treturn 0\n}\n\ntype Step struct {\n\tstate                        protoimpl.MessageState `protogen:\"open.v1\"`\n\tName                         string                 `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tHost                         string                 `protobuf:\"bytes,8,opt,name=host,proto3\" json:\"host,omitempty\"`\n\tPath                         string                 `protobuf:\"bytes,2,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tMethod                       string                 `protobuf:\"bytes,3,opt,name=method,proto3\" json:\"method,omitempty\"`\n\tNextStep                     []*TransferCandidate   `protobuf:\"bytes,6,rep,name=next_step,json=nextStep,proto3\" json:\"next_step,omitempty\"`\n\tConnectionReady              bool                   `protobuf:\"varint,7,opt,name=connection_ready,json=connectionReady,proto3\" json:\"connection_ready,omitempty\"`\n\tHeaders                      []*Header              `protobuf:\"bytes,9,rep,name=headers,proto3\" json:\"headers,omitempty\"`\n\tConnectionRecallExit         bool                   `protobuf:\"varint,10,opt,name=connection_recall_exit,json=connectionRecallExit,proto3\" json:\"connection_recall_exit,omitempty\"`\n\tWaitTime                     *TimeSpec              `protobuf:\"bytes,11,opt,name=wait_time,json=waitTime,proto3\" json:\"wait_time,omitempty\"`\n\tH2DoNotWaitForDownloadFinish bool                   `protobuf:\"varint,12,opt,name=h2_do_not_wait_for_download_finish,json=h2DoNotWaitForDownloadFinish,proto3\" json:\"h2_do_not_wait_for_download_finish,omitempty\"`\n\tunknownFields                protoimpl.UnknownFields\n\tsizeCache                    protoimpl.SizeCache\n}\n\nfunc (x *Step) Reset() {\n\t*x = Step{}\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[3]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Step) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Step) ProtoMessage() {}\n\nfunc (x *Step) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[3]\n\tif 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 Step.ProtoReflect.Descriptor instead.\nfunc (*Step) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Step) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Step) GetHost() string {\n\tif x != nil {\n\t\treturn x.Host\n\t}\n\treturn \"\"\n}\n\nfunc (x *Step) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Step) GetMethod() string {\n\tif x != nil {\n\t\treturn x.Method\n\t}\n\treturn \"\"\n}\n\nfunc (x *Step) GetNextStep() []*TransferCandidate {\n\tif x != nil {\n\t\treturn x.NextStep\n\t}\n\treturn nil\n}\n\nfunc (x *Step) GetConnectionReady() bool {\n\tif x != nil {\n\t\treturn x.ConnectionReady\n\t}\n\treturn false\n}\n\nfunc (x *Step) GetHeaders() []*Header {\n\tif x != nil {\n\t\treturn x.Headers\n\t}\n\treturn nil\n}\n\nfunc (x *Step) GetConnectionRecallExit() bool {\n\tif x != nil {\n\t\treturn x.ConnectionRecallExit\n\t}\n\treturn false\n}\n\nfunc (x *Step) GetWaitTime() *TimeSpec {\n\tif x != nil {\n\t\treturn x.WaitTime\n\t}\n\treturn nil\n}\n\nfunc (x *Step) GetH2DoNotWaitForDownloadFinish() bool {\n\tif x != nil {\n\t\treturn x.H2DoNotWaitForDownloadFinish\n\t}\n\treturn false\n}\n\ntype Config struct {\n\tstate            protoimpl.MessageState `protogen:\"open.v1\"`\n\tSteps            []*Step                `protobuf:\"bytes,1,rep,name=steps,proto3\" json:\"steps,omitempty\"`\n\tSecuritySettings *anypb.Any             `protobuf:\"bytes,2,opt,name=security_settings,json=securitySettings,proto3\" json:\"security_settings,omitempty\"`\n\tunknownFields    protoimpl.UnknownFields\n\tsizeCache        protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[4]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes[4]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *Config) GetSteps() []*Step {\n\tif x != nil {\n\t\treturn x.Steps\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetSecuritySettings() *anypb.Any {\n\tif x != nil {\n\t\treturn x.SecuritySettings\n\t}\n\treturn nil\n}\n\nvar File_transport_internet_tlsmirror_tlstrafficgen_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"7transport/internet/tlsmirror/tlstrafficgen/config.proto\\x125v2ray.core.transport.internet.tlsmirror.tlstrafficgen\\x1a\\x19google/protobuf/any.proto\\\"\\x88\\x01\\n\" +\n\t\"\\bTimeSpec\\x12)\\n\" +\n\t\"\\x10base_nanoseconds\\x18\\x01 \\x01(\\x04R\\x0fbaseNanoseconds\\x12Q\\n\" +\n\t\"%uniform_random_multiplier_nanoseconds\\x18\\x02 \\x01(\\x04R\\\"uniformRandomMultiplierNanoseconds\\\"J\\n\" +\n\t\"\\x06Header\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value\\x12\\x16\\n\" +\n\t\"\\x06values\\x18\\x03 \\x03(\\tR\\x06values\\\"P\\n\" +\n\t\"\\x11TransferCandidate\\x12\\x16\\n\" +\n\t\"\\x06weight\\x18\\x01 \\x01(\\x05R\\x06weight\\x12#\\n\" +\n\t\"\\rgoto_location\\x18\\x02 \\x01(\\x03R\\fgotoLocation\\\"\\xa3\\x04\\n\" +\n\t\"\\x04Step\\x12\\x12\\n\" +\n\t\"\\x04name\\x18\\x01 \\x01(\\tR\\x04name\\x12\\x12\\n\" +\n\t\"\\x04host\\x18\\b \\x01(\\tR\\x04host\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x02 \\x01(\\tR\\x04path\\x12\\x16\\n\" +\n\t\"\\x06method\\x18\\x03 \\x01(\\tR\\x06method\\x12e\\n\" +\n\t\"\\tnext_step\\x18\\x06 \\x03(\\v2H.v2ray.core.transport.internet.tlsmirror.tlstrafficgen.TransferCandidateR\\bnextStep\\x12)\\n\" +\n\t\"\\x10connection_ready\\x18\\a \\x01(\\bR\\x0fconnectionReady\\x12W\\n\" +\n\t\"\\aheaders\\x18\\t \\x03(\\v2=.v2ray.core.transport.internet.tlsmirror.tlstrafficgen.HeaderR\\aheaders\\x124\\n\" +\n\t\"\\x16connection_recall_exit\\x18\\n\" +\n\t\" \\x01(\\bR\\x14connectionRecallExit\\x12\\\\\\n\" +\n\t\"\\twait_time\\x18\\v \\x01(\\v2?.v2ray.core.transport.internet.tlsmirror.tlstrafficgen.TimeSpecR\\bwaitTime\\x12H\\n\" +\n\t\"\\\"h2_do_not_wait_for_download_finish\\x18\\f \\x01(\\bR\\x1ch2DoNotWaitForDownloadFinish\\\"\\x9e\\x01\\n\" +\n\t\"\\x06Config\\x12Q\\n\" +\n\t\"\\x05steps\\x18\\x01 \\x03(\\v2;.v2ray.core.transport.internet.tlsmirror.tlstrafficgen.StepR\\x05steps\\x12A\\n\" +\n\t\"\\x11security_settings\\x18\\x02 \\x01(\\v2\\x14.google.protobuf.AnyR\\x10securitySettingsB\\xc0\\x01\\n\" +\n\t\"9com.v2ray.core.transport.internet.tlsmirror.tlstrafficgenP\\x01ZIgithub.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/tlstrafficgen\\xaa\\x025V2Ray.Core.Transport.Internet.Tlsmirror.Tlstrafficgenb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDesc), len(file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDescData\n}\n\nvar file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)\nvar file_transport_internet_tlsmirror_tlstrafficgen_config_proto_goTypes = []any{\n\t(*TimeSpec)(nil),          // 0: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.TimeSpec\n\t(*Header)(nil),            // 1: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Header\n\t(*TransferCandidate)(nil), // 2: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.TransferCandidate\n\t(*Step)(nil),              // 3: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Step\n\t(*Config)(nil),            // 4: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Config\n\t(*anypb.Any)(nil),         // 5: google.protobuf.Any\n}\nvar file_transport_internet_tlsmirror_tlstrafficgen_config_proto_depIdxs = []int32{\n\t2, // 0: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Step.next_step:type_name -> v2ray.core.transport.internet.tlsmirror.tlstrafficgen.TransferCandidate\n\t1, // 1: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Step.headers:type_name -> v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Header\n\t0, // 2: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Step.wait_time:type_name -> v2ray.core.transport.internet.tlsmirror.tlstrafficgen.TimeSpec\n\t3, // 3: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Config.steps:type_name -> v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Step\n\t5, // 4: v2ray.core.transport.internet.tlsmirror.tlstrafficgen.Config.security_settings:type_name -> google.protobuf.Any\n\t5, // [5:5] is the sub-list for method output_type\n\t5, // [5:5] is the sub-list for method input_type\n\t5, // [5:5] is the sub-list for extension type_name\n\t5, // [5:5] is the sub-list for extension extendee\n\t0, // [0:5] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_tlsmirror_tlstrafficgen_config_proto_init() }\nfunc file_transport_internet_tlsmirror_tlstrafficgen_config_proto_init() {\n\tif File_transport_internet_tlsmirror_tlstrafficgen_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDesc), len(file_transport_internet_tlsmirror_tlstrafficgen_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   5,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_tlsmirror_tlstrafficgen_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_tlsmirror_tlstrafficgen_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_tlsmirror_tlstrafficgen_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_tlsmirror_tlstrafficgen_config_proto = out.File\n\tfile_transport_internet_tlsmirror_tlstrafficgen_config_proto_goTypes = nil\n\tfile_transport_internet_tlsmirror_tlstrafficgen_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/tlstrafficgen/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.tlsmirror.tlstrafficgen;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Tlsmirror.Tlstrafficgen\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/tlstrafficgen\";\noption java_package = \"com.v2ray.core.transport.internet.tlsmirror.tlstrafficgen\";\noption java_multiple_files = true;\n\nimport \"google/protobuf/any.proto\";\n\nmessage TimeSpec {\n  uint64 base_nanoseconds = 1;\n  uint64 uniform_random_multiplier_nanoseconds = 2;\n}\n\nmessage Header {\n  string name = 1;\n  string value = 2;\n  repeated string values = 3;\n}\n\nmessage TransferCandidate{\n  int32 weight = 1;\n  int64 goto_location = 2;\n}\n\nmessage Step {\n  string name = 1;\n  string host = 8;\n  string path = 2;\n  string method = 3;\n  repeated TransferCandidate next_step = 6;\n  bool connection_ready = 7;\n  repeated Header headers = 9;\n  bool connection_recall_exit = 10;\n  TimeSpec wait_time = 11;\n  bool h2_do_not_wait_for_download_finish = 12;\n}\n\nmessage Config {\n  repeated Step steps = 1;\n  google.protobuf.Any security_settings = 2;\n}"
  },
  {
    "path": "transport/internet/tlsmirror/tlstrafficgen/errors.generated.go",
    "content": "package tlstrafficgen\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/tlsmirror/tlstrafficgen/trafficgen.go",
    "content": "package tlstrafficgen\n\nimport (\n\t\"context\"\n\tcryptoRand \"crypto/rand\"\n\t\"io\"\n\t\"math/big\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tlsmirror/httponconnection\"\n)\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\ntype TrafficGenerator struct {\n\tconfig *Config\n\tctx    context.Context\n\n\tdestination net.Destination\n\ttag         string\n}\n\nfunc NewTrafficGenerator(ctx context.Context, config *Config, destination net.Destination, tag string) *TrafficGenerator {\n\treturn &TrafficGenerator{\n\t\tctx:         ctx,\n\t\tconfig:      config,\n\t\tdestination: destination,\n\t\ttag:         tag,\n\t}\n}\n\ntype trafficGeneratorManagedConnectionController struct {\n\treadyCtx  context.Context\n\treadyDone context.CancelFunc\n\n\trecallCtx  context.Context\n\trecallDone context.CancelFunc\n\n\tinvalidatedCtx  context.Context\n\tinvalidatedDone context.CancelFunc\n}\n\nfunc newTrafficGeneratorManagedConnectionController(parent context.Context) *trafficGeneratorManagedConnectionController {\n\treadyCtx, readyDone := context.WithCancel(parent)\n\trecallCtx, recallDone := context.WithCancel(parent)\n\tinvalidatedCtx, invalidatedDone := context.WithCancel(parent)\n\treturn &trafficGeneratorManagedConnectionController{\n\t\treadyCtx:        readyCtx,\n\t\treadyDone:       readyDone,\n\t\trecallCtx:       recallCtx,\n\t\trecallDone:      recallDone,\n\t\tinvalidatedCtx:  invalidatedCtx,\n\t\tinvalidatedDone: invalidatedDone,\n\t}\n}\n\nfunc (t *trafficGeneratorManagedConnectionController) WaitConnectionReady() context.Context {\n\treturn t.readyCtx\n}\n\nfunc (t *trafficGeneratorManagedConnectionController) RecallTrafficGenerator() error {\n\tt.recallDone()\n\treturn nil\n}\n\nfunc (t *trafficGeneratorManagedConnectionController) IsConnectionInvalidated() bool {\n\treturn t.invalidatedCtx.Err() != nil\n}\n\n// Copied from https://brandur.org/fragments/crypto-rand-float64, Thanks\nfunc randIntN(max int64) int64 {\n\tnBig, err := cryptoRand.Int(cryptoRand.Reader, big.NewInt(max))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn nBig.Int64()\n}\n\nfunc randFloat64() float64 {\n\treturn float64(randIntN(1<<53)) / (1 << 53)\n}\n\nfunc (generator *TrafficGenerator) GenerateNextTraffic(ctx context.Context) error {\n\ttransportEnvironment := envctx.EnvironmentFromContext(generator.ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.OutboundDialer()\n\n\ttrafficController := newTrafficGeneratorManagedConnectionController(generator.ctx)\n\n\tvar trafficControllerIfce tlsmirror.TrafficGeneratorManagedConnection = trafficController\n\tmanagedConnectionContextValue := context.WithValue(generator.ctx,\n\t\ttlsmirror.TrafficGeneratorManagedConnectionContextKey, trafficControllerIfce) // nolint:staticcheck\n\n\tdefer func() {\n\t\ttrafficController.invalidatedDone()\n\t\ttrafficController.readyDone()\n\t}()\n\n\tconn, err := dialer(managedConnectionContextValue, generator.destination, generator.tag)\n\tif err != nil {\n\t\treturn newError(\"failed to dial to destination\").Base(err).AtWarning()\n\t}\n\ttlsConn, err := generator.tlsHandshake(conn)\n\tif err != nil {\n\t\treturn newError(\"failed to create TLS connection\").Base(err).AtWarning()\n\t}\n\tgetAlpn, ok := tlsConn.(security.ConnectionApplicationProtocol)\n\tif !ok {\n\t\treturn newError(\"TLS connection does not support getting ALPN\").AtWarning()\n\t}\n\talpn, err := getAlpn.GetConnectionApplicationProtocol()\n\tif err != nil {\n\t\treturn newError(\"failed to get ALPN from TLS connection\").Base(err).AtWarning()\n\t}\n\tsteps := generator.config.Steps\n\tcurrentStep := 0\n\thttpRoundTripper, err := httponconnection.NewSingleConnectionHTTPTransport(tlsConn, alpn)\n\tif err != nil {\n\t\treturn newError(\"failed to create HTTP transport\").Base(err).AtWarning()\n\t}\n\tfor {\n\t\tif currentStep >= len(steps) {\n\t\t\treturn tlsConn.Close()\n\t\t}\n\n\t\tstep := steps[currentStep]\n\n\t\turl := url.URL{\n\t\t\tScheme: \"https\",\n\t\t\tHost:   step.Host,\n\t\t\tPath:   step.Path,\n\t\t}\n\n\t\thttpReq := &http.Request{Host: url.Hostname(), Method: step.Method, URL: &url}\n\n\t\tif step.Headers != nil {\n\t\t\theader := make(http.Header, len(step.Headers))\n\t\t\tfor _, v := range step.Headers {\n\t\t\t\tif v.Value != \"\" {\n\t\t\t\t\theader.Add(v.Name, v.Value)\n\t\t\t\t}\n\t\t\t\tif v.Values != nil {\n\t\t\t\t\tfor _, value := range v.Values {\n\t\t\t\t\t\theader.Add(v.Name, value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\thttpReq.Header = header\n\t\t}\n\n\t\tstartTime := time.Now()\n\n\t\tresp, err := httpRoundTripper.RoundTrip(httpReq) //nolint:bodyclose\n\t\tif err != nil {\n\t\t\treturn newError(\"failed to send HTTP request\").Base(err).AtWarning()\n\t\t}\n\n\t\tfinishRequest := func() error {\n\t\t\t_, err = io.Copy(io.Discard, resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to read HTTP response body\").Base(err).AtWarning()\n\t\t\t}\n\t\t\terr = resp.Body.Close()\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to close HTTP response body\").Base(err).AtWarning()\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif step.H2DoNotWaitForDownloadFinish && alpn == \"h2\" {\n\t\t\tgo func() {\n\t\t\t\tif err := finishRequest(); err != nil {\n\t\t\t\t\tnewError(\"failed to finish request in background\").Base(err).AtWarning().WriteToLog()\n\t\t\t\t}\n\t\t\t}()\n\t\t} else {\n\t\t\tif err := finishRequest(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tendTime := time.Now()\n\n\t\teclipsedTime := endTime.Sub(startTime)\n\t\tif step.WaitTime == nil {\n\t\t\tstep.WaitTime = &TimeSpec{}\n\t\t\tnewError(\"no wait time specified for step \", currentStep, \", using default 0 seconds\").AtWarning().WriteToLog()\n\t\t}\n\t\tsecondToWait := (float64(step.WaitTime.UniformRandomMultiplierNanoseconds)*randFloat64() + float64(step.WaitTime.BaseNanoseconds)) / float64(time.Second)\n\t\tif eclipsedTime < time.Duration(secondToWait*float64(time.Second)) {\n\t\t\twaitTime := time.Duration(secondToWait*float64(time.Second)) - eclipsedTime\n\t\t\tnewError(\"waiting for \", waitTime, \" after step \", currentStep).AtDebug().WriteToLog()\n\t\t\twaitTimer := time.NewTimer(waitTime)\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\twaitTimer.Stop()\n\t\t\t\treturn ctx.Err()\n\t\t\tcase <-waitTimer.C:\n\t\t\t}\n\t\t} else {\n\t\t\tnewError(\"step \", currentStep, \" took too long: \", eclipsedTime, \", expected: \", secondToWait, \" seconds\").AtWarning().WriteToLog()\n\t\t}\n\n\t\tif step.ConnectionReady {\n\t\t\ttrafficController.readyDone()\n\t\t\tnewError(\"connection ready for payload traffic\").AtInfo().WriteToLog()\n\t\t}\n\n\t\tif step.ConnectionRecallExit {\n\t\t\tif trafficController.recallCtx.Err() != nil {\n\t\t\t\treturn tlsConn.Close()\n\t\t\t}\n\t\t}\n\n\t\tif step.NextStep == nil {\n\t\t\tcurrentStep++\n\t\t} else {\n\t\t\toverallWeight := int32(0)\n\t\t\tfor _, nextStep := range step.NextStep {\n\t\t\t\toverallWeight += nextStep.Weight\n\t\t\t}\n\t\t\tmaxBound := big.NewInt(int64(overallWeight))\n\t\t\tselectionValue, err := cryptoRand.Int(cryptoRand.Reader, maxBound)\n\t\t\tif err != nil {\n\t\t\t\treturn newError(\"failed to generate random selection value\").Base(err).AtWarning()\n\t\t\t}\n\t\t\tselectedValue := int32(selectionValue.Int64())\n\t\t\tcurrentValue := int32(0)\n\t\t\tmatched := false\n\t\t\tfor _, nextStep := range step.NextStep {\n\t\t\t\tif currentValue >= selectedValue {\n\t\t\t\t\tcurrentStep = int(nextStep.GotoLocation)\n\t\t\t\t\tmatched = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcurrentValue += nextStep.Weight\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tnewError(\"invalid steps jump instruction, check configuration for step \", currentStep).AtError().WriteToLog()\n\t\t\t\tcurrentStep++\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (generator *TrafficGenerator) tlsHandshake(conn net.Conn) (security.Conn, error) {\n\tsecuritySettingInstance, err := serial.GetInstanceOf(generator.config.SecuritySettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to get instance of security settings\").Base(err)\n\t}\n\tsecurityEngine, err := common.CreateObject(generator.ctx, securitySettingInstance)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create security engine from security settings\").Base(err)\n\t}\n\tsecurityEngineTyped, ok := securityEngine.(security.Engine)\n\tif !ok {\n\t\treturn nil, newError(\"type assertion error when create security engine from security settings\")\n\t}\n\n\treturn securityEngineTyped.Client(conn)\n}\n"
  },
  {
    "path": "transport/internet/transportcommon/dialer.go",
    "content": "package transportcommon\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc DialWithSecuritySettings(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tdialer := transportEnvironment.Dialer()\n\tconn, err := dialer.Dial(ctx, nil, dest, streamSettings.SocketSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial to \", dest).Base(err)\n\t}\n\tsecurityEngine, err := security.CreateSecurityEngineFromSettings(ctx, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create security engine\").Base(err)\n\t}\n\n\tif securityEngine != nil {\n\t\tconn, err = securityEngine.Client(conn, security.OptionWithDestination{Dest: dest})\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"unable to create security protocol client from security engine\").Base(err)\n\t\t}\n\t}\n\treturn internet.Connection(conn), nil\n}\n"
  },
  {
    "path": "transport/internet/transportcommon/errors.generated.go",
    "content": "package transportcommon\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/transportcommon/httpDialer.go",
    "content": "package transportcommon\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/http2\"\n\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n)\n\ntype DialerFunc func(ctx context.Context, addr string) (net.Conn, error)\n\nfunc NewALPNAwareHTTPRoundTripper(ctx context.Context, dialer DialerFunc,\n\tbackdropTransport http.RoundTripper,\n) http.RoundTripper {\n\treturn NewALPNAwareHTTPRoundTripperWithH2Pool(ctx, dialer, backdropTransport, 1)\n}\n\n// NewALPNAwareHTTPRoundTripperWithH2Pool creates an instance of RoundTripper that dial to remote HTTPS endpoint with\n// an alternative version of TLS implementation.\nfunc NewALPNAwareHTTPRoundTripperWithH2Pool(ctx context.Context, dialer DialerFunc,\n\tbackdropTransport http.RoundTripper,\n\th2PoolSize int,\n) http.RoundTripper {\n\trtImpl := &alpnAwareHTTPRoundTripperImpl{\n\t\tconnectWithH1:     map[string]bool{},\n\t\tbackdropTransport: backdropTransport,\n\t\tpendingConn:       map[pendingConnKey]*unclaimedConnection{},\n\t\tdialer:            dialer,\n\t\tctx:               ctx,\n\t}\n\trtImpl.init()\n\treturn rtImpl\n}\n\ntype alpnAwareHTTPRoundTripperImpl struct {\n\taccessConnectWithH1 sync.Mutex\n\tconnectWithH1       map[string]bool\n\n\thttpsH1Transport  http.RoundTripper\n\thttpsH2Transport  http.RoundTripper\n\tbackdropTransport http.RoundTripper\n\n\taccessDialingConnection sync.Mutex\n\tpendingConn             map[pendingConnKey]*unclaimedConnection\n\n\tctx    context.Context\n\tdialer DialerFunc\n\n\th2PoolSize int\n}\n\ntype pendingConnKey struct {\n\tisH2 bool\n\tdest string\n}\n\nvar (\n\terrEAGAIN        = errors.New(\"incorrect ALPN negotiated, try again with another ALPN\")\n\terrEAGAINTooMany = errors.New(\"incorrect ALPN negotiated\")\n\terrExpired       = errors.New(\"connection have expired\")\n)\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) RoundTrip(req *http.Request) (*http.Response, error) {\n\tif req.URL.Scheme != \"https\" {\n\t\treturn r.backdropTransport.RoundTrip(req)\n\t}\n\tfor retryCount := 0; retryCount < 5; retryCount++ {\n\t\teffectivePort := req.URL.Port()\n\t\tif effectivePort == \"\" {\n\t\t\teffectivePort = \"443\"\n\t\t}\n\t\tif r.getShouldConnectWithH1(fmt.Sprintf(\"%v:%v\", req.URL.Hostname(), effectivePort)) {\n\t\t\tresp, err := r.httpsH1Transport.RoundTrip(req)\n\t\t\tif errors.Is(err, errEAGAIN) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn resp, err\n\t\t}\n\t\tresp, err := r.httpsH2Transport.RoundTrip(req)\n\t\tif errors.Is(err, errEAGAIN) {\n\t\t\tcontinue\n\t\t}\n\t\treturn resp, err\n\t}\n\treturn nil, errEAGAINTooMany\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) getShouldConnectWithH1(domainName string) bool {\n\tr.accessConnectWithH1.Lock()\n\tdefer r.accessConnectWithH1.Unlock()\n\tif value, set := r.connectWithH1[domainName]; set {\n\t\treturn value\n\t}\n\treturn false\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) setShouldConnectWithH1(domainName string) {\n\tr.accessConnectWithH1.Lock()\n\tdefer r.accessConnectWithH1.Unlock()\n\tr.connectWithH1[domainName] = true\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) clearShouldConnectWithH1(domainName string) {\n\tr.accessConnectWithH1.Lock()\n\tdefer r.accessConnectWithH1.Unlock()\n\tr.connectWithH1[domainName] = false\n}\n\nfunc getPendingConnectionID(dest string, alpnIsH2 bool) pendingConnKey {\n\treturn pendingConnKey{isH2: alpnIsH2, dest: dest}\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) putConn(addr string, alpnIsH2 bool, conn net.Conn) {\n\tconnID := getPendingConnectionID(addr, alpnIsH2)\n\tr.pendingConn[connID] = NewUnclaimedConnection(conn, time.Minute)\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) getConn(addr string, alpnIsH2 bool) net.Conn {\n\tconnID := getPendingConnectionID(addr, alpnIsH2)\n\tif conn, ok := r.pendingConn[connID]; ok {\n\t\tdelete(r.pendingConn, connID)\n\t\tif claimedConnection, err := conn.claimConnection(); err == nil {\n\t\t\treturn claimedConnection\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) dialOrGetTLSWithExpectedALPN(ctx context.Context, addr string, expectedH2 bool) (net.Conn, error) {\n\tr.accessDialingConnection.Lock()\n\tdefer r.accessDialingConnection.Unlock()\n\n\tif r.getShouldConnectWithH1(addr) == expectedH2 {\n\t\treturn nil, errEAGAIN\n\t}\n\n\t// Get a cached connection if possible to reduce preflight connection closed without sending data\n\tif gconn := r.getConn(addr, expectedH2); gconn != nil {\n\t\treturn gconn, nil\n\t}\n\n\tconn, err := r.dialTLS(ctx, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tprotocol := \"\"\n\tif connAPLNGetter, ok := conn.(security.ConnectionApplicationProtocol); ok {\n\t\tconnectionALPN, err := connAPLNGetter.GetConnectionApplicationProtocol()\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to get connection ALPN\").Base(err).AtWarning()\n\t\t}\n\t\tprotocol = connectionALPN\n\t}\n\n\tprotocolIsH2 := protocol == http2.NextProtoTLS\n\n\tif protocolIsH2 == expectedH2 {\n\t\treturn conn, err\n\t}\n\n\tr.putConn(addr, protocolIsH2, conn)\n\n\tif protocolIsH2 {\n\t\tr.clearShouldConnectWithH1(addr)\n\t} else {\n\t\tr.setShouldConnectWithH1(addr)\n\t}\n\n\treturn nil, errEAGAIN\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) dialTLS(ctx context.Context, addr string) (net.Conn, error) {\n\t_ = ctx\n\treturn r.dialer(r.ctx, addr)\n}\n\nfunc (r *alpnAwareHTTPRoundTripperImpl) init() {\n\tif r.h2PoolSize >= 2 {\n\t\tr.httpsH2Transport = newH2TransportPool(int64(r.h2PoolSize), func() *http2.Transport {\n\t\t\treturn &http2.Transport{\n\t\t\t\tDialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {\n\t\t\t\t\treturn r.dialOrGetTLSWithExpectedALPN(context.Background(), addr, true)\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\t} else {\n\t\tr.httpsH2Transport = &http2.Transport{\n\t\t\tDialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {\n\t\t\t\treturn r.dialOrGetTLSWithExpectedALPN(context.Background(), addr, true)\n\t\t\t},\n\t\t}\n\t}\n\tr.httpsH1Transport = &http.Transport{\n\t\tDialTLSContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {\n\t\t\treturn r.dialOrGetTLSWithExpectedALPN(ctx, addr, false)\n\t\t},\n\t}\n}\n\nfunc NewUnclaimedConnection(conn net.Conn, expireTime time.Duration) *unclaimedConnection {\n\tc := &unclaimedConnection{\n\t\tConn: conn,\n\t}\n\ttime.AfterFunc(expireTime, c.tick)\n\treturn c\n}\n\ntype unclaimedConnection struct {\n\tnet.Conn\n\tclaimed bool\n\taccess  sync.Mutex\n}\n\nfunc (c *unclaimedConnection) claimConnection() (net.Conn, error) {\n\tc.access.Lock()\n\tdefer c.access.Unlock()\n\tif !c.claimed {\n\t\tc.claimed = true\n\t\treturn c.Conn, nil\n\t}\n\treturn nil, errExpired\n}\n\nfunc (c *unclaimedConnection) tick() {\n\tc.access.Lock()\n\tdefer c.access.Unlock()\n\tif !c.claimed {\n\t\tc.claimed = true\n\t\tc.Conn.Close() //nolint: staticcheck\n\t\tc.Conn = nil\n\t}\n}\n\ntype h2TransportFactory func() *http2.Transport\n\nfunc newH2TransportPool(size int64, h2factory h2TransportFactory) *h2TransportPool {\n\treturn &h2TransportPool{\n\t\tpool:      make([]*http2.Transport, size),\n\t\tsize:      size,\n\t\th2factory: h2factory,\n\t}\n}\n\ntype h2TransportPool struct {\n\tpool       []*http2.Transport\n\th2factory  h2TransportFactory\n\tusageCount int64\n\tsize       int64\n}\n\nfunc (h *h2TransportPool) RoundTrip(request *http.Request) (*http.Response, error) {\n\tcurrentSlot := h.usageCount % h.size\n\th.usageCount++\n\tif h.pool[currentSlot] == nil {\n\t\th.pool[currentSlot] = h.h2factory()\n\t}\n\treturn h.pool[currentSlot].RoundTrip(request)\n}\n"
  },
  {
    "path": "transport/internet/transportcommon/listener.go",
    "content": "package transportcommon\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\tv2tls \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\nfunc ListenWithSecuritySettings(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig) (\n\tnet.Listener, error,\n) {\n\tvar l net.Listener\n\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\ttransportListener := transportEnvironment.Listener()\n\n\tif port == net.Port(0) { // unix\n\t\tif !address.Family().IsDomain() {\n\t\t\treturn nil, newError(\"invalid address for unix domain socket: \", address)\n\t\t}\n\t\tlistener, err := transportListener.Listen(ctx, &net.UnixAddr{\n\t\t\tName: address.Domain(),\n\t\t\tNet:  \"unix\",\n\t\t}, streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen unix domain socket on \", address).Base(err)\n\t\t}\n\t\tnewError(\"listening unix domain socket on \", address).WriteToLog(session.ExportIDToError(ctx))\n\t\tl = listener\n\t} else { // tcp\n\t\tlistener, err := transportListener.Listen(ctx, &net.TCPAddr{\n\t\t\tIP:   address.IP(),\n\t\t\tPort: int(port),\n\t\t}, streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen TCP on \", address, \":\", port).Base(err)\n\t\t}\n\t\tnewError(\"listening TCP on \", address, \":\", port).WriteToLog(session.ExportIDToError(ctx))\n\t\tl = listener\n\t}\n\n\tif streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol {\n\t\tnewError(\"accepting PROXY protocol\").AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tif config := v2tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\tif tlsConfig := config.GetTLSConfig(); tlsConfig != nil {\n\t\t\tl = tls.NewListener(l, tlsConfig)\n\t\t}\n\t}\n\treturn l, nil\n}\n"
  },
  {
    "path": "transport/internet/transportcommon/tansportcommon.go",
    "content": "package transportcommon\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/udp/config.go",
    "content": "package udp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/udp/config.pb.go",
    "content": "package udp\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Config struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_udp_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_udp_config_proto_msgTypes[0]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_udp_config_proto_rawDescGZIP(), []int{0}\n}\n\nvar File_transport_internet_udp_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_udp_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\"#transport/internet/udp/config.proto\\x12!v2ray.core.transport.internet.udp\\\"\\b\\n\" +\n\t\"\\x06ConfigB\\x84\\x01\\n\" +\n\t\"%com.v2ray.core.transport.internet.udpP\\x01Z5github.com/v2fly/v2ray-core/v5/transport/internet/udp\\xaa\\x02!V2Ray.Core.Transport.Internet.Udpb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_udp_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_udp_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_udp_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_udp_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_udp_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_udp_config_proto_rawDesc), len(file_transport_internet_udp_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_udp_config_proto_rawDescData\n}\n\nvar file_transport_internet_udp_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_transport_internet_udp_config_proto_goTypes = []any{\n\t(*Config)(nil), // 0: v2ray.core.transport.internet.udp.Config\n}\nvar file_transport_internet_udp_config_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_transport_internet_udp_config_proto_init() }\nfunc file_transport_internet_udp_config_proto_init() {\n\tif File_transport_internet_udp_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_udp_config_proto_rawDesc), len(file_transport_internet_udp_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_udp_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_udp_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_udp_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_udp_config_proto = out.File\n\tfile_transport_internet_udp_config_proto_goTypes = nil\n\tfile_transport_internet_udp_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/udp/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.udp;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Udp\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/udp\";\noption java_package = \"com.v2ray.core.transport.internet.udp\";\noption java_multiple_files = true;\n\nmessage Config {}\n"
  },
  {
    "path": "transport/internet/udp/copy.go",
    "content": "package udp\n\nimport (\n\tgonet \"net\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype dataHandler func(content []byte, address gonet.Addr)\n\ntype copyHandler struct {\n\tonData []dataHandler\n}\n\ntype CopyOption func(*copyHandler)\n\nfunc CopyPacketConn(dst internet.AbstractPacketConnWriter, src internet.AbstractPacketConnReader, options ...CopyOption) error {\n\tvar handler copyHandler\n\tfor _, option := range options {\n\t\toption(&handler)\n\t}\n\tvar buffer [2048]byte\n\tfor {\n\t\tn, addr, err := src.ReadFrom(buffer[:])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfor _, handler := range handler.onData {\n\t\t\thandler(buffer[:n], addr)\n\t\t}\n\n\t\t_, err = dst.WriteTo(buffer[:n], addr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc UpdateActivity(timer signal.ActivityUpdater) CopyOption {\n\treturn func(handler *copyHandler) {\n\t\thandler.onData = append(handler.onData, func(content []byte, address gonet.Addr) {\n\t\t\ttimer.Update()\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "transport/internet/udp/dialer.go",
    "content": "package udp\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName,\n\t\tfunc(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\t\t\tvar sockopt *internet.SocketConfig\n\t\t\tif streamSettings != nil {\n\t\t\t\tsockopt = streamSettings.SocketSettings\n\t\t\t}\n\t\t\tconn, err := internet.DialSystem(ctx, dest, sockopt)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// TODO: handle dialer options\n\t\t\treturn internet.Connection(conn), nil\n\t\t}))\n}\n"
  },
  {
    "path": "transport/internet/udp/dispatcher.go",
    "content": "package udp\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\ntype DispatcherI interface {\n\tcommon.Closable\n\tDispatch(ctx context.Context, destination net.Destination, payload *buf.Buffer)\n}\n\nvar DispatcherConnectionTerminationSignalReceiverMark = \"DispatcherConnectionTerminationSignalReceiverMark\"\n\ntype DispatcherConnectionTerminationSignalReceiver interface {\n\tio.Closer\n}\n"
  },
  {
    "path": "transport/internet/udp/dispatcher_packetaddr.go",
    "content": "package udp\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net/packetaddr\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n)\n\ntype PacketAddrDispatcher struct {\n\tconn     net.PacketConn\n\tcallback ResponseCallback\n\tctx      context.Context\n}\n\nfunc (p PacketAddrDispatcher) Close() error {\n\tif p.ctx.Value(DispatcherConnectionTerminationSignalReceiverMark) != nil {\n\t\tp.ctx.Value(DispatcherConnectionTerminationSignalReceiverMark).(DispatcherConnectionTerminationSignalReceiver).Close()\n\t}\n\treturn p.conn.Close()\n}\n\nfunc (p PacketAddrDispatcher) Dispatch(ctx context.Context, destination net.Destination, payload *buf.Buffer) {\n\tif destination.Network != net.Network_UDP {\n\t\treturn\n\t}\n\n\t// Processing of domain address is unsupported as it adds unpredictable overhead, it will be dropped.\n\tif destination.Address.Family().IsDomain() {\n\t\treturn\n\t}\n\n\tp.conn.WriteTo(payload.Bytes(), &net.UDPAddr{IP: destination.Address.IP(), Port: int(destination.Port.Value())})\n}\n\nfunc (p PacketAddrDispatcher) readWorker() {\n\tfor {\n\t\treadBuf := buf.New()\n\t\tn, addr, err := p.conn.ReadFrom(readBuf.Extend(2048))\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\treadBuf.Resize(0, int32(n))\n\t\tp.callback(p.ctx, &udp.Packet{Payload: readBuf, Source: net.DestinationFromAddr(addr)})\n\t}\n}\n\ntype PacketAddrDispatcherCreator struct {\n\tctx context.Context\n}\n\nfunc NewPacketAddrDispatcherCreator(ctx context.Context) PacketAddrDispatcherCreator {\n\treturn PacketAddrDispatcherCreator{ctx: ctx}\n}\n\nfunc (pdc *PacketAddrDispatcherCreator) NewPacketAddrDispatcher(\n\tdispatcher routing.Dispatcher, callback ResponseCallback,\n) DispatcherI {\n\tpacketConn, _ := packetaddr.CreatePacketAddrConn(pdc.ctx, dispatcher, false)\n\tpd := &PacketAddrDispatcher{conn: packetConn, callback: callback, ctx: pdc.ctx}\n\tgo pd.readWorker()\n\treturn pd\n}\n"
  },
  {
    "path": "transport/internet/udp/dispatcher_split.go",
    "content": "package udp\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n)\n\ntype ResponseCallback func(ctx context.Context, packet *udp.Packet)\n\ntype connEntry struct {\n\tlink   *transport.Link\n\ttimer  signal.ActivityUpdater\n\tcancel context.CancelFunc\n}\n\ntype Dispatcher struct {\n\tsync.RWMutex\n\tconns      map[net.Destination]*connEntry\n\tdispatcher routing.Dispatcher\n\tcallback   ResponseCallback\n}\n\nfunc (v *Dispatcher) Close() error {\n\treturn nil\n}\n\nfunc NewSplitDispatcher(dispatcher routing.Dispatcher, callback ResponseCallback) DispatcherI {\n\treturn &Dispatcher{\n\t\tconns:      make(map[net.Destination]*connEntry),\n\t\tdispatcher: dispatcher,\n\t\tcallback:   callback,\n\t}\n}\n\nfunc (v *Dispatcher) RemoveRay(dest net.Destination) {\n\tv.Lock()\n\tdefer v.Unlock()\n\tif conn, found := v.conns[dest]; found {\n\t\tcommon.Close(conn.link.Reader)\n\t\tcommon.Close(conn.link.Writer)\n\t\tdelete(v.conns, dest)\n\t}\n}\n\nfunc (v *Dispatcher) getInboundRay(ctx context.Context, dest net.Destination) *connEntry {\n\tv.Lock()\n\tdefer v.Unlock()\n\n\tif entry, found := v.conns[dest]; found {\n\t\treturn entry\n\t}\n\n\tnewError(\"establishing new connection for \", dest).WriteToLog()\n\n\tctx, cancel := context.WithCancel(ctx)\n\tremoveRay := func() {\n\t\tcancel()\n\t\tv.RemoveRay(dest)\n\t}\n\ttimer := signal.CancelAfterInactivity(ctx, removeRay, time.Second*300)\n\tlink, _ := v.dispatcher.Dispatch(ctx, dest)\n\tentry := &connEntry{\n\t\tlink:   link,\n\t\ttimer:  timer,\n\t\tcancel: removeRay,\n\t}\n\tv.conns[dest] = entry\n\tgo handleInput(ctx, entry, dest, v.callback)\n\treturn entry\n}\n\nfunc (v *Dispatcher) Dispatch(ctx context.Context, destination net.Destination, payload *buf.Buffer) {\n\t// TODO: Add user to destString\n\tnewError(\"dispatch request to: \", destination).AtDebug().WriteToLog(session.ExportIDToError(ctx))\n\n\tconn := v.getInboundRay(ctx, destination)\n\toutputStream := conn.link.Writer\n\tif outputStream != nil {\n\t\tif err := outputStream.WriteMultiBuffer(buf.MultiBuffer{payload}); err != nil {\n\t\t\tnewError(\"failed to write first UDP payload\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\tconn.cancel()\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc handleInput(ctx context.Context, conn *connEntry, dest net.Destination, callback ResponseCallback) {\n\tdefer conn.cancel()\n\n\tinput := conn.link.Reader\n\ttimer := conn.timer\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t}\n\n\t\tmb, err := input.ReadMultiBuffer()\n\t\tif err != nil {\n\t\t\tnewError(\"failed to handle UDP input\").Base(err).WriteToLog(session.ExportIDToError(ctx))\n\t\t\treturn\n\t\t}\n\t\ttimer.Update()\n\t\tfor _, b := range mb {\n\t\t\tcallback(ctx, &udp.Packet{\n\t\t\t\tPayload: b,\n\t\t\t\tSource:  dest,\n\t\t\t})\n\t\t}\n\t}\n}\n\ntype dispatcherConn struct {\n\tdispatcher *Dispatcher\n\tcache      chan *udp.Packet\n\tdone       *done.Instance\n}\n\nfunc DialDispatcher(ctx context.Context, dispatcher routing.Dispatcher) (net.PacketConn, error) {\n\tc := &dispatcherConn{\n\t\tcache: make(chan *udp.Packet, 16),\n\t\tdone:  done.New(),\n\t}\n\n\td := NewSplitDispatcher(dispatcher, c.callback)\n\tc.dispatcher = d.(*Dispatcher)\n\treturn c, nil\n}\n\nfunc (c *dispatcherConn) callback(ctx context.Context, packet *udp.Packet) {\n\tselect {\n\tcase <-c.done.Wait():\n\t\tpacket.Payload.Release()\n\t\treturn\n\tcase c.cache <- packet:\n\tdefault:\n\t\tpacket.Payload.Release()\n\t\treturn\n\t}\n}\n\nfunc (c *dispatcherConn) ReadFrom(p []byte) (int, net.Addr, error) {\n\tselect {\n\tcase <-c.done.Wait():\n\t\treturn 0, nil, io.EOF\n\tcase packet := <-c.cache:\n\t\tn := copy(p, packet.Payload.Bytes())\n\t\treturn n, &net.UDPAddr{\n\t\t\tIP:   packet.Source.Address.IP(),\n\t\t\tPort: int(packet.Source.Port),\n\t\t}, nil\n\t}\n}\n\nfunc (c *dispatcherConn) WriteTo(p []byte, addr net.Addr) (int, error) {\n\tbuffer := buf.New()\n\traw := buffer.Extend(buf.Size)\n\tn := copy(raw, p)\n\tbuffer.Resize(0, int32(n))\n\n\tctx := context.Background()\n\tc.dispatcher.Dispatch(ctx, net.DestinationFromAddr(addr), buffer)\n\treturn n, nil\n}\n\nfunc (c *dispatcherConn) Close() error {\n\treturn c.done.Close()\n}\n\nfunc (c *dispatcherConn) LocalAddr() net.Addr {\n\treturn &net.UDPAddr{\n\t\tIP:   []byte{0, 0, 0, 0},\n\t\tPort: 0,\n\t}\n}\n\nfunc (c *dispatcherConn) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (c *dispatcherConn) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (c *dispatcherConn) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n"
  },
  {
    "path": "transport/internet/udp/dispatcher_split_test.go",
    "content": "package udp_test\n\nimport (\n\t\"context\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/transport\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\ntype TestDispatcher struct {\n\tOnDispatch func(ctx context.Context, dest net.Destination) (*transport.Link, error)\n}\n\nfunc (d *TestDispatcher) Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error) {\n\treturn d.OnDispatch(ctx, dest)\n}\n\nfunc (d *TestDispatcher) Start() error {\n\treturn nil\n}\n\nfunc (d *TestDispatcher) Close() error {\n\treturn nil\n}\n\nfunc (*TestDispatcher) Type() interface{} {\n\treturn routing.DispatcherType()\n}\n\nfunc TestSameDestinationDispatching(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tuplinkReader, uplinkWriter := pipe.New(pipe.WithSizeLimit(1024))\n\tdownlinkReader, downlinkWriter := pipe.New(pipe.WithSizeLimit(1024))\n\n\tgo func() {\n\t\tfor {\n\t\t\tdata, err := uplinkReader.ReadMultiBuffer()\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\terr = downlinkWriter.WriteMultiBuffer(data)\n\t\t\tcommon.Must(err)\n\t\t}\n\t}()\n\n\tvar count uint32\n\ttd := &TestDispatcher{\n\t\tOnDispatch: func(ctx context.Context, dest net.Destination) (*transport.Link, error) {\n\t\t\tatomic.AddUint32(&count, 1)\n\t\t\treturn &transport.Link{Reader: downlinkReader, Writer: uplinkWriter}, nil\n\t\t},\n\t}\n\tdest := net.UDPDestination(net.LocalHostIP, 53)\n\n\tb := buf.New()\n\tb.WriteString(\"abcd\")\n\n\tvar msgCount uint32\n\tdispatcher := NewSplitDispatcher(td, func(ctx context.Context, packet *udp.Packet) {\n\t\tatomic.AddUint32(&msgCount, 1)\n\t})\n\n\tdispatcher.Dispatch(ctx, dest, b)\n\tfor i := 0; i < 5; i++ {\n\t\tdispatcher.Dispatch(ctx, dest, b)\n\t}\n\n\ttime.Sleep(time.Second)\n\tcancel()\n\n\tif count != 1 {\n\t\tt.Error(\"count: \", count)\n\t}\n\tif v := atomic.LoadUint32(&msgCount); v != 6 {\n\t\tt.Error(\"msgCount: \", v)\n\t}\n}\n"
  },
  {
    "path": "transport/internet/udp/errors.generated.go",
    "content": "package udp\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/udp/hub.go",
    "content": "package udp\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/envctx\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/udp\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\ntype HubOption func(h *Hub)\n\nfunc HubCapacity(capacity int) HubOption {\n\treturn func(h *Hub) {\n\t\th.capacity = capacity\n\t}\n}\n\nfunc HubReceiveOriginalDestination(r bool) HubOption {\n\treturn func(h *Hub) {\n\t\th.recvOrigDest = r\n\t}\n}\n\ntype Hub struct {\n\tconn         *net.UDPConn\n\tconnPacket   net.PacketConn\n\tcache        chan *udp.Packet\n\tcapacity     int\n\trecvOrigDest bool\n}\n\nfunc ListenUDP(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, options ...HubOption) (*Hub, error) {\n\thub := &Hub{\n\t\tcapacity:     256,\n\t\trecvOrigDest: false,\n\t}\n\tfor _, opt := range options {\n\t\topt(hub)\n\t}\n\n\tvar sockopt *internet.SocketConfig\n\tif streamSettings != nil {\n\t\tsockopt = streamSettings.SocketSettings\n\t}\n\tif sockopt != nil && sockopt.ReceiveOriginalDestAddress {\n\t\thub.recvOrigDest = true\n\t}\n\ttransportEnvironment := envctx.EnvironmentFromContext(ctx).(environment.TransportEnvironment)\n\tlistener := transportEnvironment.Listener()\n\tudpConn, err := listener.ListenPacket(ctx, &net.UDPAddr{\n\t\tIP:   address.IP(),\n\t\tPort: int(port),\n\t}, sockopt)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnewError(\"listening UDP on \", address, \":\", port).WriteToLog()\n\tif udpConnDirect, ok := udpConn.(*net.UDPConn); ok {\n\t\thub.conn = udpConnDirect\n\t} else {\n\t\thub.connPacket = udpConn\n\t}\n\n\thub.cache = make(chan *udp.Packet, hub.capacity)\n\n\tgo hub.start()\n\treturn hub, nil\n}\n\n// Close implements net.Listener.\nfunc (h *Hub) Close() error {\n\tif h.connPacket != nil {\n\t\th.connPacket.Close()\n\t\treturn nil\n\t}\n\th.conn.Close()\n\treturn nil\n}\n\nfunc (h *Hub) WriteTo(payload []byte, dest net.Destination) (int, error) {\n\tif h.connPacket != nil {\n\t\treturn h.connPacket.WriteTo(payload, &net.UDPAddr{\n\t\t\tIP:   dest.Address.IP(),\n\t\t\tPort: int(dest.Port),\n\t\t})\n\t}\n\treturn h.conn.WriteToUDP(payload, &net.UDPAddr{\n\t\tIP:   dest.Address.IP(),\n\t\tPort: int(dest.Port),\n\t})\n}\n\nfunc (h *Hub) start() {\n\tc := h.cache\n\tdefer close(c)\n\n\toobBytes := make([]byte, 256)\n\n\tfor {\n\t\tbuffer := buf.New()\n\t\tif h.conn != nil {\n\t\t\tvar noob int\n\t\t\tvar addr *net.UDPAddr\n\t\t\trawBytes := buffer.Extend(buf.Size)\n\t\t\tn, noob, _, addr, err := ReadUDPMsg(h.conn, rawBytes, oobBytes)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to read UDP msg\").Base(err).WriteToLog()\n\t\t\t\tbuffer.Release()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbuffer.Resize(0, int32(n))\n\n\t\t\tif buffer.IsEmpty() {\n\t\t\t\tbuffer.Release()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpayload := &udp.Packet{\n\t\t\t\tPayload: buffer,\n\t\t\t\tSource:  net.UDPDestination(net.IPAddress(addr.IP), net.Port(addr.Port)),\n\t\t\t}\n\t\t\tif h.recvOrigDest && noob > 0 {\n\t\t\t\tpayload.Target = RetrieveOriginalDest(oobBytes[:noob])\n\t\t\t\tif payload.Target.IsValid() {\n\t\t\t\t\tnewError(\"UDP original destination: \", payload.Target).AtDebug().WriteToLog()\n\t\t\t\t} else {\n\t\t\t\t\tnewError(\"failed to read UDP original destination\").WriteToLog()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tselect {\n\t\t\tcase c <- payload:\n\t\t\tdefault:\n\t\t\t\tbuffer.Release()\n\t\t\t\tpayload.Payload = nil\n\t\t\t}\n\t\t} else {\n\t\t\trawBytes := buffer.Extend(buf.Size)\n\t\t\tn, addr, err := h.connPacket.ReadFrom(rawBytes)\n\t\t\tif err != nil {\n\t\t\t\tnewError(\"failed to read UDP msg\").Base(err).WriteToLog()\n\t\t\t\tbuffer.Release()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbuffer.Resize(0, int32(n))\n\n\t\t\tif buffer.IsEmpty() {\n\t\t\t\tbuffer.Release()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpayload := &udp.Packet{\n\t\t\t\tPayload: buffer,\n\t\t\t\tSource:  net.DestinationFromAddr(addr),\n\t\t\t}\n\t\t\tselect {\n\t\t\tcase c <- payload:\n\t\t\tdefault:\n\t\t\t\tbuffer.Release()\n\t\t\t\tpayload.Payload = nil\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Addr implements net.Listener.\nfunc (h *Hub) Addr() net.Addr {\n\tif h.conn == nil {\n\t\treturn h.connPacket.LocalAddr()\n\t}\n\treturn h.conn.LocalAddr()\n}\n\nfunc (h *Hub) Receive() <-chan *udp.Packet {\n\treturn h.cache\n}\n"
  },
  {
    "path": "transport/internet/udp/hub_freebsd.go",
    "content": "//go:build freebsd\n// +build freebsd\n\npackage udp\n\nimport (\n\t\"bytes\"\n\t\"encoding/gob\"\n\t\"io\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\n// RetrieveOriginalDest from stored laddr, caddr\nfunc RetrieveOriginalDest(oob []byte) net.Destination {\n\tdec := gob.NewDecoder(bytes.NewBuffer(oob))\n\tvar la, ra net.UDPAddr\n\tdec.Decode(&la)\n\tdec.Decode(&ra)\n\tip, port, err := internet.OriginalDst(&la, &ra)\n\tif err != nil {\n\t\treturn net.Destination{}\n\t}\n\treturn net.UDPDestination(net.IPAddress(ip), net.Port(port))\n}\n\n// ReadUDPMsg stores laddr, caddr for later use\nfunc ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {\n\tnBytes, addr, err := conn.ReadFromUDP(payload)\n\tif err != nil {\n\t\treturn nBytes, 0, 0, addr, err\n\t}\n\n\tvar buf bytes.Buffer\n\tenc := gob.NewEncoder(&buf)\n\tlocalAddr, ok := conn.LocalAddr().(*net.UDPAddr)\n\tif !ok {\n\t\treturn 0, 0, 0, nil, errors.New(\"invalid local address\")\n\t}\n\tif addr == nil {\n\t\treturn 0, 0, 0, nil, errors.New(\"invalid remote address\")\n\t}\n\tenc.Encode(localAddr)\n\tenc.Encode(addr)\n\n\tvar reader io.Reader = &buf\n\tnoob, _ := reader.Read(oob)\n\n\treturn nBytes, noob, 0, addr, nil\n}\n"
  },
  {
    "path": "transport/internet/udp/hub_linux.go",
    "content": "//go:build linux\n// +build linux\n\npackage udp\n\nimport (\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc RetrieveOriginalDest(oob []byte) net.Destination {\n\tmsgs, err := syscall.ParseSocketControlMessage(oob)\n\tif err != nil {\n\t\treturn net.Destination{}\n\t}\n\tfor _, msg := range msgs {\n\t\tif msg.Header.Level == syscall.SOL_IP && msg.Header.Type == syscall.IP_RECVORIGDSTADDR {\n\t\t\tip := net.IPAddress(msg.Data[4:8])\n\t\t\tport := net.PortFromBytes(msg.Data[2:4])\n\t\t\treturn net.UDPDestination(ip, port)\n\t\t} else if msg.Header.Level == syscall.SOL_IPV6 && msg.Header.Type == unix.IPV6_RECVORIGDSTADDR {\n\t\t\tip := net.IPAddress(msg.Data[8:24])\n\t\t\tport := net.PortFromBytes(msg.Data[2:4])\n\t\t\treturn net.UDPDestination(ip, port)\n\t\t}\n\t}\n\treturn net.Destination{}\n}\n\nfunc ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {\n\treturn conn.ReadMsgUDP(payload, oob)\n}\n"
  },
  {
    "path": "transport/internet/udp/hub_other.go",
    "content": "//go:build !linux && !freebsd\n// +build !linux,!freebsd\n\npackage udp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n)\n\nfunc RetrieveOriginalDest(oob []byte) net.Destination {\n\treturn net.Destination{}\n}\n\nfunc ReadUDPMsg(conn *net.UDPConn, payload []byte, oob []byte) (int, int, int, *net.UDPAddr, error) {\n\tnBytes, addr, err := conn.ReadFromUDP(payload)\n\treturn nBytes, 0, 0, addr, err\n}\n"
  },
  {
    "path": "transport/internet/udp/monodest.go",
    "content": "package udp\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nfunc NewMonoDestUDPConn(conn internet.AbstractPacketConn, addr net.Addr) *MonoDestUDPConn {\n\treturn &MonoDestUDPConn{\n\t\tAbstractPacketConn: conn,\n\t\tdest:               addr,\n\t}\n}\n\ntype MonoDestUDPConn struct {\n\tinternet.AbstractPacketConn\n\tdest net.Addr\n}\n\nfunc (m *MonoDestUDPConn) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tbuffer := buf.New()\n\tbuffer.Extend(2048)\n\tnBytes, _, err := m.AbstractPacketConn.ReadFrom(buffer.Bytes())\n\tif err != nil {\n\t\tbuffer.Release()\n\t\treturn nil, err\n\t}\n\tbuffer.Resize(0, int32(nBytes))\n\treturn buf.MultiBuffer{buffer}, nil\n}\n\nfunc (m *MonoDestUDPConn) WriteMultiBuffer(buffer buf.MultiBuffer) error {\n\tfor _, b := range buffer {\n\t\t_, err := m.AbstractPacketConn.WriteTo(b.Bytes(), m.dest)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tbuf.ReleaseMulti(buffer)\n\treturn nil\n}\n\nfunc (m *MonoDestUDPConn) Read(p []byte) (n int, err error) {\n\tn, _, err = m.AbstractPacketConn.ReadFrom(p)\n\treturn\n}\n\nfunc (m *MonoDestUDPConn) Write(p []byte) (n int, err error) {\n\treturn m.AbstractPacketConn.WriteTo(p, m.dest)\n}\n"
  },
  {
    "path": "transport/internet/udp/udp.go",
    "content": "package udp\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n\nconst protocolName = \"udp\"\n"
  },
  {
    "path": "transport/internet/websocket/config.go",
    "content": "package websocket\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n)\n\nconst protocolName = \"websocket\"\n\nfunc (c *Config) GetNormalizedPath() string {\n\tpath := c.Path\n\tif path == \"\" {\n\t\treturn \"/\"\n\t}\n\tif path[0] != '/' {\n\t\treturn \"/\" + path\n\t}\n\treturn path\n}\n\nfunc (c *Config) GetRequestHeader() http.Header {\n\theader := http.Header{}\n\tfor _, h := range c.Header {\n\t\theader.Add(h.Key, h.Value)\n\t}\n\treturn header\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {\n\t\treturn new(Config)\n\t}))\n}\n"
  },
  {
    "path": "transport/internet/websocket/config.pb.go",
    "content": "package websocket\n\nimport (\n\t_ \"github.com/v2fly/v2ray-core/v5/common/protoext\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n\tunsafe \"unsafe\"\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 Header struct {\n\tstate         protoimpl.MessageState `protogen:\"open.v1\"`\n\tKey           string                 `protobuf:\"bytes,1,opt,name=key,proto3\" json:\"key,omitempty\"`\n\tValue         string                 `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tunknownFields protoimpl.UnknownFields\n\tsizeCache     protoimpl.SizeCache\n}\n\nfunc (x *Header) Reset() {\n\t*x = Header{}\n\tmi := &file_transport_internet_websocket_config_proto_msgTypes[0]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\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_transport_internet_websocket_config_proto_msgTypes[0]\n\tif 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_transport_internet_websocket_config_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Header) GetKey() string {\n\tif x != nil {\n\t\treturn x.Key\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\ntype Config struct {\n\tstate protoimpl.MessageState `protogen:\"open.v1\"`\n\t// URL path to the WebSocket service. Empty value means root(/).\n\tPath                 string    `protobuf:\"bytes,2,opt,name=path,proto3\" json:\"path,omitempty\"`\n\tHeader               []*Header `protobuf:\"bytes,3,rep,name=header,proto3\" json:\"header,omitempty\"`\n\tAcceptProxyProtocol  bool      `protobuf:\"varint,4,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3\" json:\"accept_proxy_protocol,omitempty\"`\n\tMaxEarlyData         int32     `protobuf:\"varint,5,opt,name=max_early_data,json=maxEarlyData,proto3\" json:\"max_early_data,omitempty\"`\n\tUseBrowserForwarding bool      `protobuf:\"varint,6,opt,name=use_browser_forwarding,json=useBrowserForwarding,proto3\" json:\"use_browser_forwarding,omitempty\"`\n\tEarlyDataHeaderName  string    `protobuf:\"bytes,7,opt,name=early_data_header_name,json=earlyDataHeaderName,proto3\" json:\"early_data_header_name,omitempty\"`\n\tunknownFields        protoimpl.UnknownFields\n\tsizeCache            protoimpl.SizeCache\n}\n\nfunc (x *Config) Reset() {\n\t*x = Config{}\n\tmi := &file_transport_internet_websocket_config_proto_msgTypes[1]\n\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\tms.StoreMessageInfo(mi)\n}\n\nfunc (x *Config) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Config) ProtoMessage() {}\n\nfunc (x *Config) ProtoReflect() protoreflect.Message {\n\tmi := &file_transport_internet_websocket_config_proto_msgTypes[1]\n\tif 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 Config.ProtoReflect.Descriptor instead.\nfunc (*Config) Descriptor() ([]byte, []int) {\n\treturn file_transport_internet_websocket_config_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Config) GetPath() string {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn \"\"\n}\n\nfunc (x *Config) GetHeader() []*Header {\n\tif x != nil {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\nfunc (x *Config) GetAcceptProxyProtocol() bool {\n\tif x != nil {\n\t\treturn x.AcceptProxyProtocol\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetMaxEarlyData() int32 {\n\tif x != nil {\n\t\treturn x.MaxEarlyData\n\t}\n\treturn 0\n}\n\nfunc (x *Config) GetUseBrowserForwarding() bool {\n\tif x != nil {\n\t\treturn x.UseBrowserForwarding\n\t}\n\treturn false\n}\n\nfunc (x *Config) GetEarlyDataHeaderName() string {\n\tif x != nil {\n\t\treturn x.EarlyDataHeaderName\n\t}\n\treturn \"\"\n}\n\nvar File_transport_internet_websocket_config_proto protoreflect.FileDescriptor\n\nconst file_transport_internet_websocket_config_proto_rawDesc = \"\" +\n\t\"\\n\" +\n\t\")transport/internet/websocket/config.proto\\x12'v2ray.core.transport.internet.websocket\\x1a common/protoext/extensions.proto\\\"0\\n\" +\n\t\"\\x06Header\\x12\\x10\\n\" +\n\t\"\\x03key\\x18\\x01 \\x01(\\tR\\x03key\\x12\\x14\\n\" +\n\t\"\\x05value\\x18\\x02 \\x01(\\tR\\x05value\\\"\\xd6\\x02\\n\" +\n\t\"\\x06Config\\x12\\x12\\n\" +\n\t\"\\x04path\\x18\\x02 \\x01(\\tR\\x04path\\x12G\\n\" +\n\t\"\\x06header\\x18\\x03 \\x03(\\v2/.v2ray.core.transport.internet.websocket.HeaderR\\x06header\\x122\\n\" +\n\t\"\\x15accept_proxy_protocol\\x18\\x04 \\x01(\\bR\\x13acceptProxyProtocol\\x12$\\n\" +\n\t\"\\x0emax_early_data\\x18\\x05 \\x01(\\x05R\\fmaxEarlyData\\x124\\n\" +\n\t\"\\x16use_browser_forwarding\\x18\\x06 \\x01(\\bR\\x14useBrowserForwarding\\x123\\n\" +\n\t\"\\x16early_data_header_name\\x18\\a \\x01(\\tR\\x13earlyDataHeaderName:$\\x82\\xb5\\x18 \\n\" +\n\t\"\\ttransport\\x12\\x02ws\\x8a\\xff)\\twebsocket\\x90\\xff)\\x01J\\x04\\b\\x01\\x10\\x02B\\x96\\x01\\n\" +\n\t\"+com.v2ray.core.transport.internet.websocketP\\x01Z;github.com/v2fly/v2ray-core/v5/transport/internet/websocket\\xaa\\x02'V2Ray.Core.Transport.Internet.Websocketb\\x06proto3\"\n\nvar (\n\tfile_transport_internet_websocket_config_proto_rawDescOnce sync.Once\n\tfile_transport_internet_websocket_config_proto_rawDescData []byte\n)\n\nfunc file_transport_internet_websocket_config_proto_rawDescGZIP() []byte {\n\tfile_transport_internet_websocket_config_proto_rawDescOnce.Do(func() {\n\t\tfile_transport_internet_websocket_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_transport_internet_websocket_config_proto_rawDesc), len(file_transport_internet_websocket_config_proto_rawDesc)))\n\t})\n\treturn file_transport_internet_websocket_config_proto_rawDescData\n}\n\nvar file_transport_internet_websocket_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_transport_internet_websocket_config_proto_goTypes = []any{\n\t(*Header)(nil), // 0: v2ray.core.transport.internet.websocket.Header\n\t(*Config)(nil), // 1: v2ray.core.transport.internet.websocket.Config\n}\nvar file_transport_internet_websocket_config_proto_depIdxs = []int32{\n\t0, // 0: v2ray.core.transport.internet.websocket.Config.header:type_name -> v2ray.core.transport.internet.websocket.Header\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_transport_internet_websocket_config_proto_init() }\nfunc file_transport_internet_websocket_config_proto_init() {\n\tif File_transport_internet_websocket_config_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: unsafe.Slice(unsafe.StringData(file_transport_internet_websocket_config_proto_rawDesc), len(file_transport_internet_websocket_config_proto_rawDesc)),\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_transport_internet_websocket_config_proto_goTypes,\n\t\tDependencyIndexes: file_transport_internet_websocket_config_proto_depIdxs,\n\t\tMessageInfos:      file_transport_internet_websocket_config_proto_msgTypes,\n\t}.Build()\n\tFile_transport_internet_websocket_config_proto = out.File\n\tfile_transport_internet_websocket_config_proto_goTypes = nil\n\tfile_transport_internet_websocket_config_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "transport/internet/websocket/config.proto",
    "content": "syntax = \"proto3\";\n\npackage v2ray.core.transport.internet.websocket;\noption csharp_namespace = \"V2Ray.Core.Transport.Internet.Websocket\";\noption go_package = \"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\";\noption java_package = \"com.v2ray.core.transport.internet.websocket\";\noption java_multiple_files = true;\n\nimport \"common/protoext/extensions.proto\";\n\nmessage Header {\n  string key = 1;\n  string value = 2;\n}\n\nmessage Config {\n  option (v2ray.core.common.protoext.message_opt).type = \"transport\";\n  option (v2ray.core.common.protoext.message_opt).short_name = \"ws\";\n  option (v2ray.core.common.protoext.message_opt).allow_restricted_mode_load = true;\n\n  option (v2ray.core.common.protoext.message_opt).transport_original_name = \"websocket\";\n\n  reserved 1;\n\n  // URL path to the WebSocket service. Empty value means root(/).\n  string path = 2;\n\n  repeated Header header = 3;\n\n  bool accept_proxy_protocol = 4;\n\n  int32 max_early_data = 5;\n\n  bool use_browser_forwarding = 6;\n\n  string early_data_header_name = 7;\n}\n"
  },
  {
    "path": "transport/internet/websocket/connection.go",
    "content": "package websocket\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/errors\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n)\n\nvar _ buf.Writer = (*connection)(nil)\n\n// connection is a wrapper for net.Conn over WebSocket connection.\ntype connection struct {\n\tconn       *websocket.Conn\n\treader     io.Reader\n\tremoteAddr net.Addr\n\n\tshouldWait        bool\n\tdelayedDialFinish context.Context\n\tfinishedDial      context.CancelFunc\n\tdialer            DelayedDialer\n}\n\ntype DelayedDialer interface {\n\tDial(earlyData []byte) (*websocket.Conn, error)\n}\n\nfunc newConnection(conn *websocket.Conn, remoteAddr net.Addr) *connection {\n\treturn &connection{\n\t\tconn:       conn,\n\t\tremoteAddr: remoteAddr,\n\t}\n}\n\nfunc newConnectionWithEarlyData(conn *websocket.Conn, remoteAddr net.Addr, earlyData io.Reader) *connection {\n\treturn &connection{\n\t\tconn:       conn,\n\t\tremoteAddr: remoteAddr,\n\t\treader:     earlyData,\n\t}\n}\n\nfunc newConnectionWithDelayedDial(dialer DelayedDialer) *connection {\n\tdelayedDialContext, cancelFunc := context.WithCancel(context.Background())\n\treturn &connection{\n\t\tshouldWait:        true,\n\t\tdelayedDialFinish: delayedDialContext,\n\t\tfinishedDial:      cancelFunc,\n\t\tdialer:            dialer,\n\t}\n}\n\nfunc newRelayedConnectionWithDelayedDial(dialer DelayedDialerForwarded) *connectionForwarder {\n\tdelayedDialContext, cancelFunc := context.WithCancel(context.Background())\n\treturn &connectionForwarder{\n\t\tshouldWait:        true,\n\t\tdelayedDialFinish: delayedDialContext,\n\t\tfinishedDial:      cancelFunc,\n\t\tdialer:            dialer,\n\t}\n}\n\nfunc newRelayedConnection(conn io.ReadWriteCloser) *connectionForwarder {\n\treturn &connectionForwarder{\n\t\tReadWriteCloser: conn,\n\t\tshouldWait:      false,\n\t}\n}\n\n// Read implements net.Conn.Read()\nfunc (c *connection) Read(b []byte) (int, error) {\n\tfor {\n\t\treader, err := c.getReader()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tnBytes, err := reader.Read(b)\n\t\tif errors.Cause(err) == io.EOF {\n\t\t\tc.reader = nil\n\t\t\tcontinue\n\t\t}\n\t\treturn nBytes, err\n\t}\n}\n\nfunc (c *connection) getReader() (io.Reader, error) {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\treturn nil, newError(\"unable to read delayed dial websocket connection as it do not exist\")\n\t\t}\n\t}\n\tif c.reader != nil {\n\t\treturn c.reader, nil\n\t}\n\n\t_, reader, err := c.conn.NextReader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.reader = reader\n\treturn reader, nil\n}\n\n// Write implements io.Writer.\nfunc (c *connection) Write(b []byte) (int, error) {\n\tif c.shouldWait {\n\t\tvar err error\n\t\tc.conn, err = c.dialer.Dial(b)\n\t\tc.finishedDial()\n\t\tif err != nil {\n\t\t\treturn 0, newError(\"Unable to proceed with delayed write\").Base(err)\n\t\t}\n\t\tc.remoteAddr = c.conn.RemoteAddr()\n\t\tc.shouldWait = false\n\t\treturn len(b), nil\n\t}\n\tif err := c.conn.WriteMessage(websocket.BinaryMessage, b); err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(b), nil\n}\n\nfunc (c *connection) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tmb = buf.Compact(mb)\n\tmb, err := buf.WriteMultiBuffer(c, mb)\n\tbuf.ReleaseMulti(mb)\n\treturn err\n}\n\nfunc (c *connection) Close() error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\treturn newError(\"unable to close delayed dial websocket connection as it do not exist\")\n\t\t}\n\t}\n\tvar errors []interface{}\n\tif err := c.conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, \"\"), time.Now().Add(time.Second*5)); err != nil {\n\t\terrors = append(errors, err)\n\t}\n\tif err := c.conn.Close(); err != nil {\n\t\terrors = append(errors, err)\n\t}\n\tif len(errors) > 0 {\n\t\treturn newError(\"failed to close connection\").Base(newError(serial.Concat(errors...)))\n\t}\n\treturn nil\n}\n\nfunc (c *connection) LocalAddr() net.Addr {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\tnewError(\"websocket transport is not materialized when LocalAddr() is called\").AtWarning().WriteToLog()\n\t\t\treturn &net.UnixAddr{\n\t\t\t\tName: \"@placeholder\",\n\t\t\t\tNet:  \"unix\",\n\t\t\t}\n\t\t}\n\t}\n\treturn c.conn.LocalAddr()\n}\n\nfunc (c *connection) RemoteAddr() net.Addr {\n\treturn c.remoteAddr\n}\n\nfunc (c *connection) SetDeadline(t time.Time) error {\n\tif err := c.SetReadDeadline(t); err != nil {\n\t\treturn err\n\t}\n\treturn c.SetWriteDeadline(t)\n}\n\nfunc (c *connection) SetReadDeadline(t time.Time) error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\tnewError(\"websocket transport is not materialized when SetReadDeadline() is called\").AtWarning().WriteToLog()\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn c.conn.SetReadDeadline(t)\n}\n\nfunc (c *connection) SetWriteDeadline(t time.Time) error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.conn == nil {\n\t\t\tnewError(\"websocket transport is not materialized when SetWriteDeadline() is called\").AtWarning().WriteToLog()\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn c.conn.SetWriteDeadline(t)\n}\n"
  },
  {
    "path": "transport/internet/websocket/connforwarder.go",
    "content": "package websocket\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n)\n\ntype connectionForwarder struct {\n\tio.ReadWriteCloser\n\n\tshouldWait        bool\n\tdelayedDialFinish context.Context\n\tfinishedDial      context.CancelFunc\n\tdialer            DelayedDialerForwarded\n}\n\nfunc (c *connectionForwarder) Read(p []byte) (n int, err error) {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.ReadWriteCloser == nil {\n\t\t\treturn 0, newError(\"unable to read delayed dial websocket connection as it do not exist\")\n\t\t}\n\t}\n\treturn c.ReadWriteCloser.Read(p)\n}\n\nfunc (c *connectionForwarder) Write(p []byte) (n int, err error) {\n\tif c.shouldWait {\n\t\tvar err error\n\t\tc.ReadWriteCloser, err = c.dialer.Dial(p)\n\t\tc.finishedDial()\n\t\tif err != nil {\n\t\t\treturn 0, newError(\"Unable to proceed with delayed write\").Base(err)\n\t\t}\n\t\tc.shouldWait = false\n\t\treturn len(p), nil\n\t}\n\treturn c.ReadWriteCloser.Write(p)\n}\n\nfunc (c *connectionForwarder) Close() error {\n\tif c.shouldWait {\n\t\t<-c.delayedDialFinish.Done()\n\t\tif c.ReadWriteCloser == nil {\n\t\t\treturn newError(\"unable to close delayed dial websocket connection as it do not exist\")\n\t\t}\n\t}\n\treturn c.ReadWriteCloser.Close()\n}\n\nfunc (c connectionForwarder) LocalAddr() net.Addr {\n\treturn &net.UnixAddr{\n\t\tName: \"not available\",\n\t\tNet:  \"\",\n\t}\n}\n\nfunc (c connectionForwarder) RemoteAddr() net.Addr {\n\treturn &net.UnixAddr{\n\t\tName: \"not available\",\n\t\tNet:  \"\",\n\t}\n}\n\nfunc (c connectionForwarder) SetDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (c connectionForwarder) SetReadDeadline(t time.Time) error {\n\treturn nil\n}\n\nfunc (c connectionForwarder) SetWriteDeadline(t time.Time) error {\n\treturn nil\n}\n\ntype DelayedDialerForwarded interface {\n\tDial(earlyData []byte) (io.ReadWriteCloser, error)\n}\n"
  },
  {
    "path": "transport/internet/websocket/dialer.go",
    "content": "package websocket\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"io\"\n\tgonet \"net\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n\n\tcore \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/security\"\n)\n\n// Dial dials a WebSocket connection to the given destination.\nfunc Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {\n\tnewError(\"creating connection to \", dest).WriteToLog(session.ExportIDToError(ctx))\n\n\tconn, err := dialWebsocket(ctx, dest, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"failed to dial WebSocket\").Base(err)\n\t}\n\treturn internet.Connection(conn), nil\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportDialer(protocolName, Dial))\n}\n\nfunc dialWebsocket(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (net.Conn, error) {\n\twsSettings := streamSettings.ProtocolSettings.(*Config)\n\n\tdialer := &websocket.Dialer{\n\t\tNetDial: func(network, addr string) (net.Conn, error) {\n\t\t\treturn internet.DialSystem(ctx, dest, streamSettings.SocketSettings)\n\t\t},\n\t\tReadBufferSize:   4 * 1024,\n\t\tWriteBufferSize:  4 * 1024,\n\t\tHandshakeTimeout: time.Second * 8,\n\t}\n\n\tprotocol := \"ws\"\n\n\tsecurityEngine, err := security.CreateSecurityEngineFromSettings(ctx, streamSettings)\n\tif err != nil {\n\t\treturn nil, newError(\"unable to create security engine\").Base(err)\n\t}\n\n\tif securityEngine != nil {\n\t\tprotocol = \"wss\"\n\n\t\tdialer.NetDialTLSContext = func(ctx context.Context, network, addr string) (gonet.Conn, error) {\n\t\t\tconn, err := dialer.NetDial(network, addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"dial TLS connection failed\").Base(err)\n\t\t\t}\n\t\t\tconn, err = securityEngine.Client(conn,\n\t\t\t\tsecurity.OptionWithDestination{Dest: dest},\n\t\t\t\tsecurity.OptionWithALPN{ALPNs: []string{\"http/1.1\"}})\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newError(\"unable to create security protocol client from security engine\").Base(err)\n\t\t\t}\n\t\t\treturn conn, nil\n\t\t}\n\t}\n\n\thost := dest.NetAddr()\n\tif (protocol == \"ws\" && dest.Port == 80) || (protocol == \"wss\" && dest.Port == 443) {\n\t\thost = dest.Address.String()\n\t}\n\turi := protocol + \"://\" + host + wsSettings.GetNormalizedPath()\n\n\tif wsSettings.UseBrowserForwarding {\n\t\tvar forwarder extension.BrowserForwarder\n\t\terr := core.RequireFeatures(ctx, func(Forwarder extension.BrowserForwarder) {\n\t\t\tforwarder = Forwarder\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"cannot find browser forwarder service\").Base(err)\n\t\t}\n\t\tif wsSettings.MaxEarlyData != 0 {\n\t\t\treturn newRelayedConnectionWithDelayedDial(&dialerWithEarlyDataRelayed{\n\t\t\t\tforwarder: forwarder,\n\t\t\t\turiBase:   uri,\n\t\t\t\tconfig:    wsSettings,\n\t\t\t}), nil\n\t\t}\n\t\tconn, err := forwarder.DialWebsocket(uri, nil)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"cannot dial with browser forwarder service\").Base(err)\n\t\t}\n\t\treturn newRelayedConnection(conn), nil\n\t}\n\n\tif wsSettings.MaxEarlyData != 0 {\n\t\treturn newConnectionWithDelayedDial(&dialerWithEarlyData{\n\t\t\tdialer:  dialer,\n\t\t\turiBase: uri,\n\t\t\tconfig:  wsSettings,\n\t\t}), nil\n\t}\n\n\tconn, resp, err := dialer.Dial(uri, wsSettings.GetRequestHeader()) // nolint: bodyclose\n\tif err != nil {\n\t\tvar reason string\n\t\tif resp != nil {\n\t\t\treason = resp.Status\n\t\t}\n\t\treturn nil, newError(\"failed to dial to (\", uri, \"): \", reason).Base(err)\n\t}\n\n\treturn newConnection(conn, conn.RemoteAddr()), nil\n}\n\ntype dialerWithEarlyData struct {\n\tdialer  *websocket.Dialer\n\turiBase string\n\tconfig  *Config\n}\n\nfunc (d dialerWithEarlyData) Dial(earlyData []byte) (*websocket.Conn, error) {\n\tearlyDataBuf := bytes.NewBuffer(nil)\n\tbase64EarlyDataEncoder := base64.NewEncoder(base64.RawURLEncoding, earlyDataBuf)\n\n\tearlydata := bytes.NewReader(earlyData)\n\tlimitedEarlyDatareader := io.LimitReader(earlydata, int64(d.config.MaxEarlyData))\n\tn, encerr := io.Copy(base64EarlyDataEncoder, limitedEarlyDatareader)\n\tif encerr != nil {\n\t\treturn nil, newError(\"websocket delayed dialer cannot encode early data\").Base(encerr)\n\t}\n\n\tif errc := base64EarlyDataEncoder.Close(); errc != nil {\n\t\treturn nil, newError(\"websocket delayed dialer cannot encode early data tail\").Base(errc)\n\t}\n\n\tdialFunction := func() (*websocket.Conn, *http.Response, error) {\n\t\treturn d.dialer.Dial(d.uriBase+earlyDataBuf.String(), d.config.GetRequestHeader())\n\t}\n\n\tif d.config.EarlyDataHeaderName != \"\" {\n\t\tdialFunction = func() (*websocket.Conn, *http.Response, error) {\n\t\t\tearlyDataStr := earlyDataBuf.String()\n\t\t\tcurrentHeader := d.config.GetRequestHeader()\n\t\t\tcurrentHeader.Set(d.config.EarlyDataHeaderName, earlyDataStr)\n\t\t\treturn d.dialer.Dial(d.uriBase, currentHeader)\n\t\t}\n\t}\n\n\tconn, resp, err := dialFunction() // nolint: bodyclose\n\tif err != nil {\n\t\tvar reason string\n\t\tif resp != nil {\n\t\t\treason = resp.Status\n\t\t}\n\t\treturn nil, newError(\"failed to dial to (\", d.uriBase, \") with early data: \", reason).Base(err)\n\t}\n\tif n != int64(len(earlyData)) {\n\t\tif errWrite := conn.WriteMessage(websocket.BinaryMessage, earlyData[n:]); errWrite != nil {\n\t\t\treturn nil, newError(\"failed to dial to (\", d.uriBase, \") with early data as write of remainder early data failed: \").Base(errWrite)\n\t\t}\n\t}\n\treturn conn, nil\n}\n\ntype dialerWithEarlyDataRelayed struct {\n\tforwarder extension.BrowserForwarder\n\turiBase   string\n\tconfig    *Config\n}\n\nfunc (d dialerWithEarlyDataRelayed) Dial(earlyData []byte) (io.ReadWriteCloser, error) {\n\tearlyDataBuf := bytes.NewBuffer(nil)\n\tbase64EarlyDataEncoder := base64.NewEncoder(base64.RawURLEncoding, earlyDataBuf)\n\n\tearlydata := bytes.NewReader(earlyData)\n\tlimitedEarlyDatareader := io.LimitReader(earlydata, int64(d.config.MaxEarlyData))\n\tn, encerr := io.Copy(base64EarlyDataEncoder, limitedEarlyDatareader)\n\tif encerr != nil {\n\t\treturn nil, newError(\"websocket delayed dialer cannot encode early data\").Base(encerr)\n\t}\n\n\tif errc := base64EarlyDataEncoder.Close(); errc != nil {\n\t\treturn nil, newError(\"websocket delayed dialer cannot encode early data tail\").Base(errc)\n\t}\n\n\tdialFunction := func() (io.ReadWriteCloser, error) {\n\t\treturn d.forwarder.DialWebsocket(d.uriBase+earlyDataBuf.String(), d.config.GetRequestHeader())\n\t}\n\n\tif d.config.EarlyDataHeaderName != \"\" {\n\t\tearlyDataStr := earlyDataBuf.String()\n\t\tcurrentHeader := d.config.GetRequestHeader()\n\t\tcurrentHeader.Set(d.config.EarlyDataHeaderName, earlyDataStr)\n\t\treturn d.forwarder.DialWebsocket(d.uriBase, currentHeader)\n\t}\n\n\tconn, err := dialFunction()\n\tif err != nil {\n\t\tvar reason string\n\t\treturn nil, newError(\"failed to dial to (\", d.uriBase, \") with early data: \", reason).Base(err)\n\t}\n\tif n != int64(len(earlyData)) {\n\t\tif _, errWrite := conn.Write(earlyData[n:]); errWrite != nil {\n\t\t\treturn nil, newError(\"failed to dial to (\", d.uriBase, \") with early data as write of remainder early data failed: \").Base(errWrite)\n\t\t}\n\t}\n\treturn conn, nil\n}\n"
  },
  {
    "path": "transport/internet/websocket/errors.generated.go",
    "content": "package websocket\n\nimport \"github.com/v2fly/v2ray-core/v5/common/errors\"\n\ntype errPathObjHolder struct{}\n\nfunc newError(values ...interface{}) *errors.Error {\n\treturn errors.New(values...).WithPathObj(errPathObjHolder{})\n}\n"
  },
  {
    "path": "transport/internet/websocket/hub.go",
    "content": "package websocket\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\thttp_proto \"github.com/v2fly/v2ray-core/v5/common/protocol/http\"\n\t\"github.com/v2fly/v2ray-core/v5/common/session\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\tv2tls \"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n)\n\ntype requestHandler struct {\n\tpath                string\n\tln                  *Listener\n\tearlyDataEnabled    bool\n\tearlyDataHeaderName string\n}\n\nvar upgrader = &websocket.Upgrader{\n\tReadBufferSize:   4 * 1024,\n\tWriteBufferSize:  4 * 1024,\n\tHandshakeTimeout: time.Second * 4,\n\tCheckOrigin: func(r *http.Request) bool {\n\t\treturn true\n\t},\n}\n\nfunc (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {\n\tresponseHeader := http.Header{}\n\n\tvar earlyData io.Reader\n\tif !h.earlyDataEnabled { // nolint: gocritic\n\t\tif request.URL.Path != h.path {\n\t\t\twriter.WriteHeader(http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t} else if h.earlyDataHeaderName != \"\" {\n\t\tif request.URL.Path != h.path {\n\t\t\twriter.WriteHeader(http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tearlyDataStr := request.Header.Get(h.earlyDataHeaderName)\n\t\tearlyData = base64.NewDecoder(base64.RawURLEncoding, bytes.NewReader([]byte(earlyDataStr)))\n\t\tif strings.EqualFold(\"Sec-WebSocket-Protocol\", h.earlyDataHeaderName) {\n\t\t\tresponseHeader.Set(h.earlyDataHeaderName, earlyDataStr)\n\t\t}\n\t} else {\n\t\tif strings.HasPrefix(request.URL.RequestURI(), h.path) {\n\t\t\tearlyDataStr := request.URL.RequestURI()[len(h.path):]\n\t\t\tearlyData = base64.NewDecoder(base64.RawURLEncoding, bytes.NewReader([]byte(earlyDataStr)))\n\t\t} else {\n\t\t\twriter.WriteHeader(http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t}\n\n\tconn, err := upgrader.Upgrade(writer, request, responseHeader)\n\tif err != nil {\n\t\tnewError(\"failed to convert to WebSocket connection\").Base(err).WriteToLog()\n\t\treturn\n\t}\n\n\tforwardedAddrs := http_proto.ParseXForwardedFor(request.Header)\n\tremoteAddr := conn.RemoteAddr()\n\tif len(forwardedAddrs) > 0 && forwardedAddrs[0].Family().IsIP() {\n\t\tremoteAddr = &net.TCPAddr{\n\t\t\tIP:   forwardedAddrs[0].IP(),\n\t\t\tPort: int(0),\n\t\t}\n\t}\n\tif earlyData == nil {\n\t\th.ln.addConn(newConnection(conn, remoteAddr))\n\t} else {\n\t\th.ln.addConn(newConnectionWithEarlyData(conn, remoteAddr, earlyData))\n\t}\n}\n\ntype Listener struct {\n\tsync.Mutex\n\tserver   http.Server\n\tlistener net.Listener\n\tconfig   *Config\n\taddConn  internet.ConnHandler\n}\n\nfunc ListenWS(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {\n\tl := &Listener{\n\t\taddConn: addConn,\n\t}\n\twsSettings := streamSettings.ProtocolSettings.(*Config)\n\tl.config = wsSettings\n\tif l.config != nil {\n\t\tif streamSettings.SocketSettings == nil {\n\t\t\tstreamSettings.SocketSettings = &internet.SocketConfig{}\n\t\t}\n\t\tstreamSettings.SocketSettings.AcceptProxyProtocol = l.config.AcceptProxyProtocol\n\t}\n\tvar listener net.Listener\n\tvar err error\n\tif port == net.Port(0) { // unix\n\t\tlistener, err = internet.ListenSystem(ctx, &net.UnixAddr{\n\t\t\tName: address.Domain(),\n\t\t\tNet:  \"unix\",\n\t\t}, streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen unix domain socket(for WS) on \", address).Base(err)\n\t\t}\n\t\tnewError(\"listening unix domain socket(for WS) on \", address).WriteToLog(session.ExportIDToError(ctx))\n\t} else { // tcp\n\t\tlistener, err = internet.ListenSystem(ctx, &net.TCPAddr{\n\t\t\tIP:   address.IP(),\n\t\t\tPort: int(port),\n\t\t}, streamSettings.SocketSettings)\n\t\tif err != nil {\n\t\t\treturn nil, newError(\"failed to listen TCP(for WS) on \", address, \":\", port).Base(err)\n\t\t}\n\t\tnewError(\"listening TCP(for WS) on \", address, \":\", port).WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tif streamSettings.SocketSettings != nil && streamSettings.SocketSettings.AcceptProxyProtocol {\n\t\tnewError(\"accepting PROXY protocol\").AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t}\n\n\tif config := v2tls.ConfigFromStreamSettings(streamSettings); config != nil {\n\t\tif tlsConfig := config.GetTLSConfig(); tlsConfig != nil {\n\t\t\tlistener = tls.NewListener(listener, tlsConfig)\n\t\t}\n\t}\n\n\tl.listener = listener\n\tuseEarlyData := false\n\tearlyDataHeaderName := \"\"\n\tif wsSettings.MaxEarlyData != 0 {\n\t\tuseEarlyData = true\n\t\tearlyDataHeaderName = wsSettings.EarlyDataHeaderName\n\t}\n\n\tl.server = http.Server{\n\t\tHandler: &requestHandler{\n\t\t\tpath:                wsSettings.GetNormalizedPath(),\n\t\t\tln:                  l,\n\t\t\tearlyDataEnabled:    useEarlyData,\n\t\t\tearlyDataHeaderName: earlyDataHeaderName,\n\t\t},\n\t\tReadHeaderTimeout: time.Second * 4,\n\t\tMaxHeaderBytes:    http.DefaultMaxHeaderBytes,\n\t}\n\n\tgo func() {\n\t\tif err := l.server.Serve(l.listener); err != nil {\n\t\t\tnewError(\"failed to serve http for WebSocket\").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))\n\t\t}\n\t}()\n\n\treturn l, err\n}\n\n// Addr implements net.Listener.Addr().\nfunc (ln *Listener) Addr() net.Addr {\n\treturn ln.listener.Addr()\n}\n\n// Close implements net.Listener.Close().\nfunc (ln *Listener) Close() error {\n\treturn ln.listener.Close()\n}\n\nfunc init() {\n\tcommon.Must(internet.RegisterTransportListener(protocolName, ListenWS))\n}\n"
  },
  {
    "path": "transport/internet/websocket/ws.go",
    "content": "/*\nPackage websocket implements Websocket transport\n\nWebsocket transport implements an HTTP(S) compliable, surveillance proof transport method with plausible deniability.\n*/\npackage websocket\n\n//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen\n"
  },
  {
    "path": "transport/internet/websocket/ws_test.go",
    "content": "package websocket_test\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet\"\n\t\"github.com/v2fly/v2ray-core/v5/transport/internet/tls\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/internet/websocket\"\n)\n\nfunc Test_listenWSAndDial(t *testing.T) {\n\tlisten, err := ListenWS(context.Background(), net.LocalHostIP, 13146, &internet.MemoryStreamConfig{\n\t\tProtocolName: \"websocket\",\n\t\tProtocolSettings: &Config{\n\t\t\tPath: \"ws\",\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tgo func(c internet.Connection) {\n\t\t\tdefer c.Close()\n\n\t\t\tvar b [1024]byte\n\t\t\t_, err := c.Read(b[:])\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tcommon.Must2(c.Write([]byte(\"Response\")))\n\t\t}(conn)\n\t})\n\tcommon.Must(err)\n\n\tctx := context.Background()\n\tstreamSettings := &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"websocket\",\n\t\tProtocolSettings: &Config{Path: \"ws\"},\n\t}\n\tconn, err := Dial(ctx, net.TCPDestination(net.DomainAddress(\"localhost\"), 13146), streamSettings)\n\n\tcommon.Must(err)\n\t_, err = conn.Write([]byte(\"Test connection 1\"))\n\tcommon.Must(err)\n\n\tvar b [1024]byte\n\tn, err := conn.Read(b[:])\n\tcommon.Must(err)\n\tif string(b[:n]) != \"Response\" {\n\t\tt.Error(\"response: \", string(b[:n]))\n\t}\n\n\tcommon.Must(conn.Close())\n\t<-time.After(time.Second * 5)\n\tconn, err = Dial(ctx, net.TCPDestination(net.DomainAddress(\"localhost\"), 13146), streamSettings)\n\tcommon.Must(err)\n\t_, err = conn.Write([]byte(\"Test connection 2\"))\n\tcommon.Must(err)\n\tn, err = conn.Read(b[:])\n\tcommon.Must(err)\n\tif string(b[:n]) != \"Response\" {\n\t\tt.Error(\"response: \", string(b[:n]))\n\t}\n\tcommon.Must(conn.Close())\n\n\tcommon.Must(listen.Close())\n}\n\nfunc TestDialWithRemoteAddr(t *testing.T) {\n\tlisten, err := ListenWS(context.Background(), net.LocalHostIP, 13148, &internet.MemoryStreamConfig{\n\t\tProtocolName: \"websocket\",\n\t\tProtocolSettings: &Config{\n\t\t\tPath: \"ws\",\n\t\t},\n\t}, func(conn internet.Connection) {\n\t\tgo func(c internet.Connection) {\n\t\t\tdefer c.Close()\n\n\t\t\tvar b [1024]byte\n\t\t\t_, err := c.Read(b[:])\n\t\t\t// common.Must(err)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t_, err = c.Write([]byte(\"Response\"))\n\t\t\tcommon.Must(err)\n\t\t}(conn)\n\t})\n\tcommon.Must(err)\n\n\tconn, err := Dial(context.Background(), net.TCPDestination(net.DomainAddress(\"localhost\"), 13148), &internet.MemoryStreamConfig{\n\t\tProtocolName:     \"websocket\",\n\t\tProtocolSettings: &Config{Path: \"ws\", Header: []*Header{{Key: \"X-Forwarded-For\", Value: \"1.1.1.1\"}}},\n\t})\n\n\tcommon.Must(err)\n\t_, err = conn.Write([]byte(\"Test connection 1\"))\n\tcommon.Must(err)\n\n\tvar b [1024]byte\n\tn, err := conn.Read(b[:])\n\tcommon.Must(err)\n\tif string(b[:n]) != \"Response\" {\n\t\tt.Error(\"response: \", string(b[:n]))\n\t}\n\n\tcommon.Must(listen.Close())\n}\n\nfunc Test_listenWSAndDial_TLS(t *testing.T) {\n\tif runtime.GOARCH == \"arm64\" {\n\t\treturn\n\t}\n\n\tstart := time.Now()\n\n\tstreamSettings := &internet.MemoryStreamConfig{\n\t\tProtocolName: \"websocket\",\n\t\tProtocolSettings: &Config{\n\t\t\tPath: \"wss\",\n\t\t},\n\t\tSecurityType: \"tls\",\n\t\tSecuritySettings: &tls.Config{\n\t\t\tAllowInsecure: true,\n\t\t\tCertificate:   []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.CommonName(\"localhost\")))},\n\t\t},\n\t}\n\tlisten, err := ListenWS(context.Background(), net.LocalHostIP, 13143, streamSettings, func(conn internet.Connection) {\n\t\tgo func() {\n\t\t\t_ = conn.Close()\n\t\t}()\n\t})\n\tcommon.Must(err)\n\tdefer listen.Close()\n\n\tconn, err := Dial(context.Background(), net.TCPDestination(net.DomainAddress(\"localhost\"), 13143), streamSettings)\n\tcommon.Must(err)\n\t_ = conn.Close()\n\n\tend := time.Now()\n\tif !end.Before(start.Add(time.Second * 5)) {\n\t\tt.Error(\"end: \", end, \" start: \", start)\n\t}\n}\n"
  },
  {
    "path": "transport/link.go",
    "content": "package transport\n\nimport \"github.com/v2fly/v2ray-core/v5/common/buf\"\n\n// Link is a utility for connecting between an inbound and an outbound proxy handler.\ntype Link struct {\n\tReader buf.Reader\n\tWriter buf.Writer\n}\n"
  },
  {
    "path": "transport/pipe/impl.go",
    "content": "package pipe\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n)\n\ntype state byte\n\nconst (\n\topen state = iota\n\tclosed\n\terrord\n)\n\ntype pipeOption struct {\n\tlimit           int32 // maximum buffer size in bytes\n\tdiscardOverflow bool\n}\n\nfunc (o *pipeOption) isFull(curSize int32) bool {\n\treturn o.limit >= 0 && curSize > o.limit\n}\n\ntype pipe struct {\n\tsync.Mutex\n\tdata        buf.MultiBuffer\n\treadSignal  *signal.Notifier\n\twriteSignal *signal.Notifier\n\tdone        *done.Instance\n\toption      pipeOption\n\tstate       state\n}\n\nvar (\n\terrBufferFull = errors.New(\"buffer full\")\n\terrSlowDown   = errors.New(\"slow down\")\n)\n\nfunc (p *pipe) getState(forRead bool) error {\n\tswitch p.state {\n\tcase open:\n\t\tif !forRead && p.option.isFull(p.data.Len()) {\n\t\t\treturn errBufferFull\n\t\t}\n\t\treturn nil\n\tcase closed:\n\t\tif !forRead {\n\t\t\treturn io.ErrClosedPipe\n\t\t}\n\t\tif !p.data.IsEmpty() {\n\t\t\treturn nil\n\t\t}\n\t\treturn io.EOF\n\tcase errord:\n\t\treturn io.ErrClosedPipe\n\tdefault:\n\t\tpanic(\"impossible case\")\n\t}\n}\n\nfunc (p *pipe) readMultiBufferInternal() (buf.MultiBuffer, error) {\n\tp.Lock()\n\tdefer p.Unlock()\n\n\tif err := p.getState(true); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdata := p.data\n\tp.data = nil\n\treturn data, nil\n}\n\nfunc (p *pipe) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\tfor {\n\t\tdata, err := p.readMultiBufferInternal()\n\t\tif data != nil || err != nil {\n\t\t\tp.writeSignal.Signal()\n\t\t\treturn data, err\n\t\t}\n\n\t\tselect {\n\t\tcase <-p.readSignal.Wait():\n\t\tcase <-p.done.Wait():\n\t\t}\n\t}\n}\n\nfunc (p *pipe) ReadMultiBufferTimeout(d time.Duration) (buf.MultiBuffer, error) {\n\ttimer := time.NewTimer(d)\n\tdefer timer.Stop()\n\n\tfor {\n\t\tdata, err := p.readMultiBufferInternal()\n\t\tif data != nil || err != nil {\n\t\t\tp.writeSignal.Signal()\n\t\t\treturn data, err\n\t\t}\n\n\t\tselect {\n\t\tcase <-p.readSignal.Wait():\n\t\tcase <-p.done.Wait():\n\t\tcase <-timer.C:\n\t\t\treturn nil, buf.ErrReadTimeout\n\t\t}\n\t}\n}\n\nfunc (p *pipe) writeMultiBufferInternal(mb buf.MultiBuffer) error {\n\tp.Lock()\n\tdefer p.Unlock()\n\n\tif err := p.getState(false); err != nil {\n\t\treturn err\n\t}\n\n\tif p.data == nil {\n\t\tp.data = mb\n\t\treturn nil\n\t}\n\n\tp.data, _ = buf.MergeMulti(p.data, mb)\n\treturn errSlowDown\n}\n\nfunc (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\tif mb.IsEmpty() {\n\t\treturn nil\n\t}\n\n\tfor {\n\t\terr := p.writeMultiBufferInternal(mb)\n\t\tif err == nil {\n\t\t\tp.readSignal.Signal()\n\t\t\treturn nil\n\t\t}\n\n\t\tif err == errSlowDown {\n\t\t\tp.readSignal.Signal()\n\n\t\t\t// Yield current goroutine. Hopefully the reading counterpart can pick up the payload.\n\t\t\truntime.Gosched()\n\t\t\treturn nil\n\t\t}\n\n\t\tif err == errBufferFull && p.option.discardOverflow {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\treturn nil\n\t\t}\n\n\t\tif err != errBufferFull {\n\t\t\tbuf.ReleaseMulti(mb)\n\t\t\tp.readSignal.Signal()\n\t\t\treturn err\n\t\t}\n\n\t\tselect {\n\t\tcase <-p.writeSignal.Wait():\n\t\tcase <-p.done.Wait():\n\t\t\treturn io.ErrClosedPipe\n\t\t}\n\t}\n}\n\nfunc (p *pipe) Close() error {\n\tp.Lock()\n\tdefer p.Unlock()\n\n\tif p.state == closed || p.state == errord {\n\t\treturn nil\n\t}\n\n\tp.state = closed\n\tcommon.Must(p.done.Close())\n\treturn nil\n}\n\n// Interrupt implements common.Interruptible.\nfunc (p *pipe) Interrupt() {\n\tp.Lock()\n\tdefer p.Unlock()\n\n\tif p.state == closed || p.state == errord {\n\t\treturn\n\t}\n\n\tp.state = errord\n\n\tif !p.data.IsEmpty() {\n\t\tbuf.ReleaseMulti(p.data)\n\t\tp.data = nil\n\t}\n\n\tcommon.Must(p.done.Close())\n}\n"
  },
  {
    "path": "transport/pipe/pipe.go",
    "content": "package pipe\n\nimport (\n\t\"context\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/signal\"\n\t\"github.com/v2fly/v2ray-core/v5/common/signal/done\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n)\n\n// Option for creating new Pipes.\ntype Option func(*pipeOption)\n\n// WithoutSizeLimit returns an Option for Pipe to have no size limit.\nfunc WithoutSizeLimit() Option {\n\treturn func(opt *pipeOption) {\n\t\topt.limit = -1\n\t}\n}\n\n// WithSizeLimit returns an Option for Pipe to have the given size limit.\nfunc WithSizeLimit(limit int32) Option {\n\treturn func(opt *pipeOption) {\n\t\topt.limit = limit\n\t}\n}\n\n// DiscardOverflow returns an Option for Pipe to discard writes if full.\nfunc DiscardOverflow() Option {\n\treturn func(opt *pipeOption) {\n\t\topt.discardOverflow = true\n\t}\n}\n\n// OptionsFromContext returns a list of Options from context.\nfunc OptionsFromContext(ctx context.Context) []Option {\n\tvar opt []Option\n\n\tbp := policy.BufferPolicyFromContext(ctx)\n\tif bp.PerConnection >= 0 {\n\t\topt = append(opt, WithSizeLimit(bp.PerConnection))\n\t} else {\n\t\topt = append(opt, WithoutSizeLimit())\n\t}\n\n\treturn opt\n}\n\n// New creates a new Reader and Writer that connects to each other.\nfunc New(opts ...Option) (*Reader, *Writer) {\n\tp := &pipe{\n\t\treadSignal:  signal.NewNotifier(),\n\t\twriteSignal: signal.NewNotifier(),\n\t\tdone:        done.New(),\n\t\toption: pipeOption{\n\t\t\tlimit: -1,\n\t\t},\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(&(p.option))\n\t}\n\n\treturn &Reader{\n\t\t\tpipe: p,\n\t\t}, &Writer{\n\t\t\tpipe: p,\n\t\t}\n}\n"
  },
  {
    "path": "transport/pipe/pipe_test.go",
    "content": "package pipe_test\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n\t. \"github.com/v2fly/v2ray-core/v5/transport/pipe\"\n)\n\nfunc TestPipeReadWrite(t *testing.T) {\n\tpReader, pWriter := New(WithSizeLimit(1024))\n\n\tb := buf.New()\n\tb.WriteString(\"abcd\")\n\tcommon.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))\n\n\tb2 := buf.New()\n\tb2.WriteString(\"efg\")\n\tcommon.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b2}))\n\n\trb, err := pReader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif r := cmp.Diff(rb.String(), \"abcdefg\"); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestPipeInterrupt(t *testing.T) {\n\tpReader, pWriter := New(WithSizeLimit(1024))\n\tpayload := []byte{'a', 'b', 'c', 'd'}\n\tb := buf.New()\n\tb.Write(payload)\n\tcommon.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))\n\tpWriter.Interrupt()\n\n\trb, err := pReader.ReadMultiBuffer()\n\tif err != io.ErrClosedPipe {\n\t\tt.Fatal(\"expect io.ErrClosePipe, but got \", err)\n\t}\n\tif !rb.IsEmpty() {\n\t\tt.Fatal(\"expect empty buffer, but got \", rb.Len())\n\t}\n}\n\nfunc TestPipeClose(t *testing.T) {\n\tpReader, pWriter := New(WithSizeLimit(1024))\n\tpayload := []byte{'a', 'b', 'c', 'd'}\n\tb := buf.New()\n\tcommon.Must2(b.Write(payload))\n\tcommon.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{b}))\n\tcommon.Must(pWriter.Close())\n\n\trb, err := pReader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif rb.String() != string(payload) {\n\t\tt.Fatal(\"expect content \", string(payload), \" but actually \", rb.String())\n\t}\n\n\trb, err = pReader.ReadMultiBuffer()\n\tif err != io.EOF {\n\t\tt.Fatal(\"expected EOF, but got \", err)\n\t}\n\tif !rb.IsEmpty() {\n\t\tt.Fatal(\"expect empty buffer, but got \", rb.String())\n\t}\n}\n\nfunc TestPipeLimitZero(t *testing.T) {\n\tpReader, pWriter := New(WithSizeLimit(0))\n\tbb := buf.New()\n\tcommon.Must2(bb.Write([]byte{'a', 'b'}))\n\tcommon.Must(pWriter.WriteMultiBuffer(buf.MultiBuffer{bb}))\n\n\tvar errg errgroup.Group\n\terrg.Go(func() error {\n\t\tb := buf.New()\n\t\tb.Write([]byte{'c', 'd'})\n\t\treturn pWriter.WriteMultiBuffer(buf.MultiBuffer{b})\n\t})\n\terrg.Go(func() error {\n\t\ttime.Sleep(time.Second)\n\n\t\tvar container buf.MultiBufferContainer\n\t\tif err := buf.Copy(pReader, &container); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif r := cmp.Diff(container.String(), \"abcd\"); r != \"\" {\n\t\t\treturn errors.New(r)\n\t\t}\n\t\treturn nil\n\t})\n\terrg.Go(func() error {\n\t\ttime.Sleep(time.Second * 2)\n\t\treturn pWriter.Close()\n\t})\n\tif err := errg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestPipeWriteMultiThread(t *testing.T) {\n\tpReader, pWriter := New(WithSizeLimit(0))\n\n\tvar errg errgroup.Group\n\tfor i := 0; i < 10; i++ {\n\t\terrg.Go(func() error {\n\t\t\tb := buf.New()\n\t\t\tb.WriteString(\"abcd\")\n\t\t\treturn pWriter.WriteMultiBuffer(buf.MultiBuffer{b})\n\t\t})\n\t}\n\ttime.Sleep(time.Millisecond * 100)\n\tpWriter.Close()\n\terrg.Wait()\n\n\tb, err := pReader.ReadMultiBuffer()\n\tcommon.Must(err)\n\tif r := cmp.Diff(b[0].Bytes(), []byte{'a', 'b', 'c', 'd'}); r != \"\" {\n\t\tt.Error(r)\n\t}\n}\n\nfunc TestInterfaces(t *testing.T) {\n\t_ = (buf.Reader)(new(Reader))\n\t_ = (buf.TimeoutReader)(new(Reader))\n\n\t_ = (common.Interruptible)(new(Reader))\n\t_ = (common.Interruptible)(new(Writer))\n\t_ = (common.Closable)(new(Writer))\n}\n\nfunc BenchmarkPipeReadWrite(b *testing.B) {\n\treader, writer := New(WithoutSizeLimit())\n\ta := buf.New()\n\ta.Extend(buf.Size)\n\tc := buf.MultiBuffer{a}\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tcommon.Must(writer.WriteMultiBuffer(c))\n\t\td, err := reader.ReadMultiBuffer()\n\t\tcommon.Must(err)\n\t\tc = d\n\t}\n}\n"
  },
  {
    "path": "transport/pipe/reader.go",
    "content": "package pipe\n\nimport (\n\t\"time\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\n// Reader is a buf.Reader that reads content from a pipe.\ntype Reader struct {\n\tpipe *pipe\n}\n\n// ReadMultiBuffer implements buf.Reader.\nfunc (r *Reader) ReadMultiBuffer() (buf.MultiBuffer, error) {\n\treturn r.pipe.ReadMultiBuffer()\n}\n\n// ReadMultiBufferTimeout reads content from a pipe within the given duration, or returns buf.ErrTimeout otherwise.\nfunc (r *Reader) ReadMultiBufferTimeout(d time.Duration) (buf.MultiBuffer, error) {\n\treturn r.pipe.ReadMultiBufferTimeout(d)\n}\n\n// Interrupt implements common.Interruptible.\nfunc (r *Reader) Interrupt() {\n\tr.pipe.Interrupt()\n}\n"
  },
  {
    "path": "transport/pipe/writer.go",
    "content": "package pipe\n\nimport (\n\t\"github.com/v2fly/v2ray-core/v5/common/buf\"\n)\n\n// Writer is a buf.Writer that writes data into a pipe.\ntype Writer struct {\n\tpipe *pipe\n}\n\n// WriteMultiBuffer implements buf.Writer.\nfunc (w *Writer) WriteMultiBuffer(mb buf.MultiBuffer) error {\n\treturn w.pipe.WriteMultiBuffer(mb)\n}\n\n// Close implements io.Closer. After the pipe is closed, writing to the pipe will return io.ErrClosedPipe, while reading will return io.EOF.\nfunc (w *Writer) Close() error {\n\treturn w.pipe.Close()\n}\n\n// Interrupt implements common.Interruptible.\nfunc (w *Writer) Interrupt() {\n\tw.pipe.Interrupt()\n}\n"
  },
  {
    "path": "v2ray.go",
    "content": "package core\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\tsync \"sync\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/deferredpersistentstorage\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/filesystemimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/features/extension/storage\"\n\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/systemnetworkimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/environment/transientstorageimpl\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/features\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns/localdns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/inbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/features/policy\"\n\t\"github.com/v2fly/v2ray-core/v5/features/routing\"\n\t\"github.com/v2fly/v2ray-core/v5/features/stats\"\n)\n\n// Server is an instance of V2Ray. At any time, there must be at most one Server instance running.\ntype Server interface {\n\tcommon.Runnable\n}\n\n// ServerType returns the type of the server.\nfunc ServerType() interface{} {\n\treturn (*Instance)(nil)\n}\n\ntype resolution struct {\n\tdeps     []reflect.Type\n\tcallback interface{}\n}\n\nfunc getFeature(allFeatures []features.Feature, t reflect.Type) features.Feature {\n\tfor _, f := range allFeatures {\n\t\tif reflect.TypeOf(f.Type()) == t {\n\t\t\treturn f\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (r *resolution) resolve(allFeatures []features.Feature) (bool, error) {\n\tvar fs []features.Feature\n\tfor _, d := range r.deps {\n\t\tf := getFeature(allFeatures, d)\n\t\tif f == nil {\n\t\t\treturn false, nil\n\t\t}\n\t\tfs = append(fs, f)\n\t}\n\n\tcallback := reflect.ValueOf(r.callback)\n\tvar input []reflect.Value\n\tcallbackType := callback.Type()\n\tfor i := 0; i < callbackType.NumIn(); i++ {\n\t\tpt := callbackType.In(i)\n\t\tfor _, f := range fs {\n\t\t\tif reflect.TypeOf(f).AssignableTo(pt) {\n\t\t\t\tinput = append(input, reflect.ValueOf(f))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(input) != callbackType.NumIn() {\n\t\tpanic(\"Can't get all input parameters\")\n\t}\n\n\tvar err error\n\tret := callback.Call(input)\n\terrInterface := reflect.TypeOf((*error)(nil)).Elem()\n\tfor i := len(ret) - 1; i >= 0; i-- {\n\t\tif ret[i].Type() == errInterface {\n\t\t\tv := ret[i].Interface()\n\t\t\tif v != nil {\n\t\t\t\terr = v.(error)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn true, err\n}\n\n// Instance combines all functionalities in V2Ray.\ntype Instance struct {\n\taccess             sync.Mutex\n\tfeatures           []features.Feature\n\tfeatureResolutions []resolution\n\trunning            bool\n\tenv                environment.RootEnvironment\n\n\tctx context.Context\n}\n\nfunc AddInboundHandler(server *Instance, config *InboundHandlerConfig) error {\n\tinboundManager := server.GetFeature(inbound.ManagerType()).(inbound.Manager)\n\tproxyEnv := server.env.ProxyEnvironment(\"i\" + config.Tag)\n\trawHandler, err := CreateObjectWithEnvironment(server, config, proxyEnv)\n\tif err != nil {\n\t\treturn err\n\t}\n\thandler, ok := rawHandler.(inbound.Handler)\n\tif !ok {\n\t\treturn newError(\"not an InboundHandler\")\n\t}\n\tif err := inboundManager.AddHandler(server.ctx, handler); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc addInboundHandlers(server *Instance, configs []*InboundHandlerConfig) error {\n\tfor _, inboundConfig := range configs {\n\t\tif err := AddInboundHandler(server, inboundConfig); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc AddOutboundHandler(server *Instance, config *OutboundHandlerConfig) error {\n\toutboundManager := server.GetFeature(outbound.ManagerType()).(outbound.Manager)\n\tproxyEnv := server.env.ProxyEnvironment(\"o\" + config.Tag)\n\trawHandler, err := CreateObjectWithEnvironment(server, config, proxyEnv)\n\tif err != nil {\n\t\treturn err\n\t}\n\thandler, ok := rawHandler.(outbound.Handler)\n\tif !ok {\n\t\treturn newError(\"not an OutboundHandler\")\n\t}\n\tif err := outboundManager.AddHandler(server.ctx, handler); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc RemoveOutboundHandler(server *Instance, tag string) error {\n\toutboundManager := server.GetFeature(outbound.ManagerType()).(outbound.Manager)\n\tif err := outboundManager.RemoveHandler(server.ctx, tag); err != nil {\n\t\treturn err\n\t}\n\n\tif err := server.env.DropProxyEnvironment(\"o\" + tag); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc addOutboundHandlers(server *Instance, configs []*OutboundHandlerConfig) error {\n\tfor _, outboundConfig := range configs {\n\t\tif err := AddOutboundHandler(server, outboundConfig); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// RequireFeatures is a helper function to require features from Instance in context.\n// See Instance.RequireFeatures for more information.\nfunc RequireFeatures(ctx context.Context, callback interface{}) error {\n\tv := MustFromContext(ctx)\n\treturn v.RequireFeatures(callback)\n}\n\n// New returns a new V2Ray instance based on given configuration.\n// The instance is not started at this point.\n// To ensure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.\nfunc New(config *Config) (*Instance, error) {\n\tserver := &Instance{ctx: context.Background()}\n\n\tdone, err := initInstanceWithConfig(config, server)\n\tif done {\n\t\treturn nil, err\n\t}\n\n\treturn server, nil\n}\n\nfunc NewWithContext(ctx context.Context, config *Config) (*Instance, error) {\n\tserver := &Instance{ctx: ctx}\n\n\tdone, err := initInstanceWithConfig(config, server)\n\tif done {\n\t\treturn nil, err\n\t}\n\n\treturn server, nil\n}\n\nfunc initInstanceWithConfig(config *Config, server *Instance) (bool, error) {\n\tif config.Transport != nil {\n\t\tfeatures.PrintDeprecatedFeatureWarning(\"global transport settings\")\n\t}\n\tif err := config.Transport.Apply(); err != nil {\n\t\treturn true, err\n\t}\n\n\tdefaultNetworkImpl := systemnetworkimpl.NewSystemNetworkDefault()\n\tdefaultFilesystemImpl := filesystemimpl.NewDefaultFileSystemDefaultImpl()\n\tdeferredPersistentStorageImpl := deferredpersistentstorage.NewDeferredPersistentStorage(server.ctx)\n\tserver.env = environment.NewRootEnvImpl(server.ctx,\n\t\ttransientstorageimpl.NewScopedTransientStorageImpl(),\n\t\tdefaultNetworkImpl.Dialer(),\n\t\tdefaultNetworkImpl.Listener(),\n\t\tdefaultFilesystemImpl,\n\t\tdeferredPersistentStorageImpl)\n\n\tfor _, appSettings := range config.App {\n\t\tsettings, err := serial.GetInstanceOf(appSettings)\n\t\tif err != nil {\n\t\t\treturn true, err\n\t\t}\n\t\tkey := appSettings.TypeUrl\n\t\tappEnv := server.env.AppEnvironment(key)\n\t\tobj, err := CreateObjectWithEnvironment(server, settings, appEnv)\n\t\tif err != nil {\n\t\t\treturn true, err\n\t\t}\n\t\tif feature, ok := obj.(features.Feature); ok {\n\t\t\tif err := server.AddFeature(feature); err != nil {\n\t\t\t\treturn true, err\n\t\t\t}\n\t\t}\n\t}\n\n\tessentialFeatures := []struct {\n\t\tType     interface{}\n\t\tInstance features.Feature\n\t}{\n\t\t{dns.ClientType(), localdns.New()},\n\t\t{policy.ManagerType(), policy.DefaultManager{}},\n\t\t{routing.RouterType(), routing.DefaultRouter{}},\n\t\t{stats.ManagerType(), stats.NoopManager{}},\n\t}\n\n\tfor _, f := range essentialFeatures {\n\t\tif server.GetFeature(f.Type) == nil {\n\t\t\tif err := server.AddFeature(f.Instance); err != nil {\n\t\t\t\treturn true, err\n\t\t\t}\n\t\t}\n\t}\n\n\tif server.featureResolutions != nil {\n\t\treturn true, newError(\"not all dependency are resolved.\")\n\t}\n\n\tif persistentStorageService := server.GetFeature(storage.ScopedPersistentStorageServiceType); persistentStorageService != nil {\n\t\tdeferredPersistentStorageImpl.ProvideInner(server.ctx, persistentStorageService.(storage.ScopedPersistentStorage))\n\t} else {\n\t\tdeferredPersistentStorageImpl.ProvideInner(server.ctx, nil)\n\t}\n\n\tif err := addInboundHandlers(server, config.Inbound); err != nil {\n\t\treturn true, err\n\t}\n\n\tif err := addOutboundHandlers(server, config.Outbound); err != nil {\n\t\treturn true, err\n\t}\n\treturn false, nil\n}\n\n// Type implements common.HasType.\nfunc (s *Instance) Type() interface{} {\n\treturn ServerType()\n}\n\n// Close shutdown the V2Ray instance.\nfunc (s *Instance) Close() error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\n\ts.running = false\n\n\tvar errors []interface{}\n\tfor _, f := range s.features {\n\t\tif err := f.Close(); err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif len(errors) > 0 {\n\t\treturn newError(\"failed to close all features\").Base(newError(serial.Concat(errors...)))\n\t}\n\n\treturn nil\n}\n\n// RequireFeatures registers a callback, which will be called when all dependent features are registered.\n// The callback must be a func(). All its parameters must be features.Feature.\nfunc (s *Instance) RequireFeatures(callback interface{}) error {\n\tcallbackType := reflect.TypeOf(callback)\n\tif callbackType.Kind() != reflect.Func {\n\t\tpanic(\"not a function\")\n\t}\n\n\tvar featureTypes []reflect.Type\n\tfor i := 0; i < callbackType.NumIn(); i++ {\n\t\tfeatureTypes = append(featureTypes, reflect.PtrTo(callbackType.In(i)))\n\t}\n\n\tr := resolution{\n\t\tdeps:     featureTypes,\n\t\tcallback: callback,\n\t}\n\tif finished, err := r.resolve(s.features); finished {\n\t\treturn err\n\t}\n\ts.featureResolutions = append(s.featureResolutions, r)\n\treturn nil\n}\n\n// AddFeature registers a feature into current Instance.\nfunc (s *Instance) AddFeature(feature features.Feature) error {\n\ts.features = append(s.features, feature)\n\n\tif s.running {\n\t\tif err := feature.Start(); err != nil {\n\t\t\tnewError(\"failed to start feature\").Base(err).WriteToLog()\n\t\t}\n\t\treturn nil\n\t}\n\n\tif s.featureResolutions == nil {\n\t\treturn nil\n\t}\n\n\tvar pendingResolutions []resolution\n\tfor _, r := range s.featureResolutions {\n\t\tfinished, err := r.resolve(s.features)\n\t\tif finished && err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !finished {\n\t\t\tpendingResolutions = append(pendingResolutions, r)\n\t\t}\n\t}\n\tif len(pendingResolutions) == 0 {\n\t\ts.featureResolutions = nil\n\t} else if len(pendingResolutions) < len(s.featureResolutions) {\n\t\ts.featureResolutions = pendingResolutions\n\t}\n\n\treturn nil\n}\n\n// GetFeature returns a feature of the given type, or nil if such feature is not registered.\nfunc (s *Instance) GetFeature(featureType interface{}) features.Feature {\n\treturn getFeature(s.features, reflect.TypeOf(featureType))\n}\n\n// Start starts the V2Ray instance, including all registered features. When Start returns error, the state of the instance is unknown.\n// A V2Ray instance can be started only once. Upon closing, the instance is not guaranteed to start again.\n//\n// v2ray:api:stable\nfunc (s *Instance) Start() error {\n\ts.access.Lock()\n\tdefer s.access.Unlock()\n\n\ts.running = true\n\tfor _, f := range s.features {\n\t\tif err := f.Start(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tnewError(\"V2Ray \", Version(), \" started\").AtWarning().WriteToLog()\n\n\treturn nil\n}\n"
  },
  {
    "path": "v2ray_test.go",
    "content": "package core_test\n\nimport (\n\t\"testing\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/anypb\"\n\n\t. \"github.com/v2fly/v2ray-core/v5\"\n\t\"github.com/v2fly/v2ray-core/v5/app/dispatcher\"\n\t\"github.com/v2fly/v2ray-core/v5/app/proxyman\"\n\t\"github.com/v2fly/v2ray-core/v5/common\"\n\t\"github.com/v2fly/v2ray-core/v5/common/net\"\n\t\"github.com/v2fly/v2ray-core/v5/common/protocol\"\n\t\"github.com/v2fly/v2ray-core/v5/common/serial\"\n\t\"github.com/v2fly/v2ray-core/v5/common/uuid\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns\"\n\t\"github.com/v2fly/v2ray-core/v5/features/dns/localdns\"\n\t_ \"github.com/v2fly/v2ray-core/v5/main/distro/all\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/dokodemo\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess\"\n\t\"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound\"\n\t\"github.com/v2fly/v2ray-core/v5/testing/servers/tcp\"\n)\n\nfunc TestV2RayDependency(t *testing.T) {\n\tinstance := new(Instance)\n\n\twait := make(chan bool, 1)\n\tinstance.RequireFeatures(func(d dns.Client) {\n\t\tif d == nil {\n\t\t\tt.Error(\"expected dns client fulfilled, but actually nil\")\n\t\t}\n\t\twait <- true\n\t})\n\tinstance.AddFeature(localdns.New())\n\t<-wait\n}\n\nfunc TestV2RayClose(t *testing.T) {\n\tport := tcp.PickPort()\n\n\tuserID := uuid.New()\n\tconfig := &Config{\n\t\tApp: []*anypb.Any{\n\t\t\tserial.ToTypedMessage(&dispatcher.Config{}),\n\t\t\tserial.ToTypedMessage(&proxyman.InboundConfig{}),\n\t\t\tserial.ToTypedMessage(&proxyman.OutboundConfig{}),\n\t\t},\n\t\tInbound: []*InboundHandlerConfig{\n\t\t\t{\n\t\t\t\tReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{\n\t\t\t\t\tPortRange: net.SinglePortRange(port),\n\t\t\t\t\tListen:    net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t}),\n\t\t\t\tProxySettings: serial.ToTypedMessage(&dokodemo.Config{\n\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\tPort:    uint32(0),\n\t\t\t\t\tNetworkList: &net.NetworkList{\n\t\t\t\t\t\tNetwork: []net.Network{net.Network_TCP, net.Network_UDP},\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t\tOutbound: []*OutboundHandlerConfig{\n\t\t\t{\n\t\t\t\tProxySettings: serial.ToTypedMessage(&outbound.Config{\n\t\t\t\t\tReceiver: []*protocol.ServerEndpoint{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddress: net.NewIPOrDomain(net.LocalHostIP),\n\t\t\t\t\t\t\tPort:    uint32(0),\n\t\t\t\t\t\t\tUser: []*protocol.User{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAccount: serial.ToTypedMessage(&vmess.Account{\n\t\t\t\t\t\t\t\t\t\tId: userID.String(),\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},\n\t}\n\n\tcfgBytes, err := proto.Marshal(config)\n\tcommon.Must(err)\n\n\tserver, err := StartInstance(FormatProtobuf, cfgBytes)\n\tcommon.Must(err)\n\tserver.Close()\n}\n"
  }
]